Add post-quantum consensus foundation
This commit is contained in:
parent
01154a9bc5
commit
ad21afbfa9
454 changed files with 35738 additions and 6 deletions
|
|
@ -35,6 +35,7 @@ LIBVEXTA_CONSENSUS=libvexta_consensus.a
|
||||||
LIBVEXTA_CLI=libvexta_cli.a
|
LIBVEXTA_CLI=libvexta_cli.a
|
||||||
LIBVEXTA_UTIL=libvexta_util.a
|
LIBVEXTA_UTIL=libvexta_util.a
|
||||||
LIBVEXTA_CRYPTO_BASE=crypto/libvexta_crypto_base.a
|
LIBVEXTA_CRYPTO_BASE=crypto/libvexta_crypto_base.a
|
||||||
|
LIBVEXTA_PQ=crypto/libvexta_pq.a
|
||||||
LIBVEXTAQT=qt/libvextaqt.a
|
LIBVEXTAQT=qt/libvextaqt.a
|
||||||
LIBSECP256K1=secp256k1/libsecp256k1.la
|
LIBSECP256K1=secp256k1/libsecp256k1.la
|
||||||
|
|
||||||
|
|
@ -70,6 +71,7 @@ $(LIBSECP256K1): $(wildcard secp256k1/src/*.h) $(wildcard secp256k1/src/*.c) $(w
|
||||||
# But to build the less dependent modules first, we manually select their order here:
|
# But to build the less dependent modules first, we manually select their order here:
|
||||||
EXTRA_LIBRARIES += \
|
EXTRA_LIBRARIES += \
|
||||||
$(LIBVEXTA_CRYPTO) \
|
$(LIBVEXTA_CRYPTO) \
|
||||||
|
$(LIBVEXTA_PQ) \
|
||||||
$(LIBVEXTA_UTIL) \
|
$(LIBVEXTA_UTIL) \
|
||||||
$(LIBVEXTA_COMMON) \
|
$(LIBVEXTA_COMMON) \
|
||||||
$(LIBVEXTA_CONSENSUS) \
|
$(LIBVEXTA_CONSENSUS) \
|
||||||
|
|
@ -499,6 +501,36 @@ crypto_libvexta_crypto_shani_a_CXXFLAGS += $(SHANI_CXXFLAGS)
|
||||||
crypto_libvexta_crypto_shani_a_CPPFLAGS += -DENABLE_SHANI
|
crypto_libvexta_crypto_shani_a_CPPFLAGS += -DENABLE_SHANI
|
||||||
crypto_libvexta_crypto_shani_a_SOURCES = crypto/sha256_shani.cpp
|
crypto_libvexta_crypto_shani_a_SOURCES = crypto/sha256_shani.cpp
|
||||||
|
|
||||||
|
# post-quantum cryptography: ML-DSA-65 + SLH-DSA/SPHINCS+ sha2-128s
|
||||||
|
crypto_libvexta_pq_a_CPPFLAGS = $(AM_CPPFLAGS) -Isrc -I$(srcdir) -I$(srcdir)/crypto/pq/mldsa65 -I$(srcdir)/crypto/pq/sphincsplus -DDILITHIUM_MODE=3 -DPARAMS=sphincs-sha2-128s
|
||||||
|
crypto_libvexta_pq_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
|
||||||
|
crypto_libvexta_pq_a_CFLAGS = $(AM_CFLAGS) $(PIE_FLAGS)
|
||||||
|
crypto_libvexta_pq_a_SOURCES = \
|
||||||
|
crypto/pq/pq.cpp \
|
||||||
|
crypto/pq/pq.h \
|
||||||
|
crypto/pq/pq_randombytes.cpp \
|
||||||
|
crypto/pq/mldsa65/fips202.c \
|
||||||
|
crypto/pq/mldsa65/ntt.c \
|
||||||
|
crypto/pq/mldsa65/packing.c \
|
||||||
|
crypto/pq/mldsa65/poly.c \
|
||||||
|
crypto/pq/mldsa65/polyvec.c \
|
||||||
|
crypto/pq/mldsa65/reduce.c \
|
||||||
|
crypto/pq/mldsa65/rounding.c \
|
||||||
|
crypto/pq/mldsa65/sign.c \
|
||||||
|
crypto/pq/mldsa65/symmetric-shake.c \
|
||||||
|
crypto/pq/sphincsplus/address.c \
|
||||||
|
crypto/pq/sphincsplus/fips202.c \
|
||||||
|
crypto/pq/sphincsplus/fors.c \
|
||||||
|
crypto/pq/sphincsplus/hash_sha2.c \
|
||||||
|
crypto/pq/sphincsplus/merkle.c \
|
||||||
|
crypto/pq/sphincsplus/sha2.c \
|
||||||
|
crypto/pq/sphincsplus/sign.c \
|
||||||
|
crypto/pq/sphincsplus/thash_sha2_simple.c \
|
||||||
|
crypto/pq/sphincsplus/utils.c \
|
||||||
|
crypto/pq/sphincsplus/utilsx1.c \
|
||||||
|
crypto/pq/sphincsplus/wots.c \
|
||||||
|
crypto/pq/sphincsplus/wotsx1.c
|
||||||
|
|
||||||
# consensus: shared between all executables that validate any consensus rules.
|
# consensus: shared between all executables that validate any consensus rules.
|
||||||
libvexta_consensus_a_CPPFLAGS = $(AM_CPPFLAGS) $(VEXTA_INCLUDES)
|
libvexta_consensus_a_CPPFLAGS = $(AM_CPPFLAGS) $(VEXTA_INCLUDES)
|
||||||
libvexta_consensus_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
|
libvexta_consensus_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
|
||||||
|
|
@ -677,6 +709,7 @@ vexta_bin_ldadd = \
|
||||||
$(LIBVEXTA_UTIL) \
|
$(LIBVEXTA_UTIL) \
|
||||||
$(LIBVEXTA_ZMQ) \
|
$(LIBVEXTA_ZMQ) \
|
||||||
$(LIBVEXTA_CONSENSUS) \
|
$(LIBVEXTA_CONSENSUS) \
|
||||||
|
$(LIBVEXTA_PQ) \
|
||||||
$(LIBVEXTA_CRYPTO) \
|
$(LIBVEXTA_CRYPTO) \
|
||||||
$(LIBLEVELDB) \
|
$(LIBLEVELDB) \
|
||||||
$(LIBLEVELDB_SSE42) \
|
$(LIBLEVELDB_SSE42) \
|
||||||
|
|
@ -711,6 +744,7 @@ vexta_cli_LDADD = \
|
||||||
$(LIBVEXTA_CLI) \
|
$(LIBVEXTA_CLI) \
|
||||||
$(LIBUNIVALUE) \
|
$(LIBUNIVALUE) \
|
||||||
$(LIBVEXTA_CONSENSUS) \
|
$(LIBVEXTA_CONSENSUS) \
|
||||||
|
$(LIBVEXTA_PQ) \
|
||||||
$(LIBVEXTA_UTIL) \
|
$(LIBVEXTA_UTIL) \
|
||||||
$(LIBVEXTA_CRYPTO)
|
$(LIBVEXTA_CRYPTO)
|
||||||
|
|
||||||
|
|
@ -732,6 +766,7 @@ vexta_tx_LDADD = \
|
||||||
$(LIBVEXTA_COMMON) \
|
$(LIBVEXTA_COMMON) \
|
||||||
$(LIBVEXTA_UTIL) \
|
$(LIBVEXTA_UTIL) \
|
||||||
$(LIBVEXTA_CONSENSUS) \
|
$(LIBVEXTA_CONSENSUS) \
|
||||||
|
$(LIBVEXTA_PQ) \
|
||||||
$(LIBVEXTA_CRYPTO) \
|
$(LIBVEXTA_CRYPTO) \
|
||||||
$(LIBSECP256K1)
|
$(LIBSECP256K1)
|
||||||
|
|
||||||
|
|
@ -765,6 +800,7 @@ vexta_util_LDADD = \
|
||||||
$(LIBVEXTA_UTIL) \
|
$(LIBVEXTA_UTIL) \
|
||||||
$(LIBUNIVALUE) \
|
$(LIBUNIVALUE) \
|
||||||
$(LIBVEXTA_CONSENSUS) \
|
$(LIBVEXTA_CONSENSUS) \
|
||||||
|
$(LIBVEXTA_PQ) \
|
||||||
$(LIBVEXTA_CRYPTO) \
|
$(LIBVEXTA_CRYPTO) \
|
||||||
$(LIBSECP256K1)
|
$(LIBSECP256K1)
|
||||||
|
|
||||||
|
|
@ -774,7 +810,32 @@ vexta_util_LDADD += $(BOOST_LIBS)
|
||||||
# vextaconsensus library #
|
# vextaconsensus library #
|
||||||
if BUILD_VEXTA_LIBS
|
if BUILD_VEXTA_LIBS
|
||||||
include_HEADERS = script/vextaconsensus.h
|
include_HEADERS = script/vextaconsensus.h
|
||||||
libvextaconsensus_la_SOURCES = support/cleanse.cpp $(crypto_libvexta_crypto_base_a_SOURCES) $(libvexta_consensus_a_SOURCES)
|
libvextaconsensus_pq_sources = \
|
||||||
|
crypto/pq/pq.cpp \
|
||||||
|
crypto/pq/pq.h \
|
||||||
|
crypto/pq/mldsa65/fips202.c \
|
||||||
|
crypto/pq/mldsa65/ntt.c \
|
||||||
|
crypto/pq/mldsa65/packing.c \
|
||||||
|
crypto/pq/mldsa65/poly.c \
|
||||||
|
crypto/pq/mldsa65/polyvec.c \
|
||||||
|
crypto/pq/mldsa65/reduce.c \
|
||||||
|
crypto/pq/mldsa65/rounding.c \
|
||||||
|
crypto/pq/mldsa65/sign.c \
|
||||||
|
crypto/pq/mldsa65/symmetric-shake.c \
|
||||||
|
crypto/pq/sphincsplus/address.c \
|
||||||
|
crypto/pq/sphincsplus/fips202.c \
|
||||||
|
crypto/pq/sphincsplus/fors.c \
|
||||||
|
crypto/pq/sphincsplus/hash_sha2.c \
|
||||||
|
crypto/pq/sphincsplus/merkle.c \
|
||||||
|
crypto/pq/sphincsplus/sha2.c \
|
||||||
|
crypto/pq/sphincsplus/sign.c \
|
||||||
|
crypto/pq/sphincsplus/thash_sha2_simple.c \
|
||||||
|
crypto/pq/sphincsplus/utils.c \
|
||||||
|
crypto/pq/sphincsplus/utilsx1.c \
|
||||||
|
crypto/pq/sphincsplus/wots.c \
|
||||||
|
crypto/pq/sphincsplus/wotsx1.c
|
||||||
|
|
||||||
|
libvextaconsensus_la_SOURCES = support/cleanse.cpp $(crypto_libvexta_crypto_base_a_SOURCES) $(libvextaconsensus_pq_sources) $(libvexta_consensus_a_SOURCES)
|
||||||
|
|
||||||
if GLIBC_BACK_COMPAT
|
if GLIBC_BACK_COMPAT
|
||||||
libvextaconsensus_la_SOURCES += compat/glibc_compat.cpp
|
libvextaconsensus_la_SOURCES += compat/glibc_compat.cpp
|
||||||
|
|
@ -782,8 +843,9 @@ endif
|
||||||
|
|
||||||
libvextaconsensus_la_LDFLAGS = $(AM_LDFLAGS) -no-undefined $(RELDFLAGS)
|
libvextaconsensus_la_LDFLAGS = $(AM_LDFLAGS) -no-undefined $(RELDFLAGS)
|
||||||
libvextaconsensus_la_LIBADD = $(LIBSECP256K1)
|
libvextaconsensus_la_LIBADD = $(LIBSECP256K1)
|
||||||
libvextaconsensus_la_CPPFLAGS = $(AM_CPPFLAGS) -I$(builddir)/obj -I$(srcdir)/secp256k1/include -DBUILD_VEXTA_INTERNAL
|
libvextaconsensus_la_CPPFLAGS = $(AM_CPPFLAGS) -I$(builddir)/obj -I$(srcdir)/secp256k1/include -I$(srcdir)/crypto/pq/mldsa65 -I$(srcdir)/crypto/pq/sphincsplus -DDILITHIUM_MODE=3 -DPARAMS=sphincs-sha2-128s -DVEXTA_PQ_VERIFY_ONLY -DBUILD_VEXTA_INTERNAL
|
||||||
libvextaconsensus_la_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
|
libvextaconsensus_la_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
|
||||||
|
libvextaconsensus_la_CFLAGS = $(AM_CFLAGS) $(PIE_FLAGS)
|
||||||
|
|
||||||
endif
|
endif
|
||||||
#
|
#
|
||||||
|
|
|
||||||
|
|
@ -111,6 +111,7 @@ DIGIBYTE_TESTS =\
|
||||||
test/policy_fee_tests.cpp \
|
test/policy_fee_tests.cpp \
|
||||||
test/policyestimator_tests.cpp \
|
test/policyestimator_tests.cpp \
|
||||||
test/pow_tests.cpp \
|
test/pow_tests.cpp \
|
||||||
|
test/pq_tests.cpp \
|
||||||
test/prevector_tests.cpp \
|
test/prevector_tests.cpp \
|
||||||
test/raii_event_tests.cpp \
|
test/raii_event_tests.cpp \
|
||||||
test/random_tests.cpp \
|
test/random_tests.cpp \
|
||||||
|
|
@ -177,8 +178,8 @@ DIGIBYTE_TEST_SUITE += \
|
||||||
endif
|
endif
|
||||||
|
|
||||||
test_test_digibyte_SOURCES = $(DIGIBYTE_TEST_SUITE) $(DIGIBYTE_TESTS) $(JSON_TEST_FILES) $(RAW_TEST_FILES)
|
test_test_digibyte_SOURCES = $(DIGIBYTE_TEST_SUITE) $(DIGIBYTE_TESTS) $(JSON_TEST_FILES) $(RAW_TEST_FILES)
|
||||||
test_test_digibyte_CPPFLAGS = $(AM_CPPFLAGS) $(DIGIBYTE_INCLUDES) $(TESTDEFS) $(EVENT_CFLAGS)
|
test_test_digibyte_CPPFLAGS = $(AM_CPPFLAGS) $(DIGIBYTE_INCLUDES) $(UNIVALUE_CFLAGS) $(TESTDEFS) $(EVENT_CFLAGS)
|
||||||
test_test_digibyte_LDADD = $(LIBTEST_UTIL)
|
test_test_digibyte_LDADD = $(LIBTEST_UTIL) $(LIBVEXTA_PQ)
|
||||||
if ENABLE_WALLET
|
if ENABLE_WALLET
|
||||||
test_test_digibyte_LDADD += $(LIBDIGIBYTE_WALLET)
|
test_test_digibyte_LDADD += $(LIBDIGIBYTE_WALLET)
|
||||||
endif
|
endif
|
||||||
|
|
|
||||||
|
|
@ -103,6 +103,13 @@ public:
|
||||||
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
|
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
|
||||||
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].min_activation_height = 0; // No activation delay
|
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].min_activation_height = 0; // No activation delay
|
||||||
|
|
||||||
|
// VEXTA quantum-resistant witness v2/v3.
|
||||||
|
// Integrated but intentionally not active yet.
|
||||||
|
consensus.vDeployments[Consensus::DEPLOYMENT_PQR].bit = 3;
|
||||||
|
consensus.vDeployments[Consensus::DEPLOYMENT_PQR].nStartTime = Consensus::BIP9Deployment::NEVER_ACTIVE;
|
||||||
|
consensus.vDeployments[Consensus::DEPLOYMENT_PQR].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
|
||||||
|
consensus.vDeployments[Consensus::DEPLOYMENT_PQR].min_activation_height = 0;
|
||||||
|
|
||||||
// The best chain should have at least this much work.
|
// The best chain should have at least this much work.
|
||||||
consensus.nMinimumChainWork = uint256{};
|
consensus.nMinimumChainWork = uint256{};
|
||||||
|
|
||||||
|
|
@ -235,6 +242,12 @@ public:
|
||||||
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nTimeout = 1750457304; // 20th June 2025 Testnet
|
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nTimeout = 1750457304; // 20th June 2025 Testnet
|
||||||
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].min_activation_height = 0; // No activation delay
|
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].min_activation_height = 0; // No activation delay
|
||||||
|
|
||||||
|
// VEXTA quantum-resistant witness v2/v3.
|
||||||
|
// Integrated but intentionally not active yet.
|
||||||
|
consensus.vDeployments[Consensus::DEPLOYMENT_PQR].bit = 3;
|
||||||
|
consensus.vDeployments[Consensus::DEPLOYMENT_PQR].nStartTime = Consensus::BIP9Deployment::NEVER_ACTIVE;
|
||||||
|
consensus.vDeployments[Consensus::DEPLOYMENT_PQR].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
|
||||||
|
consensus.vDeployments[Consensus::DEPLOYMENT_PQR].min_activation_height = 0;
|
||||||
|
|
||||||
// The best chain should have at least this much work.
|
// The best chain should have at least this much work.
|
||||||
consensus.nMinimumChainWork = uint256{};
|
consensus.nMinimumChainWork = uint256{};
|
||||||
|
|
@ -369,6 +382,13 @@ public:
|
||||||
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
|
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
|
||||||
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].min_activation_height = 0; // No activation delay
|
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].min_activation_height = 0; // No activation delay
|
||||||
|
|
||||||
|
// VEXTA quantum-resistant witness v2/v3.
|
||||||
|
// Integrated but intentionally not active yet.
|
||||||
|
consensus.vDeployments[Consensus::DEPLOYMENT_PQR].bit = 3;
|
||||||
|
consensus.vDeployments[Consensus::DEPLOYMENT_PQR].nStartTime = Consensus::BIP9Deployment::NEVER_ACTIVE;
|
||||||
|
consensus.vDeployments[Consensus::DEPLOYMENT_PQR].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
|
||||||
|
consensus.vDeployments[Consensus::DEPLOYMENT_PQR].min_activation_height = 0;
|
||||||
|
|
||||||
// message start is defined as the first 4 bytes of the sha256d of the block script
|
// message start is defined as the first 4 bytes of the sha256d of the block script
|
||||||
CHashWriter h(SER_DISK, 0);
|
CHashWriter h(SER_DISK, 0);
|
||||||
h << consensus.signet_challenge;
|
h << consensus.signet_challenge;
|
||||||
|
|
@ -454,6 +474,13 @@ public:
|
||||||
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
|
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
|
||||||
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].min_activation_height = 0; // No activation delay
|
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].min_activation_height = 0; // No activation delay
|
||||||
|
|
||||||
|
// VEXTA quantum-resistant witness v2/v3.
|
||||||
|
// Integrated but intentionally not active yet.
|
||||||
|
consensus.vDeployments[Consensus::DEPLOYMENT_PQR].bit = 3;
|
||||||
|
consensus.vDeployments[Consensus::DEPLOYMENT_PQR].nStartTime = Consensus::BIP9Deployment::NEVER_ACTIVE;
|
||||||
|
consensus.vDeployments[Consensus::DEPLOYMENT_PQR].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
|
||||||
|
consensus.vDeployments[Consensus::DEPLOYMENT_PQR].min_activation_height = 0;
|
||||||
|
|
||||||
consensus.nMinimumChainWork = uint256{};
|
consensus.nMinimumChainWork = uint256{};
|
||||||
consensus.defaultAssumeValid = uint256{};
|
consensus.defaultAssumeValid = uint256{};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,11 +32,12 @@ enum BuriedDeployment : int16_t {
|
||||||
enum DeploymentPos : uint16_t {
|
enum DeploymentPos : uint16_t {
|
||||||
DEPLOYMENT_TESTDUMMY,
|
DEPLOYMENT_TESTDUMMY,
|
||||||
DEPLOYMENT_TAPROOT, // Deployment of Schnorr/Taproot (BIPs 340-342)
|
DEPLOYMENT_TAPROOT, // Deployment of Schnorr/Taproot (BIPs 340-342)
|
||||||
|
DEPLOYMENT_PQR, // VEXTA quantum-resistant witness v2/v3
|
||||||
// NOTE: Also add new deployments to VersionBitsDeploymentInfo in deploymentinfo.cpp
|
// NOTE: Also add new deployments to VersionBitsDeploymentInfo in deploymentinfo.cpp
|
||||||
MAX_VERSION_BITS_DEPLOYMENTS
|
MAX_VERSION_BITS_DEPLOYMENTS
|
||||||
};
|
};
|
||||||
constexpr bool ValidDeployment(BuriedDeployment dep) { return dep <= DEPLOYMENT_NVERSIONBIPS; }
|
constexpr bool ValidDeployment(BuriedDeployment dep) { return dep <= DEPLOYMENT_NVERSIONBIPS; }
|
||||||
constexpr bool ValidDeployment(DeploymentPos dep) { return DEPLOYMENT_TESTDUMMY <= dep && dep <= DEPLOYMENT_TAPROOT; }
|
constexpr bool ValidDeployment(DeploymentPos dep) { return DEPLOYMENT_TESTDUMMY <= dep && dep <= DEPLOYMENT_PQR; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Struct for each individual consensus rule change using BIP9.
|
* Struct for each individual consensus rule change using BIP9.
|
||||||
|
|
|
||||||
19
src/crypto/pq/CONFORMANCE.md
Normal file
19
src/crypto/pq/CONFORMANCE.md
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
# Vexta PQC Conformance (b2 — full KAT)
|
||||||
|
|
||||||
|
Validated against pinned upstream known-answer vectors.
|
||||||
|
|
||||||
|
## ML-DSA-65 (FIPS 204, dilithium mode 3)
|
||||||
|
- Pinned commit: d35ba3fe5449bee3e6d43e1f296c3ca818bd36be
|
||||||
|
- Artifact: `_d/ref/test/test_vectors3` stdout
|
||||||
|
- SHA256: 14bf84918ee90e7afbd580191d3eb890d4557e0900b1145e39a8399ef7dd3fba
|
||||||
|
- Status: PASS
|
||||||
|
|
||||||
|
## SPHINCS+-sha2-128s-simple (FIPS 205 / SLH-DSA)
|
||||||
|
- Pinned commit: 7ec789ace6874d875f4bb84cb61b81155398167e
|
||||||
|
- Checker: `_s/vectors.py sphincs-sha2-128s-simple ref`
|
||||||
|
- Expected SHA256: 65942fac8e225fde77dd277d297e68c94c2e25a2a4089f88be4b56fa92b18a84
|
||||||
|
- Status: PASS (ok)
|
||||||
|
|
||||||
|
Reproduce:
|
||||||
|
cd src/crypto/pq/_d/ref && make test/test_vectors3 && ./test/test_vectors3 | sha256sum
|
||||||
|
cd src/crypto/pq/_s && python3 vectors.py sphincs-sha2-128s-simple ref
|
||||||
21
src/crypto/pq/README.md
Normal file
21
src/crypto/pq/README.md
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
# Vexta post-quantum vendored references
|
||||||
|
|
||||||
|
Clean-room vendored, MIT-attribution discipline. No KV5 lineage.
|
||||||
|
|
||||||
|
## ML-DSA-65 (Dilithium mode 3, NIST FIPS 204)
|
||||||
|
- Upstream: https://github.com/pq-crystals/dilithium
|
||||||
|
- Pinned commit: d35ba3fe5449bee3e6d43e1f296c3ca818bd36be
|
||||||
|
- License: Apache-2.0 / public-domain (dual). Vendored, not relicensed.
|
||||||
|
- Param pin: DILITHIUM_MODE=3 (compile define).
|
||||||
|
|
||||||
|
## SLH-DSA (SPHINCS+ sha2-128s-simple, NIST FIPS 205)
|
||||||
|
- Upstream: https://github.com/sphincs/sphincsplus
|
||||||
|
- Pinned commit: 7ec789ace6874d875f4bb84cb61b81155398167e
|
||||||
|
- License: CC0 public domain. Vendored, not relicensed.
|
||||||
|
- Param pin: PARAMS=sphincs-sha2-128s; sha2 backend + simple thash only.
|
||||||
|
|
||||||
|
## Local modifications
|
||||||
|
- Deleted all test-only RNGs (randombytes.c, rng.*): insecure for wallet use.
|
||||||
|
- randombytes.h unified to a single prototype; definition in pq_randombytes.cpp
|
||||||
|
is backed by Bitcoin's GetStrongRandBytes (CSPRNG).
|
||||||
|
- Pruned shake/haraka backends and robust thash variants.
|
||||||
9
src/crypto/pq/_d/.gitignore
vendored
Normal file
9
src/crypto/pq/_d/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
PQCsignKAT_Dilithium2.req
|
||||||
|
PQCsignKAT_Dilithium2.rsp
|
||||||
|
PQCsignKAT_Dilithium3.req
|
||||||
|
PQCsignKAT_Dilithium3.rsp
|
||||||
|
PQCsignKAT_Dilithium5.req
|
||||||
|
PQCsignKAT_Dilithium5.rsp
|
||||||
|
tvecs2
|
||||||
|
tvecs3
|
||||||
|
tvecs5
|
||||||
33
src/crypto/pq/_d/.travis.yml
Normal file
33
src/crypto/pq/_d/.travis.yml
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
language: c
|
||||||
|
os: linux
|
||||||
|
dist: bionic
|
||||||
|
compiler:
|
||||||
|
- gcc
|
||||||
|
- clang
|
||||||
|
arch:
|
||||||
|
- amd64
|
||||||
|
- arm64
|
||||||
|
- ppc64le
|
||||||
|
- s390x
|
||||||
|
script: ./runtests.sh
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
include:
|
||||||
|
- os: osx
|
||||||
|
osx_image: xcode11.6
|
||||||
|
compiler: clang
|
||||||
|
env:
|
||||||
|
- CFLAGS="-I/usr/local/opt/openssl@1.1/include/"
|
||||||
|
- NISTFLAGS="-I/usr/local/opt/openssl@1.1/include/"
|
||||||
|
- LDFLAGS="-L/usr/local/opt/openssl@1.1/lib/"
|
||||||
|
|
||||||
|
- stage: coverage
|
||||||
|
os: linux
|
||||||
|
compiler: gcc
|
||||||
|
before_install:
|
||||||
|
- sudo apt-get update
|
||||||
|
- sudo apt-get install -y lcov
|
||||||
|
- gem install coveralls-lcov
|
||||||
|
script: ./runlcov.sh
|
||||||
|
after_success:
|
||||||
|
- coveralls-lcov ref/dilithium.lcov
|
||||||
7
src/crypto/pq/_d/AUTHORS.md
Normal file
7
src/crypto/pq/_d/AUTHORS.md
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
Léo Ducas,
|
||||||
|
Eike Kiltz,
|
||||||
|
Tancrède Lepoint,
|
||||||
|
Vadim Lyubashevsky,
|
||||||
|
Gregor Seiler,
|
||||||
|
Peter Schwabe,
|
||||||
|
Damien Stehlé
|
||||||
15
src/crypto/pq/_d/Common_META.yml
Normal file
15
src/crypto/pq/_d/Common_META.yml
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
commons:
|
||||||
|
- name: common_ref
|
||||||
|
folder_name: ref
|
||||||
|
sources: fips202.c fips202.h
|
||||||
|
- name: common_avx2
|
||||||
|
folder_name: avx2
|
||||||
|
sources: f1600x4.S fips202.c fips202.h fips202x4.c fips202x4.h
|
||||||
|
supported_platforms:
|
||||||
|
- architecture: x86_64
|
||||||
|
operating_systems:
|
||||||
|
- Darwin
|
||||||
|
- Linux
|
||||||
|
required_flags:
|
||||||
|
- avx2
|
||||||
|
- popcnt
|
||||||
44
src/crypto/pq/_d/Dilithium2_META.yml
Normal file
44
src/crypto/pq/_d/Dilithium2_META.yml
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
name: Dilithium2
|
||||||
|
type: signature
|
||||||
|
claimed-nist-level: 2
|
||||||
|
length-public-key: 1312
|
||||||
|
length-secret-key: 2560
|
||||||
|
length-signature: 2420
|
||||||
|
nistkat-sha256: 9a196e7fb32fbc93757dc2d8dc1924460eab66303c0c08aeb8b798fb8d8f8cf3
|
||||||
|
testvectors-sha256: 5f0d135c0f7fd43f3fb9727265fcd6ec3651eb8c67c04ea5f3d8dfa1d99740d2
|
||||||
|
principal-submitters:
|
||||||
|
- Vadim Lyubashevsky
|
||||||
|
auxiliary-submitters:
|
||||||
|
- Shi Bai
|
||||||
|
- Léo Ducas
|
||||||
|
- Eike Kiltz
|
||||||
|
- Tancrède Lepoint
|
||||||
|
- Peter Schwabe
|
||||||
|
- Gregor Seiler
|
||||||
|
- Damien Stehlé
|
||||||
|
implementations:
|
||||||
|
- name: ref
|
||||||
|
version: https://github.com/pq-crystals/dilithium/tree/master
|
||||||
|
folder_name: ref
|
||||||
|
compile_opts: -DDILITHIUM_MODE=2 -DDILITHIUM_RANDOMIZED_SIGNING
|
||||||
|
signature_keypair: pqcrystals_dilithium2_ref_keypair
|
||||||
|
signature_signature: pqcrystals_dilithium2_ref_signature
|
||||||
|
signature_verify: pqcrystals_dilithium2_ref_verify
|
||||||
|
sources: ../LICENSE api.h config.h params.h sign.c sign.h packing.c packing.h polyvec.c polyvec.h poly.c poly.h ntt.c ntt.h reduce.c reduce.h rounding.c rounding.h symmetric.h fips202.h symmetric-shake.c
|
||||||
|
common_dep: common_ref
|
||||||
|
- name: avx2
|
||||||
|
version: https://github.com/pq-crystals/dilithium/tree/master
|
||||||
|
compile_opts: -DDILITHIUM_MODE=2 -DDILITHIUM_RANDOMIZED_SIGNING
|
||||||
|
signature_keypair: pqcrystals_dilithium2_avx2_keypair
|
||||||
|
signature_signature: pqcrystals_dilithium2_avx2_signature
|
||||||
|
signature_verify: pqcrystals_dilithium2_avx2_verify
|
||||||
|
sources: ../LICENSE api.h config.h params.h align.h sign.c sign.h packing.c packing.h polyvec.c polyvec.h poly.c poly.h ntt.S invntt.S pointwise.S ntt.h shuffle.S shuffle.inc consts.c consts.h rejsample.c rejsample.h rounding.c rounding.h symmetric.h fips202.h fips202x4.h symmetric-shake.c
|
||||||
|
common_dep: common_avx2
|
||||||
|
supported_platforms:
|
||||||
|
- architecture: x86_64
|
||||||
|
operating_systems:
|
||||||
|
- Darwin
|
||||||
|
- Linux
|
||||||
|
required_flags:
|
||||||
|
- avx2
|
||||||
|
- popcnt
|
||||||
44
src/crypto/pq/_d/Dilithium3_META.yml
Normal file
44
src/crypto/pq/_d/Dilithium3_META.yml
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
name: Dilithium3
|
||||||
|
type: signature
|
||||||
|
claimed-nist-level: 3
|
||||||
|
length-public-key: 1952
|
||||||
|
length-secret-key: 4032
|
||||||
|
length-signature: 3309
|
||||||
|
nistkat-sha256: 7cb96242eac9907a55b5c84c202f0ebd552419c50b2e986dc2e28f07ecebf072
|
||||||
|
testvectors-sha256: 14bf84918ee90e7afbd580191d3eb890d4557e0900b1145e39a8399ef7dd3fba
|
||||||
|
principal-submitters:
|
||||||
|
- Vadim Lyubashevsky
|
||||||
|
auxiliary-submitters:
|
||||||
|
- Shi Bai
|
||||||
|
- Léo Ducas
|
||||||
|
- Eike Kiltz
|
||||||
|
- Tancrède Lepoint
|
||||||
|
- Peter Schwabe
|
||||||
|
- Gregor Seiler
|
||||||
|
- Damien Stehlé
|
||||||
|
implementations:
|
||||||
|
- name: ref
|
||||||
|
version: https://github.com/pq-crystals/dilithium/tree/master
|
||||||
|
folder_name: ref
|
||||||
|
compile_opts: -DDILITHIUM_MODE=3 -DDILITHIUM_RANDOMIZED_SIGNING
|
||||||
|
signature_keypair: pqcrystals_dilithium3_ref_keypair
|
||||||
|
signature_signature: pqcrystals_dilithium3_ref_signature
|
||||||
|
signature_verify: pqcrystals_dilithium3_ref_verify
|
||||||
|
sources: ../LICENSE api.h config.h params.h sign.c sign.h packing.c packing.h polyvec.c polyvec.h poly.c poly.h ntt.c ntt.h reduce.c reduce.h rounding.c rounding.h symmetric.h fips202.h symmetric-shake.c
|
||||||
|
common_dep: common_ref
|
||||||
|
- name: avx2
|
||||||
|
version: https://github.com/pq-crystals/dilithium/tree/master
|
||||||
|
compile_opts: -DDILITHIUM_MODE=3 -DDILITHIUM_RANDOMIZED_SIGNING
|
||||||
|
signature_keypair: pqcrystals_dilithium3_avx2_keypair
|
||||||
|
signature_signature: pqcrystals_dilithium3_avx2_signature
|
||||||
|
signature_verify: pqcrystals_dilithium3_avx2_verify
|
||||||
|
sources: ../LICENSE api.h config.h params.h align.h sign.c sign.h packing.c packing.h polyvec.c polyvec.h poly.c poly.h ntt.S invntt.S pointwise.S ntt.h shuffle.S shuffle.inc consts.c consts.h rejsample.c rejsample.h rounding.c rounding.h symmetric.h fips202.h fips202x4.h symmetric-shake.c
|
||||||
|
common_dep: common_avx2
|
||||||
|
supported_platforms:
|
||||||
|
- architecture: x86_64
|
||||||
|
operating_systems:
|
||||||
|
- Darwin
|
||||||
|
- Linux
|
||||||
|
required_flags:
|
||||||
|
- avx2
|
||||||
|
- popcnt
|
||||||
44
src/crypto/pq/_d/Dilithium5_META.yml
Normal file
44
src/crypto/pq/_d/Dilithium5_META.yml
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
name: Dilithium5
|
||||||
|
type: signature
|
||||||
|
claimed-nist-level: 5
|
||||||
|
length-public-key: 2592
|
||||||
|
length-secret-key: 4896
|
||||||
|
length-signature: 4627
|
||||||
|
nistkat-sha256: 4537905d2aabcf302fab2f242baed293459ecda7c230e6a67063b02c7e2840ed
|
||||||
|
testvectors-sha256: 759a3ba35210c7e27ff90a7ce5e399295533b82ef125e6ec98af158e00268e44
|
||||||
|
principal-submitters:
|
||||||
|
- Vadim Lyubashevsky
|
||||||
|
auxiliary-submitters:
|
||||||
|
- Shi Bai
|
||||||
|
- Léo Ducas
|
||||||
|
- Eike Kiltz
|
||||||
|
- Tancrède Lepoint
|
||||||
|
- Peter Schwabe
|
||||||
|
- Gregor Seiler
|
||||||
|
- Damien Stehlé
|
||||||
|
implementations:
|
||||||
|
- name: ref
|
||||||
|
version: https://github.com/pq-crystals/dilithium/tree/master
|
||||||
|
folder_name: ref
|
||||||
|
compile_opts: -DDILITHIUM_MODE=5 -DDILITHIUM_RANDOMIZED_SIGNING
|
||||||
|
signature_keypair: pqcrystals_dilithium5_ref_keypair
|
||||||
|
signature_signature: pqcrystals_dilithium5_ref_signature
|
||||||
|
signature_verify: pqcrystals_dilithium5_ref_verify
|
||||||
|
sources: ../LICENSE api.h config.h params.h sign.c sign.h packing.c packing.h polyvec.c polyvec.h poly.c poly.h ntt.c ntt.h reduce.c reduce.h rounding.c rounding.h symmetric.h fips202.h symmetric-shake.c
|
||||||
|
common_dep: common_ref
|
||||||
|
- name: avx2
|
||||||
|
version: https://github.com/pq-crystals/dilithium/tree/master
|
||||||
|
compile_opts: -DDILITHIUM_MODE=5 -DDILITHIUM_RANDOMIZED_SIGNING
|
||||||
|
signature_keypair: pqcrystals_dilithium5_avx2_keypair
|
||||||
|
signature_signature: pqcrystals_dilithium5_avx2_signature
|
||||||
|
signature_verify: pqcrystals_dilithium5_avx2_verify
|
||||||
|
sources: ../LICENSE api.h config.h params.h align.h sign.c sign.h packing.c packing.h polyvec.c polyvec.h poly.c poly.h ntt.S invntt.S pointwise.S ntt.h shuffle.S shuffle.inc consts.c consts.h rejsample.c rejsample.h rounding.c rounding.h symmetric.h fips202.h fips202x4.h symmetric-shake.c
|
||||||
|
common_dep: common_avx2
|
||||||
|
supported_platforms:
|
||||||
|
- architecture: x86_64
|
||||||
|
operating_systems:
|
||||||
|
- Darwin
|
||||||
|
- Linux
|
||||||
|
required_flags:
|
||||||
|
- avx2
|
||||||
|
- popcnt
|
||||||
7
src/crypto/pq/_d/LICENSE
Normal file
7
src/crypto/pq/_d/LICENSE
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
Public Domain (https://creativecommons.org/share-your-work/public-domain/cc0/);
|
||||||
|
or Apache 2.0 License (https://www.apache.org/licenses/LICENSE-2.0.html) or GPL 2.0 License (http://www.gnu.org/licenses/gpl-2.0.html).
|
||||||
|
|
||||||
|
For Keccak and the random number generator
|
||||||
|
we are using public-domain code from sources
|
||||||
|
and by authors listed in comments on top of
|
||||||
|
the respective files.
|
||||||
81
src/crypto/pq/_d/README.md
Normal file
81
src/crypto/pq/_d/README.md
Normal file
|
|
@ -0,0 +1,81 @@
|
||||||
|
# Dilithium
|
||||||
|
|
||||||
|
[](https://travis-ci.org/pq-crystals/dilithium) [](https://coveralls.io/github/pq-crystals/dilithium?branch=master)
|
||||||
|
|
||||||
|
This repository contains the official reference implementation of the [Dilithium](https://www.pq-crystals.org/dilithium/) signature scheme, and an optimized implementation for x86 CPUs supporting the AVX2 instruction set. Dilithium is standardized as [FIPS 204](https://csrc.nist.gov/pubs/fips/204/final).
|
||||||
|
|
||||||
|
## Build instructions
|
||||||
|
|
||||||
|
The implementations contain several test and benchmarking programs and a Makefile to facilitate compilation.
|
||||||
|
|
||||||
|
### Prerequisites
|
||||||
|
|
||||||
|
Some of the test programs require [OpenSSL](https://openssl.org). If the OpenSSL header files and/or shared libraries do not lie in one of the standard locations on your system, it is necessary to specify their location via compiler and linker flags in the environment variables `CFLAGS`, `NISTFLAGS`, and `LDFLAGS`.
|
||||||
|
|
||||||
|
For example, on macOS you can install OpenSSL via [Homebrew](https://brew.sh) by running
|
||||||
|
```sh
|
||||||
|
brew install openssl
|
||||||
|
```
|
||||||
|
Then, run
|
||||||
|
```sh
|
||||||
|
export CFLAGS="-I/opt/homebrew/opt/openssl@1.1/include"
|
||||||
|
export NISTFLAGS="-I/opt/homebrew/opt/openssl@1.1/include"
|
||||||
|
export LDFLAGS="-L/opt/homebrew/opt/openssl@1.1/lib"
|
||||||
|
```
|
||||||
|
before compilation to add the OpenSSL header and library locations to the respective search paths.
|
||||||
|
|
||||||
|
### Test programs
|
||||||
|
|
||||||
|
To compile the test programs on Linux or macOS, go to the `ref/` or `avx2/` directory and run
|
||||||
|
```sh
|
||||||
|
make
|
||||||
|
```
|
||||||
|
This produces the executables
|
||||||
|
```sh
|
||||||
|
test/test_dilithium$ALG
|
||||||
|
test/test_vectors$ALG
|
||||||
|
```
|
||||||
|
where `$ALG` ranges over the parameter sets 2, 3, and 5.
|
||||||
|
|
||||||
|
* `test_dilithium$ALG` tests 10000 times to generate keys, sign a random message of 59 bytes and verify the produced signature. Also, the program will try to verify wrong signatures where a single random byte of a valid signature was randomly distorted. The program will abort with an error message and return -1 if there was an error. Otherwise it will output the key and signature sizes and return 0.
|
||||||
|
* `test_vectors$ALG` performs further tests of internal functions and prints deterministically generated test vectors for several intermediate values that occur in the Dilithium algorithms. Namely, a 48 byte seed, the matrix A corresponding to the first 32 bytes of seed, a short secret vector s corresponding to the first 32 bytes of seed and nonce 0, a masking vector y corresponding to the seed and nonce 0, the high bits w1 and the low bits w0 of the vector w = Ay, the power-of-two rounding t1 of w and the corresponding low part t0, and the challenge c for the seed and w1. This program is meant to help to ensure compatibility of independent implementations.
|
||||||
|
|
||||||
|
### Benchmarking programs
|
||||||
|
|
||||||
|
For benchmarking the implementations, we provide speed test programs for x86 CPUs that use the Time Step Counter (TSC) or the actual cycle counter provided by the Performance Measurement Counters (PMC) to measure performance. To compile the programs run
|
||||||
|
```sh
|
||||||
|
make speed
|
||||||
|
```
|
||||||
|
This produces the executables
|
||||||
|
```sh
|
||||||
|
test/test_speed$ALG
|
||||||
|
```
|
||||||
|
for all parameter sets `$ALG` as above. The programs report the median and average cycle counts of 10000 executions of various internal functions and the API functions for key generation, signing and verification. By default the Time Step Counter is used. If instead you want to obtain the actual cycle counts from the Performance Measurement Counters export `CFLAGS="-DUSE_RDPMC"` before compilation.
|
||||||
|
|
||||||
|
Please note that the reference implementation in `ref/` is not optimized for any platform, and, since it prioritises clean code, is significantly slower than a trivially optimized but still platform-independent implementation. Hence benchmarking the reference code does not provide representative results.
|
||||||
|
|
||||||
|
Our Dilithium implementations are contained in the [SUPERCOP](https://bench.cr.yp.to) benchmarking framework. See [here](http://bench.cr.yp.to/results-sign.html#amd64-kizomba) for current cycle counts on an Intel KabyLake CPU.
|
||||||
|
|
||||||
|
## Randomized signing
|
||||||
|
|
||||||
|
By default our code implements Dilithium's hedged signing mode. To change this to the deterministic signing mode, undefine the `DILITHIUM_RANDOMIZED_SIGNING` preprocessor macro at compilation by either commenting the line
|
||||||
|
```sh
|
||||||
|
#define DILITHIUM_RANDOMIZED_SIGNING
|
||||||
|
```
|
||||||
|
in config.h, or adding `-UDILITHIUM_RANDOMIZED_SIGNING` to the compiler flags in the environment variable `CFLAGS`.
|
||||||
|
|
||||||
|
## Shared libraries
|
||||||
|
|
||||||
|
All implementations can be compiled into shared libraries by running
|
||||||
|
```sh
|
||||||
|
make shared
|
||||||
|
```
|
||||||
|
For example in the directory `ref/` of the reference implementation, this produces the libraries
|
||||||
|
```sh
|
||||||
|
libpqcrystals_dilithium$ALG_ref.so
|
||||||
|
```
|
||||||
|
for all parameter sets `$ALG`, and the required symmetric crypto library
|
||||||
|
```
|
||||||
|
libpqcrystals_fips202_ref.so
|
||||||
|
```
|
||||||
|
All global symbols in the libraries lie in the namespaces `pqcrystals_dilithium$ALG_ref` and `libpqcrystals_fips202_ref`. Hence it is possible to link a program against all libraries simultaneously and obtain access to all implementations for all parameter sets. The corresponding API header file is `ref/api.h`, which contains prototypes for all API functions and preprocessor defines for the key and signature lengths.
|
||||||
3
src/crypto/pq/_d/SHA256SUMS
Normal file
3
src/crypto/pq/_d/SHA256SUMS
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
5f0d135c0f7fd43f3fb9727265fcd6ec3651eb8c67c04ea5f3d8dfa1d99740d2 tvecs2
|
||||||
|
14bf84918ee90e7afbd580191d3eb890d4557e0900b1145e39a8399ef7dd3fba tvecs3
|
||||||
|
759a3ba35210c7e27ff90a7ce5e399295533b82ef125e6ec98af158e00268e44 tvecs5
|
||||||
2
src/crypto/pq/_d/avx2/.gitignore
vendored
Normal file
2
src/crypto/pq/_d/avx2/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
*.so
|
||||||
|
*.o
|
||||||
19
src/crypto/pq/_d/avx2/align.h
Normal file
19
src/crypto/pq/_d/avx2/align.h
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
#ifndef ALIGN_H
|
||||||
|
#define ALIGN_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <immintrin.h>
|
||||||
|
|
||||||
|
#define ALIGNED_UINT8(N) \
|
||||||
|
union { \
|
||||||
|
uint8_t coeffs[N]; \
|
||||||
|
__m256i vec[(N+31)/32]; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ALIGNED_INT32(N) \
|
||||||
|
union { \
|
||||||
|
int32_t coeffs[N]; \
|
||||||
|
__m256i vec[(N+7)/8]; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
100
src/crypto/pq/_d/avx2/api.h
Normal file
100
src/crypto/pq/_d/avx2/api.h
Normal file
|
|
@ -0,0 +1,100 @@
|
||||||
|
#ifndef API_H
|
||||||
|
#define API_H
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define pqcrystals_dilithium2_PUBLICKEYBYTES 1312
|
||||||
|
#define pqcrystals_dilithium2_SECRETKEYBYTES 2560
|
||||||
|
#define pqcrystals_dilithium2_BYTES 2420
|
||||||
|
|
||||||
|
#define pqcrystals_dilithium2_avx2_PUBLICKEYBYTES pqcrystals_dilithium2_PUBLICKEYBYTES
|
||||||
|
#define pqcrystals_dilithium2_avx2_SECRETKEYBYTES pqcrystals_dilithium2_SECRETKEYBYTES
|
||||||
|
#define pqcrystals_dilithium2_avx2_BYTES pqcrystals_dilithium2_BYTES
|
||||||
|
|
||||||
|
int pqcrystals_dilithium2_avx2_keypair(uint8_t *pk, uint8_t *sk);
|
||||||
|
|
||||||
|
int pqcrystals_dilithium2_avx2_signature(uint8_t *sig, size_t *siglen,
|
||||||
|
const uint8_t *m, size_t mlen,
|
||||||
|
const uint8_t *ctx, size_t ctxlen,
|
||||||
|
const uint8_t *sk);
|
||||||
|
|
||||||
|
int pqcrystals_dilithium2_avx2(uint8_t *sm, size_t *smlen,
|
||||||
|
const uint8_t *m, size_t mlen,
|
||||||
|
const uint8_t *ctx, size_t ctxlen,
|
||||||
|
const uint8_t *sk);
|
||||||
|
|
||||||
|
int pqcrystals_dilithium2_avx2_verify(const uint8_t *sig, size_t siglen,
|
||||||
|
const uint8_t *m, size_t mlen,
|
||||||
|
const uint8_t *ctx, size_t ctxlen,
|
||||||
|
const uint8_t *pk);
|
||||||
|
|
||||||
|
int pqcrystals_dilithium2_avx2_open(uint8_t *m, size_t *mlen,
|
||||||
|
const uint8_t *sm, size_t smlen,
|
||||||
|
const uint8_t *ctx, size_t ctxlen,
|
||||||
|
const uint8_t *pk);
|
||||||
|
|
||||||
|
|
||||||
|
#define pqcrystals_dilithium3_PUBLICKEYBYTES 1952
|
||||||
|
#define pqcrystals_dilithium3_SECRETKEYBYTES 4032
|
||||||
|
#define pqcrystals_dilithium3_BYTES 3309
|
||||||
|
|
||||||
|
#define pqcrystals_dilithium3_avx2_PUBLICKEYBYTES pqcrystals_dilithium3_PUBLICKEYBYTES
|
||||||
|
#define pqcrystals_dilithium3_avx2_SECRETKEYBYTES pqcrystals_dilithium3_SECRETKEYBYTES
|
||||||
|
#define pqcrystals_dilithium3_avx2_BYTES pqcrystals_dilithium3_BYTES
|
||||||
|
|
||||||
|
int pqcrystals_dilithium3_avx2_keypair(uint8_t *pk, uint8_t *sk);
|
||||||
|
|
||||||
|
int pqcrystals_dilithium3_avx2_signature(uint8_t *sig, size_t *siglen,
|
||||||
|
const uint8_t *m, size_t mlen,
|
||||||
|
const uint8_t *ctx, size_t ctxlen,
|
||||||
|
const uint8_t *sk);
|
||||||
|
|
||||||
|
int pqcrystals_dilithium3_avx2(uint8_t *sm, size_t *smlen,
|
||||||
|
const uint8_t *m, size_t mlen,
|
||||||
|
const uint8_t *ctx, size_t ctxlen,
|
||||||
|
const uint8_t *sk);
|
||||||
|
|
||||||
|
int pqcrystals_dilithium3_avx2_verify(const uint8_t *sig, size_t siglen,
|
||||||
|
const uint8_t *m, size_t mlen,
|
||||||
|
const uint8_t *ctx, size_t ctxlen,
|
||||||
|
const uint8_t *pk);
|
||||||
|
|
||||||
|
int pqcrystals_dilithium3_avx2_open(uint8_t *m, size_t *mlen,
|
||||||
|
const uint8_t *sm, size_t smlen,
|
||||||
|
const uint8_t *ctx, size_t ctxlen,
|
||||||
|
const uint8_t *pk);
|
||||||
|
|
||||||
|
|
||||||
|
#define pqcrystals_dilithium5_PUBLICKEYBYTES 2592
|
||||||
|
#define pqcrystals_dilithium5_SECRETKEYBYTES 4896
|
||||||
|
#define pqcrystals_dilithium5_BYTES 4627
|
||||||
|
|
||||||
|
#define pqcrystals_dilithium5_avx2_PUBLICKEYBYTES pqcrystals_dilithium5_PUBLICKEYBYTES
|
||||||
|
#define pqcrystals_dilithium5_avx2_SECRETKEYBYTES pqcrystals_dilithium5_SECRETKEYBYTES
|
||||||
|
#define pqcrystals_dilithium5_avx2_BYTES pqcrystals_dilithium5_BYTES
|
||||||
|
|
||||||
|
int pqcrystals_dilithium5_avx2_keypair(uint8_t *pk, uint8_t *sk);
|
||||||
|
|
||||||
|
int pqcrystals_dilithium5_avx2_signature(uint8_t *sig, size_t *siglen,
|
||||||
|
const uint8_t *m, size_t mlen,
|
||||||
|
const uint8_t *ctx, size_t ctxlen,
|
||||||
|
const uint8_t *sk);
|
||||||
|
|
||||||
|
int pqcrystals_dilithium5_avx2(uint8_t *sm, size_t *smlen,
|
||||||
|
const uint8_t *m, size_t mlen,
|
||||||
|
const uint8_t *ctx, size_t ctxlen,
|
||||||
|
const uint8_t *sk);
|
||||||
|
|
||||||
|
int pqcrystals_dilithium5_avx2_verify(const uint8_t *sig, size_t siglen,
|
||||||
|
const uint8_t *m, size_t mlen,
|
||||||
|
const uint8_t *ctx, size_t ctxlen,
|
||||||
|
const uint8_t *pk);
|
||||||
|
|
||||||
|
int pqcrystals_dilithium5_avx2_open(uint8_t *m, size_t *mlen,
|
||||||
|
const uint8_t *sm, size_t smlen,
|
||||||
|
const uint8_t *ctx, size_t ctxlen,
|
||||||
|
const uint8_t *pk);
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
27
src/crypto/pq/_d/avx2/config.h
Normal file
27
src/crypto/pq/_d/avx2/config.h
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
#ifndef CONFIG_H
|
||||||
|
#define CONFIG_H
|
||||||
|
|
||||||
|
//#define DILITHIUM_MODE 2
|
||||||
|
#define DILITHIUM_RANDOMIZED_SIGNING
|
||||||
|
//#define USE_RDPMC
|
||||||
|
//#define DBENCH
|
||||||
|
|
||||||
|
#ifndef DILITHIUM_MODE
|
||||||
|
#define DILITHIUM_MODE 2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if DILITHIUM_MODE == 2
|
||||||
|
#define CRYPTO_ALGNAME "Dilithium2"
|
||||||
|
#define DILITHIUM_NAMESPACETOP pqcrystals_dilithium2_avx2
|
||||||
|
#define DILITHIUM_NAMESPACE(s) pqcrystals_dilithium2_avx2_##s
|
||||||
|
#elif DILITHIUM_MODE == 3
|
||||||
|
#define CRYPTO_ALGNAME "Dilithium3"
|
||||||
|
#define DILITHIUM_NAMESPACETOP pqcrystals_dilithium3_avx2
|
||||||
|
#define DILITHIUM_NAMESPACE(s) pqcrystals_dilithium3_avx2_##s
|
||||||
|
#elif DILITHIUM_MODE == 5
|
||||||
|
#define CRYPTO_ALGNAME "Dilithium5"
|
||||||
|
#define DILITHIUM_NAMESPACETOP pqcrystals_dilithium5_avx2
|
||||||
|
#define DILITHIUM_NAMESPACE(s) pqcrystals_dilithium5_avx2_##s
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
100
src/crypto/pq/_d/avx2/consts.c
Normal file
100
src/crypto/pq/_d/avx2/consts.c
Normal file
|
|
@ -0,0 +1,100 @@
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "params.h"
|
||||||
|
#include "consts.h"
|
||||||
|
|
||||||
|
#define QINV 58728449 // q^(-1) mod 2^32
|
||||||
|
#define MONT -4186625 // 2^32 mod q
|
||||||
|
#define DIV 41978 // mont^2/256
|
||||||
|
#define DIV_QINV -8395782
|
||||||
|
|
||||||
|
const qdata_t qdata = {{
|
||||||
|
#define _8XQ 0
|
||||||
|
Q, Q, Q, Q, Q, Q, Q, Q,
|
||||||
|
|
||||||
|
#define _8XQINV 8
|
||||||
|
QINV, QINV, QINV, QINV, QINV, QINV, QINV, QINV,
|
||||||
|
|
||||||
|
#define _8XDIV_QINV 16
|
||||||
|
DIV_QINV, DIV_QINV, DIV_QINV, DIV_QINV, DIV_QINV, DIV_QINV, DIV_QINV, DIV_QINV,
|
||||||
|
|
||||||
|
#define _8XDIV 24
|
||||||
|
DIV, DIV, DIV, DIV, DIV, DIV, DIV, DIV,
|
||||||
|
|
||||||
|
#define _ZETAS_QINV 32
|
||||||
|
-151046689, 1830765815, -1929875198, -1927777021, 1640767044, 1477910808, 1612161320, 1640734244,
|
||||||
|
308362795, 308362795, 308362795, 308362795, -1815525077, -1815525077, -1815525077, -1815525077,
|
||||||
|
-1374673747, -1374673747, -1374673747, -1374673747, -1091570561, -1091570561, -1091570561, -1091570561,
|
||||||
|
-1929495947, -1929495947, -1929495947, -1929495947, 515185417, 515185417, 515185417, 515185417,
|
||||||
|
-285697463, -285697463, -285697463, -285697463, 625853735, 625853735, 625853735, 625853735,
|
||||||
|
1727305304, 1727305304, 2082316400, 2082316400, -1364982364, -1364982364, 858240904, 858240904,
|
||||||
|
1806278032, 1806278032, 222489248, 222489248, -346752664, -346752664, 684667771, 684667771,
|
||||||
|
1654287830, 1654287830, -878576921, -878576921, -1257667337, -1257667337, -748618600, -748618600,
|
||||||
|
329347125, 329347125, 1837364258, 1837364258, -1443016191, -1443016191, -1170414139, -1170414139,
|
||||||
|
-1846138265, -1631226336, -1404529459, 1838055109, 1594295555, -1076973524, -1898723372, -594436433,
|
||||||
|
-202001019, -475984260, -561427818, 1797021249, -1061813248, 2059733581, -1661512036, -1104976547,
|
||||||
|
-1750224323, -901666090, 418987550, 1831915353, -1925356481, 992097815, 879957084, 2024403852,
|
||||||
|
1484874664, -1636082790, -285388938, -1983539117, -1495136972, -950076368, -1714807468, -952438995,
|
||||||
|
-1574918427, 1350681039, -2143979939, 1599739335, -1285853323, -993005454, -1440787840, 568627424,
|
||||||
|
-783134478, -588790216, 289871779, -1262003603, 2135294594, -1018755525, -889861155, 1665705315,
|
||||||
|
1321868265, 1225434135, -1784632064, 666258756, 675310538, -1555941048, -1999506068, -1499481951,
|
||||||
|
-695180180, -1375177022, 1777179795, 334803717, -178766299, -518252220, 1957047970, 1146323031,
|
||||||
|
-654783359, -1974159335, 1651689966, 140455867, -1039411342, 1955560694, 1529189038, -2131021878,
|
||||||
|
-247357819, 1518161567, -86965173, 1708872713, 1787797779, 1638590967, -120646188, -1669960606,
|
||||||
|
-916321552, 1155548552, 2143745726, 1210558298, -1261461890, -318346816, 628664287, -1729304568,
|
||||||
|
1422575624, 1424130038, -1185330464, 235321234, 168022240, 1206536194, 985155484, -894060583,
|
||||||
|
-898413, -1363460238, -605900043, 2027833504, 14253662, 1014493059, 863641633, 1819892093,
|
||||||
|
2124962073, -1223601433, -1920467227, -1637785316, -1536588520, 694382729, 235104446, -1045062172,
|
||||||
|
831969619, -300448763, 756955444, -260312805, 1554794072, 1339088280, -2040058690, -853476187,
|
||||||
|
-2047270596, -1723816713, -1591599803, -440824168, 1119856484, 1544891539, 155290192, -973777462,
|
||||||
|
991903578, 912367099, -44694137, 1176904444, -421552614, -818371958, 1747917558, -325927722,
|
||||||
|
908452108, 1851023419, -1176751719, -1354528380, -72690498, -314284737, 985022747, 963438279,
|
||||||
|
-1078959975, 604552167, -1021949428, 608791570, 173440395, -2126092136, -1316619236, -1039370342,
|
||||||
|
6087993, -110126092, 565464272, -1758099917, -1600929361, 879867909, -1809756372, 400711272,
|
||||||
|
1363007700, 30313375, -326425360, 1683520342, -517299994, 2027935492, -1372618620, 128353682,
|
||||||
|
-1123881663, 137583815, -635454918, -642772911, 45766801, 671509323, -2070602178, 419615363,
|
||||||
|
1216882040, -270590488, -1276805128, 371462360, -1357098057, -384158533, 827959816, -596344473,
|
||||||
|
702390549, -279505433, -260424530, -71875110, -1208667171, -1499603926, 2036925262, -540420426,
|
||||||
|
746144248, -1420958686, 2032221021, 1904936414, 1257750362, 1926727420, 1931587462, 1258381762,
|
||||||
|
885133339, 1629985060, 1967222129, 6363718, -1287922800, 1136965286, 1779436847, 1116720494,
|
||||||
|
1042326957, 1405999311, 713994583, 940195359, -1542497137, 2061661095, -883155599, 1726753853,
|
||||||
|
-1547952704, 394851342, 283780712, 776003547, 1123958025, 201262505, 1934038751, 374860238,
|
||||||
|
|
||||||
|
#define _ZETAS 328
|
||||||
|
-3975713, 25847, -2608894, -518909, 237124, -777960, -876248, 466468,
|
||||||
|
1826347, 1826347, 1826347, 1826347, 2353451, 2353451, 2353451, 2353451,
|
||||||
|
-359251, -359251, -359251, -359251, -2091905, -2091905, -2091905, -2091905,
|
||||||
|
3119733, 3119733, 3119733, 3119733, -2884855, -2884855, -2884855, -2884855,
|
||||||
|
3111497, 3111497, 3111497, 3111497, 2680103, 2680103, 2680103, 2680103,
|
||||||
|
2725464, 2725464, 1024112, 1024112, -1079900, -1079900, 3585928, 3585928,
|
||||||
|
-549488, -549488, -1119584, -1119584, 2619752, 2619752, -2108549, -2108549,
|
||||||
|
-2118186, -2118186, -3859737, -3859737, -1399561, -1399561, -3277672, -3277672,
|
||||||
|
1757237, 1757237, -19422, -19422, 4010497, 4010497, 280005, 280005,
|
||||||
|
2706023, 95776, 3077325, 3530437, -1661693, -3592148, -2537516, 3915439,
|
||||||
|
-3861115, -3043716, 3574422, -2867647, 3539968, -300467, 2348700, -539299,
|
||||||
|
-1699267, -1643818, 3505694, -3821735, 3507263, -2140649, -1600420, 3699596,
|
||||||
|
811944, 531354, 954230, 3881043, 3900724, -2556880, 2071892, -2797779,
|
||||||
|
-3930395, -3677745, -1452451, 2176455, -1257611, -4083598, -3190144, -3632928,
|
||||||
|
3412210, 2147896, -2967645, -411027, -671102, -22981, -381987, 1852771,
|
||||||
|
-3343383, 508951, 44288, 904516, -3724342, 1653064, 2389356, 759969,
|
||||||
|
189548, 3159746, -2409325, 1315589, 1285669, -812732, -3019102, -3628969,
|
||||||
|
-1528703, -3041255, 3475950, -1585221, 1939314, -1000202, -3157330, 126922,
|
||||||
|
-983419, 2715295, -3693493, -2477047, -1228525, -1308169, 1349076, -1430430,
|
||||||
|
264944, 3097992, -1100098, 3958618, -8578, -3249728, -210977, -1316856,
|
||||||
|
-3553272, -1851402, -177440, 1341330, -1584928, -1439742, -3881060, 3839961,
|
||||||
|
2091667, -3342478, 266997, -3520352, 900702, 495491, -655327, -3556995,
|
||||||
|
342297, 3437287, 2842341, 4055324, -3767016, -2994039, -1333058, -451100,
|
||||||
|
-1279661, 1500165, -542412, -2584293, -2013608, 1957272, -3183426, 810149,
|
||||||
|
-3038916, 2213111, -426683, -1667432, -2939036, 183443, -554416, 3937738,
|
||||||
|
3407706, 2244091, 2434439, -3759364, 1859098, -1613174, -3122442, -525098,
|
||||||
|
286988, -3342277, 2691481, 1247620, 1250494, 1869119, 1237275, 1312455,
|
||||||
|
1917081, 777191, -2831860, -3724270, 2432395, 3369112, 162844, 1652634,
|
||||||
|
3523897, -975884, 1723600, -1104333, -2235985, -976891, 3919660, 1400424,
|
||||||
|
2316500, -2446433, -1235728, -1197226, 909542, -43260, 2031748, -768622,
|
||||||
|
-2437823, 1735879, -2590150, 2486353, 2635921, 1903435, -3318210, 3306115,
|
||||||
|
-2546312, 2235880, -1671176, 594136, 2454455, 185531, 1616392, -3694233,
|
||||||
|
3866901, 1717735, -1803090, -260646, -420899, 1612842, -48306, -846154,
|
||||||
|
3817976, -3562462, 3513181, -3193378, 819034, -522500, 3207046, -3595838,
|
||||||
|
4108315, 203044, 1265009, 1595974, -3548272, -1050970, -1430225, -1962642,
|
||||||
|
-1374803, 3406031, -1846953, -3776993, -164721, -1207385, 3014001, -1799107,
|
||||||
|
269760, 472078, 1910376, -3833893, -2286327, -3545687, -1362209, 1976782,
|
||||||
|
}};
|
||||||
38
src/crypto/pq/_d/avx2/consts.h
Normal file
38
src/crypto/pq/_d/avx2/consts.h
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
#ifndef CONSTS_H
|
||||||
|
#define CONSTS_H
|
||||||
|
|
||||||
|
#include "params.h"
|
||||||
|
|
||||||
|
#define _8XQ 0
|
||||||
|
#define _8XQINV 8
|
||||||
|
#define _8XDIV_QINV 16
|
||||||
|
#define _8XDIV 24
|
||||||
|
#define _ZETAS_QINV 32
|
||||||
|
#define _ZETAS 328
|
||||||
|
|
||||||
|
/* The C ABI on MacOS exports all symbols with a leading
|
||||||
|
* underscore. This means that any symbols we refer to from
|
||||||
|
* C files (functions) can't be found, and all symbols we
|
||||||
|
* refer to from ASM also can't be found.
|
||||||
|
*
|
||||||
|
* This define helps us get around this
|
||||||
|
*/
|
||||||
|
#if defined(__WIN32__) || defined(__APPLE__)
|
||||||
|
#define decorate(s) _##s
|
||||||
|
#define _cdecl(s) decorate(s)
|
||||||
|
#define cdecl(s) _cdecl(DILITHIUM_NAMESPACE(##s))
|
||||||
|
#else
|
||||||
|
#define cdecl(s) DILITHIUM_NAMESPACE(##s)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __ASSEMBLER__
|
||||||
|
|
||||||
|
#include "align.h"
|
||||||
|
|
||||||
|
typedef ALIGNED_INT32(624) qdata_t;
|
||||||
|
|
||||||
|
#define qdata DILITHIUM_NAMESPACE(qdata)
|
||||||
|
extern const qdata_t qdata;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
909
src/crypto/pq/_d/avx2/f1600x4.S
Normal file
909
src/crypto/pq/_d/avx2/f1600x4.S
Normal file
|
|
@ -0,0 +1,909 @@
|
||||||
|
/* Taken from Bas Westerbaan's new 4-way SHAKE implementation
|
||||||
|
* for Sphincs+ (https://github.com/sphincs/sphincsplus/pull/14/),
|
||||||
|
* but uses vpshufb for byte-granular rotations as in the Keccak Code Package. */
|
||||||
|
|
||||||
|
#include "fips202x4.h"
|
||||||
|
|
||||||
|
.data
|
||||||
|
.p2align 5
|
||||||
|
rho8:
|
||||||
|
.byte 7,0,1,2,3,4,5,6,15,8,9,10,11,12,13,14,7,0,1,2,3,4,5,6,15,8,9,10,11,12,13,14
|
||||||
|
rho56:
|
||||||
|
.byte 1,2,3,4,5,6,7,0,9,10,11,12,13,14,15,8,1,2,3,4,5,6,7,0,9,10,11,12,13,14,15,8
|
||||||
|
|
||||||
|
.text
|
||||||
|
.global cdecl(f1600x4)
|
||||||
|
cdecl(f1600x4):
|
||||||
|
vmovdqa rho8(%rip), %ymm0
|
||||||
|
movq $6, %rax
|
||||||
|
looptop:
|
||||||
|
vmovdqa 0(%rdi), %ymm8
|
||||||
|
vmovdqa 32(%rdi), %ymm9
|
||||||
|
vmovdqa 64(%rdi), %ymm10
|
||||||
|
vmovdqa 96(%rdi), %ymm11
|
||||||
|
vmovdqa 128(%rdi), %ymm12
|
||||||
|
vpxor 160(%rdi), %ymm8, %ymm8
|
||||||
|
vpxor 192(%rdi), %ymm9, %ymm9
|
||||||
|
vpxor 224(%rdi), %ymm10, %ymm10
|
||||||
|
vpxor 256(%rdi), %ymm11, %ymm11
|
||||||
|
vpxor 288(%rdi), %ymm12, %ymm12
|
||||||
|
vpxor 320(%rdi), %ymm8, %ymm8
|
||||||
|
vpxor 352(%rdi), %ymm9, %ymm9
|
||||||
|
vpxor 384(%rdi), %ymm10, %ymm10
|
||||||
|
vpxor 416(%rdi), %ymm11, %ymm11
|
||||||
|
vpxor 448(%rdi), %ymm12, %ymm12
|
||||||
|
vpxor 480(%rdi), %ymm8, %ymm8
|
||||||
|
vpxor 512(%rdi), %ymm9, %ymm9
|
||||||
|
vpxor 544(%rdi), %ymm10, %ymm10
|
||||||
|
vpxor 576(%rdi), %ymm11, %ymm11
|
||||||
|
vpxor 608(%rdi), %ymm12, %ymm12
|
||||||
|
vpxor 640(%rdi), %ymm8, %ymm8
|
||||||
|
vpxor 672(%rdi), %ymm9, %ymm9
|
||||||
|
vpxor 704(%rdi), %ymm10, %ymm10
|
||||||
|
vpxor 736(%rdi), %ymm11, %ymm11
|
||||||
|
vpxor 768(%rdi), %ymm12, %ymm12
|
||||||
|
vpsllq $1, %ymm9, %ymm13
|
||||||
|
vpsllq $1, %ymm10, %ymm14
|
||||||
|
vpsllq $1, %ymm11, %ymm15
|
||||||
|
vpsllq $1, %ymm12, %ymm7
|
||||||
|
vpsllq $1, %ymm8, %ymm6
|
||||||
|
vpsrlq $63, %ymm9, %ymm5
|
||||||
|
vpsrlq $63, %ymm10, %ymm4
|
||||||
|
vpsrlq $63, %ymm11, %ymm3
|
||||||
|
vpsrlq $63, %ymm12, %ymm2
|
||||||
|
vpsrlq $63, %ymm8, %ymm1
|
||||||
|
vpor %ymm13, %ymm5, %ymm5
|
||||||
|
vpor %ymm14, %ymm4, %ymm4
|
||||||
|
vpor %ymm15, %ymm3, %ymm3
|
||||||
|
vpor %ymm7, %ymm2, %ymm2
|
||||||
|
vpor %ymm6, %ymm1, %ymm1
|
||||||
|
vpxor %ymm5, %ymm12, %ymm5
|
||||||
|
vpxor %ymm4, %ymm8, %ymm4
|
||||||
|
vpxor %ymm3, %ymm9, %ymm3
|
||||||
|
vpxor %ymm2, %ymm10, %ymm2
|
||||||
|
vpxor %ymm1, %ymm11, %ymm1
|
||||||
|
vpxor 0(%rdi), %ymm5, %ymm8
|
||||||
|
vpxor 192(%rdi), %ymm4, %ymm9
|
||||||
|
vpxor 384(%rdi), %ymm3, %ymm10
|
||||||
|
vpxor 576(%rdi), %ymm2, %ymm11
|
||||||
|
vpxor 768(%rdi), %ymm1, %ymm12
|
||||||
|
vpsllq $44, %ymm9, %ymm14
|
||||||
|
vpsllq $43, %ymm10, %ymm15
|
||||||
|
vpsllq $21, %ymm11, %ymm7
|
||||||
|
vpsllq $14, %ymm12, %ymm6
|
||||||
|
vpsrlq $20, %ymm9, %ymm9
|
||||||
|
vpsrlq $21, %ymm10, %ymm10
|
||||||
|
vpsrlq $43, %ymm11, %ymm11
|
||||||
|
vpsrlq $50, %ymm12, %ymm12
|
||||||
|
vpor %ymm14, %ymm9, %ymm9
|
||||||
|
vpor %ymm15, %ymm10, %ymm10
|
||||||
|
vpor %ymm7, %ymm11, %ymm11
|
||||||
|
vpor %ymm6, %ymm12, %ymm12
|
||||||
|
vpandn %ymm10, %ymm9, %ymm13
|
||||||
|
vpandn %ymm11, %ymm10, %ymm14
|
||||||
|
vpandn %ymm12, %ymm11, %ymm15
|
||||||
|
vpandn %ymm8, %ymm12, %ymm7
|
||||||
|
vpandn %ymm9, %ymm8, %ymm6
|
||||||
|
vpxor %ymm8, %ymm13, %ymm13
|
||||||
|
vpxor %ymm9, %ymm14, %ymm14
|
||||||
|
vpxor %ymm10, %ymm15, %ymm15
|
||||||
|
vpxor %ymm11, %ymm7, %ymm7
|
||||||
|
vpxor %ymm12, %ymm6, %ymm6
|
||||||
|
vpbroadcastq 0(%rsi), %ymm8
|
||||||
|
vpxor %ymm8, %ymm13, %ymm13
|
||||||
|
vmovdqa %ymm13, 0(%rdi)
|
||||||
|
vmovdqa %ymm14, 192(%rdi)
|
||||||
|
vmovdqa %ymm15, 384(%rdi)
|
||||||
|
vmovdqa %ymm7, 576(%rdi)
|
||||||
|
vmovdqa %ymm6, 768(%rdi)
|
||||||
|
vpxor 96(%rdi), %ymm2, %ymm8
|
||||||
|
vpxor 288(%rdi), %ymm1, %ymm9
|
||||||
|
vpxor 320(%rdi), %ymm5, %ymm10
|
||||||
|
vpxor 512(%rdi), %ymm4, %ymm11
|
||||||
|
vpxor 704(%rdi), %ymm3, %ymm12
|
||||||
|
vpsllq $28, %ymm8, %ymm13
|
||||||
|
vpsllq $20, %ymm9, %ymm14
|
||||||
|
vpsllq $3, %ymm10, %ymm15
|
||||||
|
vpsllq $45, %ymm11, %ymm7
|
||||||
|
vpsllq $61, %ymm12, %ymm6
|
||||||
|
vpsrlq $36, %ymm8, %ymm8
|
||||||
|
vpsrlq $44, %ymm9, %ymm9
|
||||||
|
vpsrlq $61, %ymm10, %ymm10
|
||||||
|
vpsrlq $19, %ymm11, %ymm11
|
||||||
|
vpsrlq $3, %ymm12, %ymm12
|
||||||
|
vpor %ymm13, %ymm8, %ymm8
|
||||||
|
vpor %ymm14, %ymm9, %ymm9
|
||||||
|
vpor %ymm15, %ymm10, %ymm10
|
||||||
|
vpor %ymm7, %ymm11, %ymm11
|
||||||
|
vpor %ymm6, %ymm12, %ymm12
|
||||||
|
vpandn %ymm10, %ymm9, %ymm13
|
||||||
|
vpandn %ymm11, %ymm10, %ymm14
|
||||||
|
vpandn %ymm12, %ymm11, %ymm15
|
||||||
|
vpandn %ymm8, %ymm12, %ymm7
|
||||||
|
vpandn %ymm9, %ymm8, %ymm6
|
||||||
|
vpxor %ymm8, %ymm13, %ymm13
|
||||||
|
vpxor %ymm9, %ymm14, %ymm14
|
||||||
|
vpxor %ymm10, %ymm15, %ymm15
|
||||||
|
vpxor %ymm11, %ymm7, %ymm7
|
||||||
|
vpxor %ymm12, %ymm6, %ymm6
|
||||||
|
vmovdqa %ymm13, 320(%rdi)
|
||||||
|
vmovdqa %ymm14, 512(%rdi)
|
||||||
|
vmovdqa %ymm15, 704(%rdi)
|
||||||
|
vmovdqa %ymm7, 96(%rdi)
|
||||||
|
vmovdqa %ymm6, 288(%rdi)
|
||||||
|
vpxor 32(%rdi), %ymm4, %ymm8
|
||||||
|
vpxor 224(%rdi), %ymm3, %ymm9
|
||||||
|
vpxor 416(%rdi), %ymm2, %ymm10
|
||||||
|
vpxor 608(%rdi), %ymm1, %ymm11
|
||||||
|
vpxor 640(%rdi), %ymm5, %ymm12
|
||||||
|
vpsllq $1, %ymm8, %ymm13
|
||||||
|
vpsllq $6, %ymm9, %ymm14
|
||||||
|
vpsllq $25, %ymm10, %ymm15
|
||||||
|
#vpsllq $8, %ymm11, %ymm7
|
||||||
|
vpsllq $18, %ymm12, %ymm6
|
||||||
|
vpsrlq $63, %ymm8, %ymm8
|
||||||
|
vpsrlq $58, %ymm9, %ymm9
|
||||||
|
vpsrlq $39, %ymm10, %ymm10
|
||||||
|
#vpsrlq $56, %ymm11, %ymm11
|
||||||
|
vpsrlq $46, %ymm12, %ymm12
|
||||||
|
vpor %ymm13, %ymm8, %ymm8
|
||||||
|
vpor %ymm14, %ymm9, %ymm9
|
||||||
|
vpor %ymm15, %ymm10, %ymm10
|
||||||
|
#vpor %ymm7, %ymm11, %ymm11
|
||||||
|
vpshufb %ymm0, %ymm11, %ymm11
|
||||||
|
vpor %ymm6, %ymm12, %ymm12
|
||||||
|
vpandn %ymm10, %ymm9, %ymm13
|
||||||
|
vpandn %ymm11, %ymm10, %ymm14
|
||||||
|
vpandn %ymm12, %ymm11, %ymm15
|
||||||
|
vpandn %ymm8, %ymm12, %ymm7
|
||||||
|
vpandn %ymm9, %ymm8, %ymm6
|
||||||
|
vpxor %ymm8, %ymm13, %ymm13
|
||||||
|
vpxor %ymm9, %ymm14, %ymm14
|
||||||
|
vpxor %ymm10, %ymm15, %ymm15
|
||||||
|
vpxor %ymm11, %ymm7, %ymm7
|
||||||
|
vpxor %ymm12, %ymm6, %ymm6
|
||||||
|
vmovdqa %ymm13, 640(%rdi)
|
||||||
|
vmovdqa %ymm14, 32(%rdi)
|
||||||
|
vmovdqa %ymm15, 224(%rdi)
|
||||||
|
vmovdqa %ymm7, 416(%rdi)
|
||||||
|
vmovdqa %ymm6, 608(%rdi)
|
||||||
|
vpxor 128(%rdi), %ymm1, %ymm8
|
||||||
|
vpxor 160(%rdi), %ymm5, %ymm9
|
||||||
|
vpxor 352(%rdi), %ymm4, %ymm10
|
||||||
|
vpxor 544(%rdi), %ymm3, %ymm11
|
||||||
|
vpxor 736(%rdi), %ymm2, %ymm12
|
||||||
|
vpsllq $27, %ymm8, %ymm13
|
||||||
|
vpsllq $36, %ymm9, %ymm14
|
||||||
|
vpsllq $10, %ymm10, %ymm15
|
||||||
|
vpsllq $15, %ymm11, %ymm7
|
||||||
|
#vpsllq $56, %ymm12, %ymm6
|
||||||
|
vpsrlq $37, %ymm8, %ymm8
|
||||||
|
vpsrlq $28, %ymm9, %ymm9
|
||||||
|
vpsrlq $54, %ymm10, %ymm10
|
||||||
|
vpsrlq $49, %ymm11, %ymm11
|
||||||
|
#vpsrlq $8, %ymm12, %ymm12
|
||||||
|
vpor %ymm13, %ymm8, %ymm8
|
||||||
|
vpor %ymm14, %ymm9, %ymm9
|
||||||
|
vpor %ymm15, %ymm10, %ymm10
|
||||||
|
vpor %ymm7, %ymm11, %ymm11
|
||||||
|
#vpor %ymm6, %ymm12, %ymm12
|
||||||
|
vpshufb rho56(%rip), %ymm12, %ymm12
|
||||||
|
vpandn %ymm10, %ymm9, %ymm13
|
||||||
|
vpandn %ymm11, %ymm10, %ymm14
|
||||||
|
vpandn %ymm12, %ymm11, %ymm15
|
||||||
|
vpandn %ymm8, %ymm12, %ymm7
|
||||||
|
vpandn %ymm9, %ymm8, %ymm6
|
||||||
|
vpxor %ymm8, %ymm13, %ymm13
|
||||||
|
vpxor %ymm9, %ymm14, %ymm14
|
||||||
|
vpxor %ymm10, %ymm15, %ymm15
|
||||||
|
vpxor %ymm11, %ymm7, %ymm7
|
||||||
|
vpxor %ymm12, %ymm6, %ymm6
|
||||||
|
vmovdqa %ymm13, 160(%rdi)
|
||||||
|
vmovdqa %ymm14, 352(%rdi)
|
||||||
|
vmovdqa %ymm15, 544(%rdi)
|
||||||
|
vmovdqa %ymm7, 736(%rdi)
|
||||||
|
vmovdqa %ymm6, 128(%rdi)
|
||||||
|
vpxor 64(%rdi), %ymm3, %ymm8
|
||||||
|
vpxor 256(%rdi), %ymm2, %ymm9
|
||||||
|
vpxor 448(%rdi), %ymm1, %ymm10
|
||||||
|
vpxor 480(%rdi), %ymm5, %ymm11
|
||||||
|
vpxor 672(%rdi), %ymm4, %ymm12
|
||||||
|
vpsllq $62, %ymm8, %ymm13
|
||||||
|
vpsllq $55, %ymm9, %ymm14
|
||||||
|
vpsllq $39, %ymm10, %ymm15
|
||||||
|
vpsllq $41, %ymm11, %ymm7
|
||||||
|
vpsllq $2, %ymm12, %ymm6
|
||||||
|
vpsrlq $2, %ymm8, %ymm8
|
||||||
|
vpsrlq $9, %ymm9, %ymm9
|
||||||
|
vpsrlq $25, %ymm10, %ymm10
|
||||||
|
vpsrlq $23, %ymm11, %ymm11
|
||||||
|
vpsrlq $62, %ymm12, %ymm12
|
||||||
|
vpor %ymm13, %ymm8, %ymm8
|
||||||
|
vpor %ymm14, %ymm9, %ymm9
|
||||||
|
vpor %ymm15, %ymm10, %ymm10
|
||||||
|
vpor %ymm7, %ymm11, %ymm11
|
||||||
|
vpor %ymm6, %ymm12, %ymm12
|
||||||
|
vpandn %ymm10, %ymm9, %ymm13
|
||||||
|
vpandn %ymm11, %ymm10, %ymm14
|
||||||
|
vpandn %ymm12, %ymm11, %ymm15
|
||||||
|
vpandn %ymm8, %ymm12, %ymm7
|
||||||
|
vpandn %ymm9, %ymm8, %ymm6
|
||||||
|
vpxor %ymm8, %ymm13, %ymm13
|
||||||
|
vpxor %ymm9, %ymm14, %ymm14
|
||||||
|
vpxor %ymm10, %ymm15, %ymm15
|
||||||
|
vpxor %ymm11, %ymm7, %ymm7
|
||||||
|
vpxor %ymm12, %ymm6, %ymm6
|
||||||
|
vmovdqa %ymm13, 480(%rdi)
|
||||||
|
vmovdqa %ymm14, 672(%rdi)
|
||||||
|
vmovdqa %ymm15, 64(%rdi)
|
||||||
|
vmovdqa %ymm7, 256(%rdi)
|
||||||
|
vmovdqa %ymm6, 448(%rdi)
|
||||||
|
vmovdqa 0(%rdi), %ymm8
|
||||||
|
vmovdqa 32(%rdi), %ymm9
|
||||||
|
vmovdqa 64(%rdi), %ymm10
|
||||||
|
vmovdqa 96(%rdi), %ymm11
|
||||||
|
vmovdqa 128(%rdi), %ymm12
|
||||||
|
vpxor 160(%rdi), %ymm8, %ymm8
|
||||||
|
vpxor 192(%rdi), %ymm9, %ymm9
|
||||||
|
vpxor 224(%rdi), %ymm10, %ymm10
|
||||||
|
vpxor 256(%rdi), %ymm11, %ymm11
|
||||||
|
vpxor 288(%rdi), %ymm12, %ymm12
|
||||||
|
vpxor 320(%rdi), %ymm8, %ymm8
|
||||||
|
vpxor 352(%rdi), %ymm9, %ymm9
|
||||||
|
vpxor 384(%rdi), %ymm10, %ymm10
|
||||||
|
vpxor 416(%rdi), %ymm11, %ymm11
|
||||||
|
vpxor 448(%rdi), %ymm12, %ymm12
|
||||||
|
vpxor 480(%rdi), %ymm8, %ymm8
|
||||||
|
vpxor 512(%rdi), %ymm9, %ymm9
|
||||||
|
vpxor 544(%rdi), %ymm10, %ymm10
|
||||||
|
vpxor 576(%rdi), %ymm11, %ymm11
|
||||||
|
vpxor 608(%rdi), %ymm12, %ymm12
|
||||||
|
vpxor 640(%rdi), %ymm8, %ymm8
|
||||||
|
vpxor 672(%rdi), %ymm9, %ymm9
|
||||||
|
vpxor 704(%rdi), %ymm10, %ymm10
|
||||||
|
vpxor 736(%rdi), %ymm11, %ymm11
|
||||||
|
vpxor 768(%rdi), %ymm12, %ymm12
|
||||||
|
vpsllq $1, %ymm9, %ymm13
|
||||||
|
vpsllq $1, %ymm10, %ymm14
|
||||||
|
vpsllq $1, %ymm11, %ymm15
|
||||||
|
vpsllq $1, %ymm12, %ymm7
|
||||||
|
vpsllq $1, %ymm8, %ymm6
|
||||||
|
vpsrlq $63, %ymm9, %ymm5
|
||||||
|
vpsrlq $63, %ymm10, %ymm4
|
||||||
|
vpsrlq $63, %ymm11, %ymm3
|
||||||
|
vpsrlq $63, %ymm12, %ymm2
|
||||||
|
vpsrlq $63, %ymm8, %ymm1
|
||||||
|
vpor %ymm13, %ymm5, %ymm5
|
||||||
|
vpor %ymm14, %ymm4, %ymm4
|
||||||
|
vpor %ymm15, %ymm3, %ymm3
|
||||||
|
vpor %ymm7, %ymm2, %ymm2
|
||||||
|
vpor %ymm6, %ymm1, %ymm1
|
||||||
|
vpxor %ymm5, %ymm12, %ymm5
|
||||||
|
vpxor %ymm4, %ymm8, %ymm4
|
||||||
|
vpxor %ymm3, %ymm9, %ymm3
|
||||||
|
vpxor %ymm2, %ymm10, %ymm2
|
||||||
|
vpxor %ymm1, %ymm11, %ymm1
|
||||||
|
vpxor 0(%rdi), %ymm5, %ymm8
|
||||||
|
vpxor 512(%rdi), %ymm4, %ymm9
|
||||||
|
vpxor 224(%rdi), %ymm3, %ymm10
|
||||||
|
vpxor 736(%rdi), %ymm2, %ymm11
|
||||||
|
vpxor 448(%rdi), %ymm1, %ymm12
|
||||||
|
vpsllq $44, %ymm9, %ymm14
|
||||||
|
vpsllq $43, %ymm10, %ymm15
|
||||||
|
vpsllq $21, %ymm11, %ymm7
|
||||||
|
vpsllq $14, %ymm12, %ymm6
|
||||||
|
vpsrlq $20, %ymm9, %ymm9
|
||||||
|
vpsrlq $21, %ymm10, %ymm10
|
||||||
|
vpsrlq $43, %ymm11, %ymm11
|
||||||
|
vpsrlq $50, %ymm12, %ymm12
|
||||||
|
vpor %ymm14, %ymm9, %ymm9
|
||||||
|
vpor %ymm15, %ymm10, %ymm10
|
||||||
|
vpor %ymm7, %ymm11, %ymm11
|
||||||
|
vpor %ymm6, %ymm12, %ymm12
|
||||||
|
vpandn %ymm10, %ymm9, %ymm13
|
||||||
|
vpandn %ymm11, %ymm10, %ymm14
|
||||||
|
vpandn %ymm12, %ymm11, %ymm15
|
||||||
|
vpandn %ymm8, %ymm12, %ymm7
|
||||||
|
vpandn %ymm9, %ymm8, %ymm6
|
||||||
|
vpxor %ymm8, %ymm13, %ymm13
|
||||||
|
vpxor %ymm9, %ymm14, %ymm14
|
||||||
|
vpxor %ymm10, %ymm15, %ymm15
|
||||||
|
vpxor %ymm11, %ymm7, %ymm7
|
||||||
|
vpxor %ymm12, %ymm6, %ymm6
|
||||||
|
vpbroadcastq 8(%rsi), %ymm8
|
||||||
|
vpxor %ymm8, %ymm13, %ymm13
|
||||||
|
vmovdqa %ymm13, 0(%rdi)
|
||||||
|
vmovdqa %ymm14, 512(%rdi)
|
||||||
|
vmovdqa %ymm15, 224(%rdi)
|
||||||
|
vmovdqa %ymm7, 736(%rdi)
|
||||||
|
vmovdqa %ymm6, 448(%rdi)
|
||||||
|
vpxor 576(%rdi), %ymm2, %ymm8
|
||||||
|
vpxor 288(%rdi), %ymm1, %ymm9
|
||||||
|
vpxor 640(%rdi), %ymm5, %ymm10
|
||||||
|
vpxor 352(%rdi), %ymm4, %ymm11
|
||||||
|
vpxor 64(%rdi), %ymm3, %ymm12
|
||||||
|
vpsllq $28, %ymm8, %ymm13
|
||||||
|
vpsllq $20, %ymm9, %ymm14
|
||||||
|
vpsllq $3, %ymm10, %ymm15
|
||||||
|
vpsllq $45, %ymm11, %ymm7
|
||||||
|
vpsllq $61, %ymm12, %ymm6
|
||||||
|
vpsrlq $36, %ymm8, %ymm8
|
||||||
|
vpsrlq $44, %ymm9, %ymm9
|
||||||
|
vpsrlq $61, %ymm10, %ymm10
|
||||||
|
vpsrlq $19, %ymm11, %ymm11
|
||||||
|
vpsrlq $3, %ymm12, %ymm12
|
||||||
|
vpor %ymm13, %ymm8, %ymm8
|
||||||
|
vpor %ymm14, %ymm9, %ymm9
|
||||||
|
vpor %ymm15, %ymm10, %ymm10
|
||||||
|
vpor %ymm7, %ymm11, %ymm11
|
||||||
|
vpor %ymm6, %ymm12, %ymm12
|
||||||
|
vpandn %ymm10, %ymm9, %ymm13
|
||||||
|
vpandn %ymm11, %ymm10, %ymm14
|
||||||
|
vpandn %ymm12, %ymm11, %ymm15
|
||||||
|
vpandn %ymm8, %ymm12, %ymm7
|
||||||
|
vpandn %ymm9, %ymm8, %ymm6
|
||||||
|
vpxor %ymm8, %ymm13, %ymm13
|
||||||
|
vpxor %ymm9, %ymm14, %ymm14
|
||||||
|
vpxor %ymm10, %ymm15, %ymm15
|
||||||
|
vpxor %ymm11, %ymm7, %ymm7
|
||||||
|
vpxor %ymm12, %ymm6, %ymm6
|
||||||
|
vmovdqa %ymm13, 640(%rdi)
|
||||||
|
vmovdqa %ymm14, 352(%rdi)
|
||||||
|
vmovdqa %ymm15, 64(%rdi)
|
||||||
|
vmovdqa %ymm7, 576(%rdi)
|
||||||
|
vmovdqa %ymm6, 288(%rdi)
|
||||||
|
vpxor 192(%rdi), %ymm4, %ymm8
|
||||||
|
vpxor 704(%rdi), %ymm3, %ymm9
|
||||||
|
vpxor 416(%rdi), %ymm2, %ymm10
|
||||||
|
vpxor 128(%rdi), %ymm1, %ymm11
|
||||||
|
vpxor 480(%rdi), %ymm5, %ymm12
|
||||||
|
vpsllq $1, %ymm8, %ymm13
|
||||||
|
vpsllq $6, %ymm9, %ymm14
|
||||||
|
vpsllq $25, %ymm10, %ymm15
|
||||||
|
#vpsllq $8, %ymm11, %ymm7
|
||||||
|
vpsllq $18, %ymm12, %ymm6
|
||||||
|
vpsrlq $63, %ymm8, %ymm8
|
||||||
|
vpsrlq $58, %ymm9, %ymm9
|
||||||
|
vpsrlq $39, %ymm10, %ymm10
|
||||||
|
#vpsrlq $56, %ymm11, %ymm11
|
||||||
|
vpsrlq $46, %ymm12, %ymm12
|
||||||
|
vpor %ymm13, %ymm8, %ymm8
|
||||||
|
vpor %ymm14, %ymm9, %ymm9
|
||||||
|
vpor %ymm15, %ymm10, %ymm10
|
||||||
|
#vpor %ymm7, %ymm11, %ymm11
|
||||||
|
vpshufb %ymm0, %ymm11, %ymm11
|
||||||
|
vpor %ymm6, %ymm12, %ymm12
|
||||||
|
vpandn %ymm10, %ymm9, %ymm13
|
||||||
|
vpandn %ymm11, %ymm10, %ymm14
|
||||||
|
vpandn %ymm12, %ymm11, %ymm15
|
||||||
|
vpandn %ymm8, %ymm12, %ymm7
|
||||||
|
vpandn %ymm9, %ymm8, %ymm6
|
||||||
|
vpxor %ymm8, %ymm13, %ymm13
|
||||||
|
vpxor %ymm9, %ymm14, %ymm14
|
||||||
|
vpxor %ymm10, %ymm15, %ymm15
|
||||||
|
vpxor %ymm11, %ymm7, %ymm7
|
||||||
|
vpxor %ymm12, %ymm6, %ymm6
|
||||||
|
vmovdqa %ymm13, 480(%rdi)
|
||||||
|
vmovdqa %ymm14, 192(%rdi)
|
||||||
|
vmovdqa %ymm15, 704(%rdi)
|
||||||
|
vmovdqa %ymm7, 416(%rdi)
|
||||||
|
vmovdqa %ymm6, 128(%rdi)
|
||||||
|
vpxor 768(%rdi), %ymm1, %ymm8
|
||||||
|
vpxor 320(%rdi), %ymm5, %ymm9
|
||||||
|
vpxor 32(%rdi), %ymm4, %ymm10
|
||||||
|
vpxor 544(%rdi), %ymm3, %ymm11
|
||||||
|
vpxor 256(%rdi), %ymm2, %ymm12
|
||||||
|
vpsllq $27, %ymm8, %ymm13
|
||||||
|
vpsllq $36, %ymm9, %ymm14
|
||||||
|
vpsllq $10, %ymm10, %ymm15
|
||||||
|
vpsllq $15, %ymm11, %ymm7
|
||||||
|
#vpsllq $56, %ymm12, %ymm6
|
||||||
|
vpsrlq $37, %ymm8, %ymm8
|
||||||
|
vpsrlq $28, %ymm9, %ymm9
|
||||||
|
vpsrlq $54, %ymm10, %ymm10
|
||||||
|
vpsrlq $49, %ymm11, %ymm11
|
||||||
|
#vpsrlq $8, %ymm12, %ymm12
|
||||||
|
vpor %ymm13, %ymm8, %ymm8
|
||||||
|
vpor %ymm14, %ymm9, %ymm9
|
||||||
|
vpor %ymm15, %ymm10, %ymm10
|
||||||
|
vpor %ymm7, %ymm11, %ymm11
|
||||||
|
#vpor %ymm6, %ymm12, %ymm12
|
||||||
|
vpshufb rho56(%rip), %ymm12, %ymm12
|
||||||
|
vpandn %ymm10, %ymm9, %ymm13
|
||||||
|
vpandn %ymm11, %ymm10, %ymm14
|
||||||
|
vpandn %ymm12, %ymm11, %ymm15
|
||||||
|
vpandn %ymm8, %ymm12, %ymm7
|
||||||
|
vpandn %ymm9, %ymm8, %ymm6
|
||||||
|
vpxor %ymm8, %ymm13, %ymm13
|
||||||
|
vpxor %ymm9, %ymm14, %ymm14
|
||||||
|
vpxor %ymm10, %ymm15, %ymm15
|
||||||
|
vpxor %ymm11, %ymm7, %ymm7
|
||||||
|
vpxor %ymm12, %ymm6, %ymm6
|
||||||
|
vmovdqa %ymm13, 320(%rdi)
|
||||||
|
vmovdqa %ymm14, 32(%rdi)
|
||||||
|
vmovdqa %ymm15, 544(%rdi)
|
||||||
|
vmovdqa %ymm7, 256(%rdi)
|
||||||
|
vmovdqa %ymm6, 768(%rdi)
|
||||||
|
vpxor 384(%rdi), %ymm3, %ymm8
|
||||||
|
vpxor 96(%rdi), %ymm2, %ymm9
|
||||||
|
vpxor 608(%rdi), %ymm1, %ymm10
|
||||||
|
vpxor 160(%rdi), %ymm5, %ymm11
|
||||||
|
vpxor 672(%rdi), %ymm4, %ymm12
|
||||||
|
vpsllq $62, %ymm8, %ymm13
|
||||||
|
vpsllq $55, %ymm9, %ymm14
|
||||||
|
vpsllq $39, %ymm10, %ymm15
|
||||||
|
vpsllq $41, %ymm11, %ymm7
|
||||||
|
vpsllq $2, %ymm12, %ymm6
|
||||||
|
vpsrlq $2, %ymm8, %ymm8
|
||||||
|
vpsrlq $9, %ymm9, %ymm9
|
||||||
|
vpsrlq $25, %ymm10, %ymm10
|
||||||
|
vpsrlq $23, %ymm11, %ymm11
|
||||||
|
vpsrlq $62, %ymm12, %ymm12
|
||||||
|
vpor %ymm13, %ymm8, %ymm8
|
||||||
|
vpor %ymm14, %ymm9, %ymm9
|
||||||
|
vpor %ymm15, %ymm10, %ymm10
|
||||||
|
vpor %ymm7, %ymm11, %ymm11
|
||||||
|
vpor %ymm6, %ymm12, %ymm12
|
||||||
|
vpandn %ymm10, %ymm9, %ymm13
|
||||||
|
vpandn %ymm11, %ymm10, %ymm14
|
||||||
|
vpandn %ymm12, %ymm11, %ymm15
|
||||||
|
vpandn %ymm8, %ymm12, %ymm7
|
||||||
|
vpandn %ymm9, %ymm8, %ymm6
|
||||||
|
vpxor %ymm8, %ymm13, %ymm13
|
||||||
|
vpxor %ymm9, %ymm14, %ymm14
|
||||||
|
vpxor %ymm10, %ymm15, %ymm15
|
||||||
|
vpxor %ymm11, %ymm7, %ymm7
|
||||||
|
vpxor %ymm12, %ymm6, %ymm6
|
||||||
|
vmovdqa %ymm13, 160(%rdi)
|
||||||
|
vmovdqa %ymm14, 672(%rdi)
|
||||||
|
vmovdqa %ymm15, 384(%rdi)
|
||||||
|
vmovdqa %ymm7, 96(%rdi)
|
||||||
|
vmovdqa %ymm6, 608(%rdi)
|
||||||
|
vmovdqa 0(%rdi), %ymm8
|
||||||
|
vmovdqa 32(%rdi), %ymm9
|
||||||
|
vmovdqa 64(%rdi), %ymm10
|
||||||
|
vmovdqa 96(%rdi), %ymm11
|
||||||
|
vmovdqa 128(%rdi), %ymm12
|
||||||
|
vpxor 160(%rdi), %ymm8, %ymm8
|
||||||
|
vpxor 192(%rdi), %ymm9, %ymm9
|
||||||
|
vpxor 224(%rdi), %ymm10, %ymm10
|
||||||
|
vpxor 256(%rdi), %ymm11, %ymm11
|
||||||
|
vpxor 288(%rdi), %ymm12, %ymm12
|
||||||
|
vpxor 320(%rdi), %ymm8, %ymm8
|
||||||
|
vpxor 352(%rdi), %ymm9, %ymm9
|
||||||
|
vpxor 384(%rdi), %ymm10, %ymm10
|
||||||
|
vpxor 416(%rdi), %ymm11, %ymm11
|
||||||
|
vpxor 448(%rdi), %ymm12, %ymm12
|
||||||
|
vpxor 480(%rdi), %ymm8, %ymm8
|
||||||
|
vpxor 512(%rdi), %ymm9, %ymm9
|
||||||
|
vpxor 544(%rdi), %ymm10, %ymm10
|
||||||
|
vpxor 576(%rdi), %ymm11, %ymm11
|
||||||
|
vpxor 608(%rdi), %ymm12, %ymm12
|
||||||
|
vpxor 640(%rdi), %ymm8, %ymm8
|
||||||
|
vpxor 672(%rdi), %ymm9, %ymm9
|
||||||
|
vpxor 704(%rdi), %ymm10, %ymm10
|
||||||
|
vpxor 736(%rdi), %ymm11, %ymm11
|
||||||
|
vpxor 768(%rdi), %ymm12, %ymm12
|
||||||
|
vpsllq $1, %ymm9, %ymm13
|
||||||
|
vpsllq $1, %ymm10, %ymm14
|
||||||
|
vpsllq $1, %ymm11, %ymm15
|
||||||
|
vpsllq $1, %ymm12, %ymm7
|
||||||
|
vpsllq $1, %ymm8, %ymm6
|
||||||
|
vpsrlq $63, %ymm9, %ymm5
|
||||||
|
vpsrlq $63, %ymm10, %ymm4
|
||||||
|
vpsrlq $63, %ymm11, %ymm3
|
||||||
|
vpsrlq $63, %ymm12, %ymm2
|
||||||
|
vpsrlq $63, %ymm8, %ymm1
|
||||||
|
vpor %ymm13, %ymm5, %ymm5
|
||||||
|
vpor %ymm14, %ymm4, %ymm4
|
||||||
|
vpor %ymm15, %ymm3, %ymm3
|
||||||
|
vpor %ymm7, %ymm2, %ymm2
|
||||||
|
vpor %ymm6, %ymm1, %ymm1
|
||||||
|
vpxor %ymm5, %ymm12, %ymm5
|
||||||
|
vpxor %ymm4, %ymm8, %ymm4
|
||||||
|
vpxor %ymm3, %ymm9, %ymm3
|
||||||
|
vpxor %ymm2, %ymm10, %ymm2
|
||||||
|
vpxor %ymm1, %ymm11, %ymm1
|
||||||
|
vpxor 0(%rdi), %ymm5, %ymm8
|
||||||
|
vpxor 352(%rdi), %ymm4, %ymm9
|
||||||
|
vpxor 704(%rdi), %ymm3, %ymm10
|
||||||
|
vpxor 256(%rdi), %ymm2, %ymm11
|
||||||
|
vpxor 608(%rdi), %ymm1, %ymm12
|
||||||
|
vpsllq $44, %ymm9, %ymm14
|
||||||
|
vpsllq $43, %ymm10, %ymm15
|
||||||
|
vpsllq $21, %ymm11, %ymm7
|
||||||
|
vpsllq $14, %ymm12, %ymm6
|
||||||
|
vpsrlq $20, %ymm9, %ymm9
|
||||||
|
vpsrlq $21, %ymm10, %ymm10
|
||||||
|
vpsrlq $43, %ymm11, %ymm11
|
||||||
|
vpsrlq $50, %ymm12, %ymm12
|
||||||
|
vpor %ymm14, %ymm9, %ymm9
|
||||||
|
vpor %ymm15, %ymm10, %ymm10
|
||||||
|
vpor %ymm7, %ymm11, %ymm11
|
||||||
|
vpor %ymm6, %ymm12, %ymm12
|
||||||
|
vpandn %ymm10, %ymm9, %ymm13
|
||||||
|
vpandn %ymm11, %ymm10, %ymm14
|
||||||
|
vpandn %ymm12, %ymm11, %ymm15
|
||||||
|
vpandn %ymm8, %ymm12, %ymm7
|
||||||
|
vpandn %ymm9, %ymm8, %ymm6
|
||||||
|
vpxor %ymm8, %ymm13, %ymm13
|
||||||
|
vpxor %ymm9, %ymm14, %ymm14
|
||||||
|
vpxor %ymm10, %ymm15, %ymm15
|
||||||
|
vpxor %ymm11, %ymm7, %ymm7
|
||||||
|
vpxor %ymm12, %ymm6, %ymm6
|
||||||
|
vpbroadcastq 16(%rsi), %ymm8
|
||||||
|
vpxor %ymm8, %ymm13, %ymm13
|
||||||
|
vmovdqa %ymm13, 0(%rdi)
|
||||||
|
vmovdqa %ymm14, 352(%rdi)
|
||||||
|
vmovdqa %ymm15, 704(%rdi)
|
||||||
|
vmovdqa %ymm7, 256(%rdi)
|
||||||
|
vmovdqa %ymm6, 608(%rdi)
|
||||||
|
vpxor 736(%rdi), %ymm2, %ymm8
|
||||||
|
vpxor 288(%rdi), %ymm1, %ymm9
|
||||||
|
vpxor 480(%rdi), %ymm5, %ymm10
|
||||||
|
vpxor 32(%rdi), %ymm4, %ymm11
|
||||||
|
vpxor 384(%rdi), %ymm3, %ymm12
|
||||||
|
vpsllq $28, %ymm8, %ymm13
|
||||||
|
vpsllq $20, %ymm9, %ymm14
|
||||||
|
vpsllq $3, %ymm10, %ymm15
|
||||||
|
vpsllq $45, %ymm11, %ymm7
|
||||||
|
vpsllq $61, %ymm12, %ymm6
|
||||||
|
vpsrlq $36, %ymm8, %ymm8
|
||||||
|
vpsrlq $44, %ymm9, %ymm9
|
||||||
|
vpsrlq $61, %ymm10, %ymm10
|
||||||
|
vpsrlq $19, %ymm11, %ymm11
|
||||||
|
vpsrlq $3, %ymm12, %ymm12
|
||||||
|
vpor %ymm13, %ymm8, %ymm8
|
||||||
|
vpor %ymm14, %ymm9, %ymm9
|
||||||
|
vpor %ymm15, %ymm10, %ymm10
|
||||||
|
vpor %ymm7, %ymm11, %ymm11
|
||||||
|
vpor %ymm6, %ymm12, %ymm12
|
||||||
|
vpandn %ymm10, %ymm9, %ymm13
|
||||||
|
vpandn %ymm11, %ymm10, %ymm14
|
||||||
|
vpandn %ymm12, %ymm11, %ymm15
|
||||||
|
vpandn %ymm8, %ymm12, %ymm7
|
||||||
|
vpandn %ymm9, %ymm8, %ymm6
|
||||||
|
vpxor %ymm8, %ymm13, %ymm13
|
||||||
|
vpxor %ymm9, %ymm14, %ymm14
|
||||||
|
vpxor %ymm10, %ymm15, %ymm15
|
||||||
|
vpxor %ymm11, %ymm7, %ymm7
|
||||||
|
vpxor %ymm12, %ymm6, %ymm6
|
||||||
|
vmovdqa %ymm13, 480(%rdi)
|
||||||
|
vmovdqa %ymm14, 32(%rdi)
|
||||||
|
vmovdqa %ymm15, 384(%rdi)
|
||||||
|
vmovdqa %ymm7, 736(%rdi)
|
||||||
|
vmovdqa %ymm6, 288(%rdi)
|
||||||
|
vpxor 512(%rdi), %ymm4, %ymm8
|
||||||
|
vpxor 64(%rdi), %ymm3, %ymm9
|
||||||
|
vpxor 416(%rdi), %ymm2, %ymm10
|
||||||
|
vpxor 768(%rdi), %ymm1, %ymm11
|
||||||
|
vpxor 160(%rdi), %ymm5, %ymm12
|
||||||
|
vpsllq $1, %ymm8, %ymm13
|
||||||
|
vpsllq $6, %ymm9, %ymm14
|
||||||
|
vpsllq $25, %ymm10, %ymm15
|
||||||
|
#vpsllq $8, %ymm11, %ymm7
|
||||||
|
vpsllq $18, %ymm12, %ymm6
|
||||||
|
vpsrlq $63, %ymm8, %ymm8
|
||||||
|
vpsrlq $58, %ymm9, %ymm9
|
||||||
|
vpsrlq $39, %ymm10, %ymm10
|
||||||
|
#vpsrlq $56, %ymm11, %ymm11
|
||||||
|
vpsrlq $46, %ymm12, %ymm12
|
||||||
|
vpor %ymm13, %ymm8, %ymm8
|
||||||
|
vpor %ymm14, %ymm9, %ymm9
|
||||||
|
vpor %ymm15, %ymm10, %ymm10
|
||||||
|
#vpor %ymm7, %ymm11, %ymm11
|
||||||
|
vpshufb %ymm0, %ymm11, %ymm11
|
||||||
|
vpor %ymm6, %ymm12, %ymm12
|
||||||
|
vpandn %ymm10, %ymm9, %ymm13
|
||||||
|
vpandn %ymm11, %ymm10, %ymm14
|
||||||
|
vpandn %ymm12, %ymm11, %ymm15
|
||||||
|
vpandn %ymm8, %ymm12, %ymm7
|
||||||
|
vpandn %ymm9, %ymm8, %ymm6
|
||||||
|
vpxor %ymm8, %ymm13, %ymm13
|
||||||
|
vpxor %ymm9, %ymm14, %ymm14
|
||||||
|
vpxor %ymm10, %ymm15, %ymm15
|
||||||
|
vpxor %ymm11, %ymm7, %ymm7
|
||||||
|
vpxor %ymm12, %ymm6, %ymm6
|
||||||
|
vmovdqa %ymm13, 160(%rdi)
|
||||||
|
vmovdqa %ymm14, 512(%rdi)
|
||||||
|
vmovdqa %ymm15, 64(%rdi)
|
||||||
|
vmovdqa %ymm7, 416(%rdi)
|
||||||
|
vmovdqa %ymm6, 768(%rdi)
|
||||||
|
vpxor 448(%rdi), %ymm1, %ymm8
|
||||||
|
vpxor 640(%rdi), %ymm5, %ymm9
|
||||||
|
vpxor 192(%rdi), %ymm4, %ymm10
|
||||||
|
vpxor 544(%rdi), %ymm3, %ymm11
|
||||||
|
vpxor 96(%rdi), %ymm2, %ymm12
|
||||||
|
vpsllq $27, %ymm8, %ymm13
|
||||||
|
vpsllq $36, %ymm9, %ymm14
|
||||||
|
vpsllq $10, %ymm10, %ymm15
|
||||||
|
vpsllq $15, %ymm11, %ymm7
|
||||||
|
#vpsllq $56, %ymm12, %ymm6
|
||||||
|
vpsrlq $37, %ymm8, %ymm8
|
||||||
|
vpsrlq $28, %ymm9, %ymm9
|
||||||
|
vpsrlq $54, %ymm10, %ymm10
|
||||||
|
vpsrlq $49, %ymm11, %ymm11
|
||||||
|
#vpsrlq $8, %ymm12, %ymm12
|
||||||
|
vpor %ymm13, %ymm8, %ymm8
|
||||||
|
vpor %ymm14, %ymm9, %ymm9
|
||||||
|
vpor %ymm15, %ymm10, %ymm10
|
||||||
|
vpor %ymm7, %ymm11, %ymm11
|
||||||
|
#vpor %ymm6, %ymm12, %ymm12
|
||||||
|
vpshufb rho56(%rip), %ymm12, %ymm12
|
||||||
|
vpandn %ymm10, %ymm9, %ymm13
|
||||||
|
vpandn %ymm11, %ymm10, %ymm14
|
||||||
|
vpandn %ymm12, %ymm11, %ymm15
|
||||||
|
vpandn %ymm8, %ymm12, %ymm7
|
||||||
|
vpandn %ymm9, %ymm8, %ymm6
|
||||||
|
vpxor %ymm8, %ymm13, %ymm13
|
||||||
|
vpxor %ymm9, %ymm14, %ymm14
|
||||||
|
vpxor %ymm10, %ymm15, %ymm15
|
||||||
|
vpxor %ymm11, %ymm7, %ymm7
|
||||||
|
vpxor %ymm12, %ymm6, %ymm6
|
||||||
|
vmovdqa %ymm13, 640(%rdi)
|
||||||
|
vmovdqa %ymm14, 192(%rdi)
|
||||||
|
vmovdqa %ymm15, 544(%rdi)
|
||||||
|
vmovdqa %ymm7, 96(%rdi)
|
||||||
|
vmovdqa %ymm6, 448(%rdi)
|
||||||
|
vpxor 224(%rdi), %ymm3, %ymm8
|
||||||
|
vpxor 576(%rdi), %ymm2, %ymm9
|
||||||
|
vpxor 128(%rdi), %ymm1, %ymm10
|
||||||
|
vpxor 320(%rdi), %ymm5, %ymm11
|
||||||
|
vpxor 672(%rdi), %ymm4, %ymm12
|
||||||
|
vpsllq $62, %ymm8, %ymm13
|
||||||
|
vpsllq $55, %ymm9, %ymm14
|
||||||
|
vpsllq $39, %ymm10, %ymm15
|
||||||
|
vpsllq $41, %ymm11, %ymm7
|
||||||
|
vpsllq $2, %ymm12, %ymm6
|
||||||
|
vpsrlq $2, %ymm8, %ymm8
|
||||||
|
vpsrlq $9, %ymm9, %ymm9
|
||||||
|
vpsrlq $25, %ymm10, %ymm10
|
||||||
|
vpsrlq $23, %ymm11, %ymm11
|
||||||
|
vpsrlq $62, %ymm12, %ymm12
|
||||||
|
vpor %ymm13, %ymm8, %ymm8
|
||||||
|
vpor %ymm14, %ymm9, %ymm9
|
||||||
|
vpor %ymm15, %ymm10, %ymm10
|
||||||
|
vpor %ymm7, %ymm11, %ymm11
|
||||||
|
vpor %ymm6, %ymm12, %ymm12
|
||||||
|
vpandn %ymm10, %ymm9, %ymm13
|
||||||
|
vpandn %ymm11, %ymm10, %ymm14
|
||||||
|
vpandn %ymm12, %ymm11, %ymm15
|
||||||
|
vpandn %ymm8, %ymm12, %ymm7
|
||||||
|
vpandn %ymm9, %ymm8, %ymm6
|
||||||
|
vpxor %ymm8, %ymm13, %ymm13
|
||||||
|
vpxor %ymm9, %ymm14, %ymm14
|
||||||
|
vpxor %ymm10, %ymm15, %ymm15
|
||||||
|
vpxor %ymm11, %ymm7, %ymm7
|
||||||
|
vpxor %ymm12, %ymm6, %ymm6
|
||||||
|
vmovdqa %ymm13, 320(%rdi)
|
||||||
|
vmovdqa %ymm14, 672(%rdi)
|
||||||
|
vmovdqa %ymm15, 224(%rdi)
|
||||||
|
vmovdqa %ymm7, 576(%rdi)
|
||||||
|
vmovdqa %ymm6, 128(%rdi)
|
||||||
|
vmovdqa 0(%rdi), %ymm8
|
||||||
|
vmovdqa 32(%rdi), %ymm9
|
||||||
|
vmovdqa 64(%rdi), %ymm10
|
||||||
|
vmovdqa 96(%rdi), %ymm11
|
||||||
|
vmovdqa 128(%rdi), %ymm12
|
||||||
|
vpxor 160(%rdi), %ymm8, %ymm8
|
||||||
|
vpxor 192(%rdi), %ymm9, %ymm9
|
||||||
|
vpxor 224(%rdi), %ymm10, %ymm10
|
||||||
|
vpxor 256(%rdi), %ymm11, %ymm11
|
||||||
|
vpxor 288(%rdi), %ymm12, %ymm12
|
||||||
|
vpxor 320(%rdi), %ymm8, %ymm8
|
||||||
|
vpxor 352(%rdi), %ymm9, %ymm9
|
||||||
|
vpxor 384(%rdi), %ymm10, %ymm10
|
||||||
|
vpxor 416(%rdi), %ymm11, %ymm11
|
||||||
|
vpxor 448(%rdi), %ymm12, %ymm12
|
||||||
|
vpxor 480(%rdi), %ymm8, %ymm8
|
||||||
|
vpxor 512(%rdi), %ymm9, %ymm9
|
||||||
|
vpxor 544(%rdi), %ymm10, %ymm10
|
||||||
|
vpxor 576(%rdi), %ymm11, %ymm11
|
||||||
|
vpxor 608(%rdi), %ymm12, %ymm12
|
||||||
|
vpxor 640(%rdi), %ymm8, %ymm8
|
||||||
|
vpxor 672(%rdi), %ymm9, %ymm9
|
||||||
|
vpxor 704(%rdi), %ymm10, %ymm10
|
||||||
|
vpxor 736(%rdi), %ymm11, %ymm11
|
||||||
|
vpxor 768(%rdi), %ymm12, %ymm12
|
||||||
|
vpsllq $1, %ymm9, %ymm13
|
||||||
|
vpsllq $1, %ymm10, %ymm14
|
||||||
|
vpsllq $1, %ymm11, %ymm15
|
||||||
|
vpsllq $1, %ymm12, %ymm7
|
||||||
|
vpsllq $1, %ymm8, %ymm6
|
||||||
|
vpsrlq $63, %ymm9, %ymm5
|
||||||
|
vpsrlq $63, %ymm10, %ymm4
|
||||||
|
vpsrlq $63, %ymm11, %ymm3
|
||||||
|
vpsrlq $63, %ymm12, %ymm2
|
||||||
|
vpsrlq $63, %ymm8, %ymm1
|
||||||
|
vpor %ymm13, %ymm5, %ymm5
|
||||||
|
vpor %ymm14, %ymm4, %ymm4
|
||||||
|
vpor %ymm15, %ymm3, %ymm3
|
||||||
|
vpor %ymm7, %ymm2, %ymm2
|
||||||
|
vpor %ymm6, %ymm1, %ymm1
|
||||||
|
vpxor %ymm5, %ymm12, %ymm5
|
||||||
|
vpxor %ymm4, %ymm8, %ymm4
|
||||||
|
vpxor %ymm3, %ymm9, %ymm3
|
||||||
|
vpxor %ymm2, %ymm10, %ymm2
|
||||||
|
vpxor %ymm1, %ymm11, %ymm1
|
||||||
|
vpxor 0(%rdi), %ymm5, %ymm8
|
||||||
|
vpxor 32(%rdi), %ymm4, %ymm9
|
||||||
|
vpxor 64(%rdi), %ymm3, %ymm10
|
||||||
|
vpxor 96(%rdi), %ymm2, %ymm11
|
||||||
|
vpxor 128(%rdi), %ymm1, %ymm12
|
||||||
|
vpsllq $44, %ymm9, %ymm14
|
||||||
|
vpsllq $43, %ymm10, %ymm15
|
||||||
|
vpsllq $21, %ymm11, %ymm7
|
||||||
|
vpsllq $14, %ymm12, %ymm6
|
||||||
|
vpsrlq $20, %ymm9, %ymm9
|
||||||
|
vpsrlq $21, %ymm10, %ymm10
|
||||||
|
vpsrlq $43, %ymm11, %ymm11
|
||||||
|
vpsrlq $50, %ymm12, %ymm12
|
||||||
|
vpor %ymm14, %ymm9, %ymm9
|
||||||
|
vpor %ymm15, %ymm10, %ymm10
|
||||||
|
vpor %ymm7, %ymm11, %ymm11
|
||||||
|
vpor %ymm6, %ymm12, %ymm12
|
||||||
|
vpandn %ymm10, %ymm9, %ymm13
|
||||||
|
vpandn %ymm11, %ymm10, %ymm14
|
||||||
|
vpandn %ymm12, %ymm11, %ymm15
|
||||||
|
vpandn %ymm8, %ymm12, %ymm7
|
||||||
|
vpandn %ymm9, %ymm8, %ymm6
|
||||||
|
vpxor %ymm8, %ymm13, %ymm13
|
||||||
|
vpxor %ymm9, %ymm14, %ymm14
|
||||||
|
vpxor %ymm10, %ymm15, %ymm15
|
||||||
|
vpxor %ymm11, %ymm7, %ymm7
|
||||||
|
vpxor %ymm12, %ymm6, %ymm6
|
||||||
|
vpbroadcastq 24(%rsi), %ymm8
|
||||||
|
vpxor %ymm8, %ymm13, %ymm13
|
||||||
|
vmovdqa %ymm13, 0(%rdi)
|
||||||
|
vmovdqa %ymm14, 32(%rdi)
|
||||||
|
vmovdqa %ymm15, 64(%rdi)
|
||||||
|
vmovdqa %ymm7, 96(%rdi)
|
||||||
|
vmovdqa %ymm6, 128(%rdi)
|
||||||
|
vpxor 256(%rdi), %ymm2, %ymm8
|
||||||
|
vpxor 288(%rdi), %ymm1, %ymm9
|
||||||
|
vpxor 160(%rdi), %ymm5, %ymm10
|
||||||
|
vpxor 192(%rdi), %ymm4, %ymm11
|
||||||
|
vpxor 224(%rdi), %ymm3, %ymm12
|
||||||
|
vpsllq $28, %ymm8, %ymm13
|
||||||
|
vpsllq $20, %ymm9, %ymm14
|
||||||
|
vpsllq $3, %ymm10, %ymm15
|
||||||
|
vpsllq $45, %ymm11, %ymm7
|
||||||
|
vpsllq $61, %ymm12, %ymm6
|
||||||
|
vpsrlq $36, %ymm8, %ymm8
|
||||||
|
vpsrlq $44, %ymm9, %ymm9
|
||||||
|
vpsrlq $61, %ymm10, %ymm10
|
||||||
|
vpsrlq $19, %ymm11, %ymm11
|
||||||
|
vpsrlq $3, %ymm12, %ymm12
|
||||||
|
vpor %ymm13, %ymm8, %ymm8
|
||||||
|
vpor %ymm14, %ymm9, %ymm9
|
||||||
|
vpor %ymm15, %ymm10, %ymm10
|
||||||
|
vpor %ymm7, %ymm11, %ymm11
|
||||||
|
vpor %ymm6, %ymm12, %ymm12
|
||||||
|
vpandn %ymm10, %ymm9, %ymm13
|
||||||
|
vpandn %ymm11, %ymm10, %ymm14
|
||||||
|
vpandn %ymm12, %ymm11, %ymm15
|
||||||
|
vpandn %ymm8, %ymm12, %ymm7
|
||||||
|
vpandn %ymm9, %ymm8, %ymm6
|
||||||
|
vpxor %ymm8, %ymm13, %ymm13
|
||||||
|
vpxor %ymm9, %ymm14, %ymm14
|
||||||
|
vpxor %ymm10, %ymm15, %ymm15
|
||||||
|
vpxor %ymm11, %ymm7, %ymm7
|
||||||
|
vpxor %ymm12, %ymm6, %ymm6
|
||||||
|
vmovdqa %ymm13, 160(%rdi)
|
||||||
|
vmovdqa %ymm14, 192(%rdi)
|
||||||
|
vmovdqa %ymm15, 224(%rdi)
|
||||||
|
vmovdqa %ymm7, 256(%rdi)
|
||||||
|
vmovdqa %ymm6, 288(%rdi)
|
||||||
|
vpxor 352(%rdi), %ymm4, %ymm8
|
||||||
|
vpxor 384(%rdi), %ymm3, %ymm9
|
||||||
|
vpxor 416(%rdi), %ymm2, %ymm10
|
||||||
|
vpxor 448(%rdi), %ymm1, %ymm11
|
||||||
|
vpxor 320(%rdi), %ymm5, %ymm12
|
||||||
|
vpsllq $1, %ymm8, %ymm13
|
||||||
|
vpsllq $6, %ymm9, %ymm14
|
||||||
|
vpsllq $25, %ymm10, %ymm15
|
||||||
|
#vpsllq $8, %ymm11, %ymm7
|
||||||
|
vpsllq $18, %ymm12, %ymm6
|
||||||
|
vpsrlq $63, %ymm8, %ymm8
|
||||||
|
vpsrlq $58, %ymm9, %ymm9
|
||||||
|
vpsrlq $39, %ymm10, %ymm10
|
||||||
|
#vpsrlq $56, %ymm11, %ymm11
|
||||||
|
vpsrlq $46, %ymm12, %ymm12
|
||||||
|
vpor %ymm13, %ymm8, %ymm8
|
||||||
|
vpor %ymm14, %ymm9, %ymm9
|
||||||
|
vpor %ymm15, %ymm10, %ymm10
|
||||||
|
#vpor %ymm7, %ymm11, %ymm11
|
||||||
|
vpshufb %ymm0, %ymm11, %ymm11
|
||||||
|
vpor %ymm6, %ymm12, %ymm12
|
||||||
|
vpandn %ymm10, %ymm9, %ymm13
|
||||||
|
vpandn %ymm11, %ymm10, %ymm14
|
||||||
|
vpandn %ymm12, %ymm11, %ymm15
|
||||||
|
vpandn %ymm8, %ymm12, %ymm7
|
||||||
|
vpandn %ymm9, %ymm8, %ymm6
|
||||||
|
vpxor %ymm8, %ymm13, %ymm13
|
||||||
|
vpxor %ymm9, %ymm14, %ymm14
|
||||||
|
vpxor %ymm10, %ymm15, %ymm15
|
||||||
|
vpxor %ymm11, %ymm7, %ymm7
|
||||||
|
vpxor %ymm12, %ymm6, %ymm6
|
||||||
|
vmovdqa %ymm13, 320(%rdi)
|
||||||
|
vmovdqa %ymm14, 352(%rdi)
|
||||||
|
vmovdqa %ymm15, 384(%rdi)
|
||||||
|
vmovdqa %ymm7, 416(%rdi)
|
||||||
|
vmovdqa %ymm6, 448(%rdi)
|
||||||
|
vpxor 608(%rdi), %ymm1, %ymm8
|
||||||
|
vpxor 480(%rdi), %ymm5, %ymm9
|
||||||
|
vpxor 512(%rdi), %ymm4, %ymm10
|
||||||
|
vpxor 544(%rdi), %ymm3, %ymm11
|
||||||
|
vpxor 576(%rdi), %ymm2, %ymm12
|
||||||
|
vpsllq $27, %ymm8, %ymm13
|
||||||
|
vpsllq $36, %ymm9, %ymm14
|
||||||
|
vpsllq $10, %ymm10, %ymm15
|
||||||
|
vpsllq $15, %ymm11, %ymm7
|
||||||
|
#vpsllq $56, %ymm12, %ymm6
|
||||||
|
vpsrlq $37, %ymm8, %ymm8
|
||||||
|
vpsrlq $28, %ymm9, %ymm9
|
||||||
|
vpsrlq $54, %ymm10, %ymm10
|
||||||
|
vpsrlq $49, %ymm11, %ymm11
|
||||||
|
#vpsrlq $8, %ymm12, %ymm12
|
||||||
|
vpor %ymm13, %ymm8, %ymm8
|
||||||
|
vpor %ymm14, %ymm9, %ymm9
|
||||||
|
vpor %ymm15, %ymm10, %ymm10
|
||||||
|
vpor %ymm7, %ymm11, %ymm11
|
||||||
|
#vpor %ymm6, %ymm12, %ymm12
|
||||||
|
vpshufb rho56(%rip), %ymm12, %ymm12
|
||||||
|
vpandn %ymm10, %ymm9, %ymm13
|
||||||
|
vpandn %ymm11, %ymm10, %ymm14
|
||||||
|
vpandn %ymm12, %ymm11, %ymm15
|
||||||
|
vpandn %ymm8, %ymm12, %ymm7
|
||||||
|
vpandn %ymm9, %ymm8, %ymm6
|
||||||
|
vpxor %ymm8, %ymm13, %ymm13
|
||||||
|
vpxor %ymm9, %ymm14, %ymm14
|
||||||
|
vpxor %ymm10, %ymm15, %ymm15
|
||||||
|
vpxor %ymm11, %ymm7, %ymm7
|
||||||
|
vpxor %ymm12, %ymm6, %ymm6
|
||||||
|
vmovdqa %ymm13, 480(%rdi)
|
||||||
|
vmovdqa %ymm14, 512(%rdi)
|
||||||
|
vmovdqa %ymm15, 544(%rdi)
|
||||||
|
vmovdqa %ymm7, 576(%rdi)
|
||||||
|
vmovdqa %ymm6, 608(%rdi)
|
||||||
|
vpxor 704(%rdi), %ymm3, %ymm8
|
||||||
|
vpxor 736(%rdi), %ymm2, %ymm9
|
||||||
|
vpxor 768(%rdi), %ymm1, %ymm10
|
||||||
|
vpxor 640(%rdi), %ymm5, %ymm11
|
||||||
|
vpxor 672(%rdi), %ymm4, %ymm12
|
||||||
|
vpsllq $62, %ymm8, %ymm13
|
||||||
|
vpsllq $55, %ymm9, %ymm14
|
||||||
|
vpsllq $39, %ymm10, %ymm15
|
||||||
|
vpsllq $41, %ymm11, %ymm7
|
||||||
|
vpsllq $2, %ymm12, %ymm6
|
||||||
|
vpsrlq $2, %ymm8, %ymm8
|
||||||
|
vpsrlq $9, %ymm9, %ymm9
|
||||||
|
vpsrlq $25, %ymm10, %ymm10
|
||||||
|
vpsrlq $23, %ymm11, %ymm11
|
||||||
|
vpsrlq $62, %ymm12, %ymm12
|
||||||
|
vpor %ymm13, %ymm8, %ymm8
|
||||||
|
vpor %ymm14, %ymm9, %ymm9
|
||||||
|
vpor %ymm15, %ymm10, %ymm10
|
||||||
|
vpor %ymm7, %ymm11, %ymm11
|
||||||
|
vpor %ymm6, %ymm12, %ymm12
|
||||||
|
vpandn %ymm10, %ymm9, %ymm13
|
||||||
|
vpandn %ymm11, %ymm10, %ymm14
|
||||||
|
vpandn %ymm12, %ymm11, %ymm15
|
||||||
|
vpandn %ymm8, %ymm12, %ymm7
|
||||||
|
vpandn %ymm9, %ymm8, %ymm6
|
||||||
|
vpxor %ymm8, %ymm13, %ymm13
|
||||||
|
vpxor %ymm9, %ymm14, %ymm14
|
||||||
|
vpxor %ymm10, %ymm15, %ymm15
|
||||||
|
vpxor %ymm11, %ymm7, %ymm7
|
||||||
|
vpxor %ymm12, %ymm6, %ymm6
|
||||||
|
vmovdqa %ymm13, 640(%rdi)
|
||||||
|
vmovdqa %ymm14, 672(%rdi)
|
||||||
|
vmovdqa %ymm15, 704(%rdi)
|
||||||
|
vmovdqa %ymm7, 736(%rdi)
|
||||||
|
vmovdqa %ymm6, 768(%rdi)
|
||||||
|
addq $32, %rsi
|
||||||
|
subq $1, %rax
|
||||||
|
jnz looptop
|
||||||
|
ret
|
||||||
|
|
||||||
|
.section .note.GNU-stack,"",@progbits
|
||||||
1
src/crypto/pq/_d/avx2/fips202.c
Symbolic link
1
src/crypto/pq/_d/avx2/fips202.c
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
../ref/fips202.c
|
||||||
57
src/crypto/pq/_d/avx2/fips202.h
Normal file
57
src/crypto/pq/_d/avx2/fips202.h
Normal file
|
|
@ -0,0 +1,57 @@
|
||||||
|
#ifndef FIPS202_H
|
||||||
|
#define FIPS202_H
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define SHAKE128_RATE 168
|
||||||
|
#define SHAKE256_RATE 136
|
||||||
|
#define SHA3_256_RATE 136
|
||||||
|
#define SHA3_512_RATE 72
|
||||||
|
|
||||||
|
#define FIPS202_NAMESPACE(s) pqcrystals_dilithium_fips202_avx2_##s
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint64_t s[25];
|
||||||
|
unsigned int pos;
|
||||||
|
} keccak_state;
|
||||||
|
|
||||||
|
#define KeccakF_RoundConstants FIPS202_NAMESPACE(KeccakF_RoundConstants)
|
||||||
|
extern const uint64_t KeccakF_RoundConstants[];
|
||||||
|
|
||||||
|
#define shake128_init FIPS202_NAMESPACE(shake128_init)
|
||||||
|
void shake128_init(keccak_state *state);
|
||||||
|
#define shake128_absorb FIPS202_NAMESPACE(shake128_absorb)
|
||||||
|
void shake128_absorb(keccak_state *state, const uint8_t *in, size_t inlen);
|
||||||
|
#define shake128_finalize FIPS202_NAMESPACE(shake128_finalize)
|
||||||
|
void shake128_finalize(keccak_state *state);
|
||||||
|
#define shake128_squeeze FIPS202_NAMESPACE(shake128_squeeze)
|
||||||
|
void shake128_squeeze(uint8_t *out, size_t outlen, keccak_state *state);
|
||||||
|
#define shake128_absorb_once FIPS202_NAMESPACE(shake128_absorb_once)
|
||||||
|
void shake128_absorb_once(keccak_state *state, const uint8_t *in, size_t inlen);
|
||||||
|
#define shake128_squeezeblocks FIPS202_NAMESPACE(shake128_squeezeblocks)
|
||||||
|
void shake128_squeezeblocks(uint8_t *out, size_t nblocks, keccak_state *state);
|
||||||
|
|
||||||
|
#define shake256_init FIPS202_NAMESPACE(shake256_init)
|
||||||
|
void shake256_init(keccak_state *state);
|
||||||
|
#define shake256_absorb FIPS202_NAMESPACE(shake256_absorb)
|
||||||
|
void shake256_absorb(keccak_state *state, const uint8_t *in, size_t inlen);
|
||||||
|
#define shake256_finalize FIPS202_NAMESPACE(shake256_finalize)
|
||||||
|
void shake256_finalize(keccak_state *state);
|
||||||
|
#define shake256_squeeze FIPS202_NAMESPACE(shake256_squeeze)
|
||||||
|
void shake256_squeeze(uint8_t *out, size_t outlen, keccak_state *state);
|
||||||
|
#define shake256_absorb_once FIPS202_NAMESPACE(shake256_absorb_once)
|
||||||
|
void shake256_absorb_once(keccak_state *state, const uint8_t *in, size_t inlen);
|
||||||
|
#define shake256_squeezeblocks FIPS202_NAMESPACE(shake256_squeezeblocks)
|
||||||
|
void shake256_squeezeblocks(uint8_t *out, size_t nblocks, keccak_state *state);
|
||||||
|
|
||||||
|
#define shake128 FIPS202_NAMESPACE(shake128)
|
||||||
|
void shake128(uint8_t *out, size_t outlen, const uint8_t *in, size_t inlen);
|
||||||
|
#define shake256 FIPS202_NAMESPACE(shake256)
|
||||||
|
void shake256(uint8_t *out, size_t outlen, const uint8_t *in, size_t inlen);
|
||||||
|
#define sha3_256 FIPS202_NAMESPACE(sha3_256)
|
||||||
|
void sha3_256(uint8_t h[32], const uint8_t *in, size_t inlen);
|
||||||
|
#define sha3_512 FIPS202_NAMESPACE(sha3_512)
|
||||||
|
void sha3_512(uint8_t h[64], const uint8_t *in, size_t inlen);
|
||||||
|
|
||||||
|
#endif
|
||||||
196
src/crypto/pq/_d/avx2/fips202x4.c
Normal file
196
src/crypto/pq/_d/avx2/fips202x4.c
Normal file
|
|
@ -0,0 +1,196 @@
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <immintrin.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "fips202.h"
|
||||||
|
#include "fips202x4.h"
|
||||||
|
|
||||||
|
static void keccakx4_absorb_once(__m256i s[25],
|
||||||
|
unsigned int r,
|
||||||
|
const uint8_t *in0,
|
||||||
|
const uint8_t *in1,
|
||||||
|
const uint8_t *in2,
|
||||||
|
const uint8_t *in3,
|
||||||
|
size_t inlen,
|
||||||
|
uint8_t p)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
uint64_t pos = 0;
|
||||||
|
__m256i t, idx;
|
||||||
|
|
||||||
|
for(i = 0; i < 25; ++i)
|
||||||
|
s[i] = _mm256_setzero_si256();
|
||||||
|
|
||||||
|
idx = _mm256_set_epi64x((long long)in3, (long long)in2, (long long)in1, (long long)in0);
|
||||||
|
while(inlen >= r) {
|
||||||
|
for(i = 0; i < r/8; ++i) {
|
||||||
|
t = _mm256_i64gather_epi64((long long *)pos, idx, 1);
|
||||||
|
s[i] = _mm256_xor_si256(s[i], t);
|
||||||
|
pos += 8;
|
||||||
|
}
|
||||||
|
inlen -= r;
|
||||||
|
|
||||||
|
f1600x4(s, KeccakF_RoundConstants);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i = 0; i < inlen/8; ++i) {
|
||||||
|
t = _mm256_i64gather_epi64((long long *)pos, idx, 1);
|
||||||
|
s[i] = _mm256_xor_si256(s[i], t);
|
||||||
|
pos += 8;
|
||||||
|
}
|
||||||
|
inlen -= 8*i;
|
||||||
|
|
||||||
|
if(inlen) {
|
||||||
|
t = _mm256_i64gather_epi64((long long *)pos, idx, 1);
|
||||||
|
idx = _mm256_set1_epi64x((1ULL << (8*inlen)) - 1);
|
||||||
|
t = _mm256_and_si256(t, idx);
|
||||||
|
s[i] = _mm256_xor_si256(s[i], t);
|
||||||
|
}
|
||||||
|
|
||||||
|
t = _mm256_set1_epi64x((uint64_t)p << 8*inlen);
|
||||||
|
s[i] = _mm256_xor_si256(s[i], t);
|
||||||
|
t = _mm256_set1_epi64x(1ULL << 63);
|
||||||
|
s[r/8 - 1] = _mm256_xor_si256(s[r/8 - 1], t);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void keccakx4_squeezeblocks(uint8_t *out0,
|
||||||
|
uint8_t *out1,
|
||||||
|
uint8_t *out2,
|
||||||
|
uint8_t *out3,
|
||||||
|
size_t nblocks,
|
||||||
|
unsigned int r,
|
||||||
|
__m256i s[25])
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
__m128d t;
|
||||||
|
|
||||||
|
while(nblocks > 0) {
|
||||||
|
f1600x4(s, KeccakF_RoundConstants);
|
||||||
|
for(i=0; i < r/8; ++i) {
|
||||||
|
t = _mm_castsi128_pd(_mm256_castsi256_si128(s[i]));
|
||||||
|
_mm_storel_pd((__attribute__((__may_alias__)) double *)&out0[8*i], t);
|
||||||
|
_mm_storeh_pd((__attribute__((__may_alias__)) double *)&out1[8*i], t);
|
||||||
|
t = _mm_castsi128_pd(_mm256_extracti128_si256(s[i],1));
|
||||||
|
_mm_storel_pd((__attribute__((__may_alias__)) double *)&out2[8*i], t);
|
||||||
|
_mm_storeh_pd((__attribute__((__may_alias__)) double *)&out3[8*i], t);
|
||||||
|
}
|
||||||
|
|
||||||
|
out0 += r;
|
||||||
|
out1 += r;
|
||||||
|
out2 += r;
|
||||||
|
out3 += r;
|
||||||
|
--nblocks;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void shake128x4_absorb_once(keccakx4_state *state,
|
||||||
|
const uint8_t *in0,
|
||||||
|
const uint8_t *in1,
|
||||||
|
const uint8_t *in2,
|
||||||
|
const uint8_t *in3,
|
||||||
|
size_t inlen)
|
||||||
|
{
|
||||||
|
keccakx4_absorb_once(state->s, SHAKE128_RATE, in0, in1, in2, in3, inlen, 0x1F);
|
||||||
|
}
|
||||||
|
|
||||||
|
void shake128x4_squeezeblocks(uint8_t *out0,
|
||||||
|
uint8_t *out1,
|
||||||
|
uint8_t *out2,
|
||||||
|
uint8_t *out3,
|
||||||
|
size_t nblocks,
|
||||||
|
keccakx4_state *state)
|
||||||
|
{
|
||||||
|
keccakx4_squeezeblocks(out0, out1, out2, out3, nblocks, SHAKE128_RATE, state->s);
|
||||||
|
}
|
||||||
|
|
||||||
|
void shake256x4_absorb_once(keccakx4_state *state,
|
||||||
|
const uint8_t *in0,
|
||||||
|
const uint8_t *in1,
|
||||||
|
const uint8_t *in2,
|
||||||
|
const uint8_t *in3,
|
||||||
|
size_t inlen)
|
||||||
|
{
|
||||||
|
keccakx4_absorb_once(state->s, SHAKE256_RATE, in0, in1, in2, in3, inlen, 0x1F);
|
||||||
|
}
|
||||||
|
|
||||||
|
void shake256x4_squeezeblocks(uint8_t *out0,
|
||||||
|
uint8_t *out1,
|
||||||
|
uint8_t *out2,
|
||||||
|
uint8_t *out3,
|
||||||
|
size_t nblocks,
|
||||||
|
keccakx4_state *state)
|
||||||
|
{
|
||||||
|
keccakx4_squeezeblocks(out0, out1, out2, out3, nblocks, SHAKE256_RATE, state->s);
|
||||||
|
}
|
||||||
|
|
||||||
|
void shake128x4(uint8_t *out0,
|
||||||
|
uint8_t *out1,
|
||||||
|
uint8_t *out2,
|
||||||
|
uint8_t *out3,
|
||||||
|
size_t outlen,
|
||||||
|
const uint8_t *in0,
|
||||||
|
const uint8_t *in1,
|
||||||
|
const uint8_t *in2,
|
||||||
|
const uint8_t *in3,
|
||||||
|
size_t inlen)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
size_t nblocks = outlen/SHAKE128_RATE;
|
||||||
|
uint8_t t[4][SHAKE128_RATE];
|
||||||
|
keccakx4_state state;
|
||||||
|
|
||||||
|
shake128x4_absorb_once(&state, in0, in1, in2, in3, inlen);
|
||||||
|
shake128x4_squeezeblocks(out0, out1, out2, out3, nblocks, &state);
|
||||||
|
|
||||||
|
out0 += nblocks*SHAKE128_RATE;
|
||||||
|
out1 += nblocks*SHAKE128_RATE;
|
||||||
|
out2 += nblocks*SHAKE128_RATE;
|
||||||
|
out3 += nblocks*SHAKE128_RATE;
|
||||||
|
outlen -= nblocks*SHAKE128_RATE;
|
||||||
|
|
||||||
|
if(outlen) {
|
||||||
|
shake128x4_squeezeblocks(t[0], t[1], t[2], t[3], 1, &state);
|
||||||
|
for(i = 0; i < outlen; ++i) {
|
||||||
|
out0[i] = t[0][i];
|
||||||
|
out1[i] = t[1][i];
|
||||||
|
out2[i] = t[2][i];
|
||||||
|
out3[i] = t[3][i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void shake256x4(uint8_t *out0,
|
||||||
|
uint8_t *out1,
|
||||||
|
uint8_t *out2,
|
||||||
|
uint8_t *out3,
|
||||||
|
size_t outlen,
|
||||||
|
const uint8_t *in0,
|
||||||
|
const uint8_t *in1,
|
||||||
|
const uint8_t *in2,
|
||||||
|
const uint8_t *in3,
|
||||||
|
size_t inlen)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
size_t nblocks = outlen/SHAKE256_RATE;
|
||||||
|
uint8_t t[4][SHAKE256_RATE];
|
||||||
|
keccakx4_state state;
|
||||||
|
|
||||||
|
shake256x4_absorb_once(&state, in0, in1, in2, in3, inlen);
|
||||||
|
shake256x4_squeezeblocks(out0, out1, out2, out3, nblocks, &state);
|
||||||
|
|
||||||
|
out0 += nblocks*SHAKE256_RATE;
|
||||||
|
out1 += nblocks*SHAKE256_RATE;
|
||||||
|
out2 += nblocks*SHAKE256_RATE;
|
||||||
|
out3 += nblocks*SHAKE256_RATE;
|
||||||
|
outlen -= nblocks*SHAKE256_RATE;
|
||||||
|
|
||||||
|
if(outlen) {
|
||||||
|
shake256x4_squeezeblocks(t[0], t[1], t[2], t[3], 1, &state);
|
||||||
|
for(i = 0; i < outlen; ++i) {
|
||||||
|
out0[i] = t[0][i];
|
||||||
|
out1[i] = t[1][i];
|
||||||
|
out2[i] = t[2][i];
|
||||||
|
out3[i] = t[3][i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
91
src/crypto/pq/_d/avx2/fips202x4.h
Normal file
91
src/crypto/pq/_d/avx2/fips202x4.h
Normal file
|
|
@ -0,0 +1,91 @@
|
||||||
|
#ifndef FIPS202X4_H
|
||||||
|
#define FIPS202X4_H
|
||||||
|
|
||||||
|
#define FIPS202X4_NAMESPACE(s) pqcrystals_dilithium_fips202x4_avx2_##s
|
||||||
|
|
||||||
|
#ifdef __ASSEMBLER__
|
||||||
|
/* The C ABI on MacOS exports all symbols with a leading
|
||||||
|
* underscore. This means that any symbols we refer to from
|
||||||
|
* C files (functions) can't be found, and all symbols we
|
||||||
|
* refer to from ASM also can't be found.
|
||||||
|
*
|
||||||
|
* This define helps us get around this
|
||||||
|
*/
|
||||||
|
#if defined(__WIN32__) || defined(__APPLE__)
|
||||||
|
#define decorate(s) _##s
|
||||||
|
#define _cdecl(s) decorate(s)
|
||||||
|
#define cdecl(s) _cdecl(FIPS202X4_NAMESPACE(##s))
|
||||||
|
#else
|
||||||
|
#define cdecl(s) FIPS202X4_NAMESPACE(##s)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#else
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <immintrin.h>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
__m256i s[25];
|
||||||
|
} keccakx4_state;
|
||||||
|
|
||||||
|
#define f1600x4 FIPS202X4_NAMESPACE(f1600x4)
|
||||||
|
void f1600x4(__m256i *s, const uint64_t *rc);
|
||||||
|
|
||||||
|
#define shake128x4_absorb_once FIPS202X4_NAMESPACE(shake128x4_absorb_once)
|
||||||
|
void shake128x4_absorb_once(keccakx4_state *state,
|
||||||
|
const uint8_t *in0,
|
||||||
|
const uint8_t *in1,
|
||||||
|
const uint8_t *in2,
|
||||||
|
const uint8_t *in3,
|
||||||
|
size_t inlen);
|
||||||
|
|
||||||
|
#define shake128x4_squeezeblocks FIPS202X4_NAMESPACE(shake128x4_squeezeblocks)
|
||||||
|
void shake128x4_squeezeblocks(uint8_t *out0,
|
||||||
|
uint8_t *out1,
|
||||||
|
uint8_t *out2,
|
||||||
|
uint8_t *out3,
|
||||||
|
size_t nblocks,
|
||||||
|
keccakx4_state *state);
|
||||||
|
|
||||||
|
#define shake256x4_absorb_once FIPS202X4_NAMESPACE(shake256x4_absorb_once)
|
||||||
|
void shake256x4_absorb_once(keccakx4_state *state,
|
||||||
|
const uint8_t *in0,
|
||||||
|
const uint8_t *in1,
|
||||||
|
const uint8_t *in2,
|
||||||
|
const uint8_t *in3,
|
||||||
|
size_t inlen);
|
||||||
|
|
||||||
|
#define shake256x4_squeezeblocks FIPS202X4_NAMESPACE(shake256x4_squeezeblocks)
|
||||||
|
void shake256x4_squeezeblocks(uint8_t *out0,
|
||||||
|
uint8_t *out1,
|
||||||
|
uint8_t *out2,
|
||||||
|
uint8_t *out3,
|
||||||
|
size_t nblocks,
|
||||||
|
keccakx4_state *state);
|
||||||
|
|
||||||
|
#define shake128x4 FIPS202X4_NAMESPACE(shake128x4)
|
||||||
|
void shake128x4(uint8_t *out0,
|
||||||
|
uint8_t *out1,
|
||||||
|
uint8_t *out2,
|
||||||
|
uint8_t *out3,
|
||||||
|
size_t outlen,
|
||||||
|
const uint8_t *in0,
|
||||||
|
const uint8_t *in1,
|
||||||
|
const uint8_t *in2,
|
||||||
|
const uint8_t *in3,
|
||||||
|
size_t inlen);
|
||||||
|
|
||||||
|
#define shake256x4 FIPS202X4_NAMESPACE(shake256x4)
|
||||||
|
void shake256x4(uint8_t *out0,
|
||||||
|
uint8_t *out1,
|
||||||
|
uint8_t *out2,
|
||||||
|
uint8_t *out3,
|
||||||
|
size_t outlen,
|
||||||
|
const uint8_t *in0,
|
||||||
|
const uint8_t *in1,
|
||||||
|
const uint8_t *in2,
|
||||||
|
const uint8_t *in3,
|
||||||
|
size_t inlen);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
240
src/crypto/pq/_d/avx2/invntt.S
Normal file
240
src/crypto/pq/_d/avx2/invntt.S
Normal file
|
|
@ -0,0 +1,240 @@
|
||||||
|
#include "consts.h"
|
||||||
|
.include "shuffle.inc"
|
||||||
|
|
||||||
|
.macro butterfly l,h,zl0=1,zl1=1,zh0=2,zh1=2
|
||||||
|
vpsubd %ymm\l,%ymm\h,%ymm12
|
||||||
|
vpaddd %ymm\h,%ymm\l,%ymm\l
|
||||||
|
|
||||||
|
vpmuldq %ymm\zl0,%ymm12,%ymm13
|
||||||
|
vmovshdup %ymm12,%ymm\h
|
||||||
|
vpmuldq %ymm\zl1,%ymm\h,%ymm14
|
||||||
|
|
||||||
|
vpmuldq %ymm\zh0,%ymm12,%ymm12
|
||||||
|
vpmuldq %ymm\zh1,%ymm\h,%ymm\h
|
||||||
|
|
||||||
|
vpmuldq %ymm0,%ymm13,%ymm13
|
||||||
|
vpmuldq %ymm0,%ymm14,%ymm14
|
||||||
|
|
||||||
|
vpsubd %ymm13,%ymm12,%ymm12
|
||||||
|
vpsubd %ymm14,%ymm\h,%ymm\h
|
||||||
|
|
||||||
|
vmovshdup %ymm12,%ymm12
|
||||||
|
vpblendd $0xAA,%ymm\h,%ymm12,%ymm\h
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro levels0t5 off
|
||||||
|
vmovdqa 256*\off+ 0(%rdi),%ymm4
|
||||||
|
vmovdqa 256*\off+ 32(%rdi),%ymm5
|
||||||
|
vmovdqa 256*\off+ 64(%rdi),%ymm6
|
||||||
|
vmovdqa 256*\off+ 96(%rdi),%ymm7
|
||||||
|
vmovdqa 256*\off+128(%rdi),%ymm8
|
||||||
|
vmovdqa 256*\off+160(%rdi),%ymm9
|
||||||
|
vmovdqa 256*\off+192(%rdi),%ymm10
|
||||||
|
vmovdqa 256*\off+224(%rdi),%ymm11
|
||||||
|
|
||||||
|
/* level 0 */
|
||||||
|
vpermq $0x1B,(_ZETAS_QINV+296-8*\off-8)*4(%rsi),%ymm3
|
||||||
|
vpermq $0x1B,(_ZETAS+296-8*\off-8)*4(%rsi),%ymm15
|
||||||
|
vmovshdup %ymm3,%ymm1
|
||||||
|
vmovshdup %ymm15,%ymm2
|
||||||
|
butterfly 4,5,1,3,2,15
|
||||||
|
|
||||||
|
vpermq $0x1B,(_ZETAS_QINV+296-8*\off-40)*4(%rsi),%ymm3
|
||||||
|
vpermq $0x1B,(_ZETAS+296-8*\off-40)*4(%rsi),%ymm15
|
||||||
|
vmovshdup %ymm3,%ymm1
|
||||||
|
vmovshdup %ymm15,%ymm2
|
||||||
|
butterfly 6,7,1,3,2,15
|
||||||
|
|
||||||
|
vpermq $0x1B,(_ZETAS_QINV+296-8*\off-72)*4(%rsi),%ymm3
|
||||||
|
vpermq $0x1B,(_ZETAS+296-8*\off-72)*4(%rsi),%ymm15
|
||||||
|
vmovshdup %ymm3,%ymm1
|
||||||
|
vmovshdup %ymm15,%ymm2
|
||||||
|
butterfly 8,9,1,3,2,15
|
||||||
|
|
||||||
|
vpermq $0x1B,(_ZETAS_QINV+296-8*\off-104)*4(%rsi),%ymm3
|
||||||
|
vpermq $0x1B,(_ZETAS+296-8*\off-104)*4(%rsi),%ymm15
|
||||||
|
vmovshdup %ymm3,%ymm1
|
||||||
|
vmovshdup %ymm15,%ymm2
|
||||||
|
butterfly 10,11,1,3,2,15
|
||||||
|
|
||||||
|
/* level 1 */
|
||||||
|
vpermq $0x1B,(_ZETAS_QINV+168-8*\off-8)*4(%rsi),%ymm3
|
||||||
|
vpermq $0x1B,(_ZETAS+168-8*\off-8)*4(%rsi),%ymm15
|
||||||
|
vmovshdup %ymm3,%ymm1
|
||||||
|
vmovshdup %ymm15,%ymm2
|
||||||
|
butterfly 4,6,1,3,2,15
|
||||||
|
butterfly 5,7,1,3,2,15
|
||||||
|
|
||||||
|
vpermq $0x1B,(_ZETAS_QINV+168-8*\off-40)*4(%rsi),%ymm3
|
||||||
|
vpermq $0x1B,(_ZETAS+168-8*\off-40)*4(%rsi),%ymm15
|
||||||
|
vmovshdup %ymm3,%ymm1
|
||||||
|
vmovshdup %ymm15,%ymm2
|
||||||
|
butterfly 8,10,1,3,2,15
|
||||||
|
butterfly 9,11,1,3,2,15
|
||||||
|
|
||||||
|
/* level 2 */
|
||||||
|
vpermq $0x1B,(_ZETAS_QINV+104-8*\off-8)*4(%rsi),%ymm3
|
||||||
|
vpermq $0x1B,(_ZETAS+104-8*\off-8)*4(%rsi),%ymm15
|
||||||
|
vmovshdup %ymm3,%ymm1
|
||||||
|
vmovshdup %ymm15,%ymm2
|
||||||
|
butterfly 4,8,1,3,2,15
|
||||||
|
butterfly 5,9,1,3,2,15
|
||||||
|
butterfly 6,10,1,3,2,15
|
||||||
|
butterfly 7,11,1,3,2,15
|
||||||
|
|
||||||
|
/* level 3 */
|
||||||
|
shuffle2 4,5,3,5
|
||||||
|
shuffle2 6,7,4,7
|
||||||
|
shuffle2 8,9,6,9
|
||||||
|
shuffle2 10,11,8,11
|
||||||
|
|
||||||
|
vpermq $0x1B,(_ZETAS_QINV+72-8*\off-8)*4(%rsi),%ymm1
|
||||||
|
vpermq $0x1B,(_ZETAS+72-8*\off-8)*4(%rsi),%ymm2
|
||||||
|
butterfly 3,5
|
||||||
|
butterfly 4,7
|
||||||
|
butterfly 6,9
|
||||||
|
butterfly 8,11
|
||||||
|
|
||||||
|
/* level 4 */
|
||||||
|
shuffle4 3,4,10,4
|
||||||
|
shuffle4 6,8,3,8
|
||||||
|
shuffle4 5,7,6,7
|
||||||
|
shuffle4 9,11,5,11
|
||||||
|
|
||||||
|
vpermq $0x1B,(_ZETAS_QINV+40-8*\off-8)*4(%rsi),%ymm1
|
||||||
|
vpermq $0x1B,(_ZETAS+40-8*\off-8)*4(%rsi),%ymm2
|
||||||
|
butterfly 10,4
|
||||||
|
butterfly 3,8
|
||||||
|
butterfly 6,7
|
||||||
|
butterfly 5,11
|
||||||
|
|
||||||
|
/* level 5 */
|
||||||
|
shuffle8 10,3,9,3
|
||||||
|
shuffle8 6,5,10,5
|
||||||
|
shuffle8 4,8,6,8
|
||||||
|
shuffle8 7,11,4,11
|
||||||
|
|
||||||
|
vpbroadcastd (_ZETAS_QINV+7-\off)*4(%rsi),%ymm1
|
||||||
|
vpbroadcastd (_ZETAS+7-\off)*4(%rsi),%ymm2
|
||||||
|
butterfly 9,3
|
||||||
|
butterfly 10,5
|
||||||
|
butterfly 6,8
|
||||||
|
butterfly 4,11
|
||||||
|
|
||||||
|
vmovdqa %ymm9,256*\off+ 0(%rdi)
|
||||||
|
vmovdqa %ymm10,256*\off+ 32(%rdi)
|
||||||
|
vmovdqa %ymm6,256*\off+ 64(%rdi)
|
||||||
|
vmovdqa %ymm4,256*\off+ 96(%rdi)
|
||||||
|
vmovdqa %ymm3,256*\off+128(%rdi)
|
||||||
|
vmovdqa %ymm5,256*\off+160(%rdi)
|
||||||
|
vmovdqa %ymm8,256*\off+192(%rdi)
|
||||||
|
vmovdqa %ymm11,256*\off+224(%rdi)
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro levels6t7 off
|
||||||
|
vmovdqa 0+32*\off(%rdi),%ymm4
|
||||||
|
vmovdqa 128+32*\off(%rdi),%ymm5
|
||||||
|
vmovdqa 256+32*\off(%rdi),%ymm6
|
||||||
|
vmovdqa 384+32*\off(%rdi),%ymm7
|
||||||
|
vmovdqa 512+32*\off(%rdi),%ymm8
|
||||||
|
vmovdqa 640+32*\off(%rdi),%ymm9
|
||||||
|
vmovdqa 768+32*\off(%rdi),%ymm10
|
||||||
|
vmovdqa 896+32*\off(%rdi),%ymm11
|
||||||
|
|
||||||
|
/* level 6 */
|
||||||
|
vpbroadcastd (_ZETAS_QINV+3)*4(%rsi),%ymm1
|
||||||
|
vpbroadcastd (_ZETAS+3)*4(%rsi),%ymm2
|
||||||
|
butterfly 4,6
|
||||||
|
butterfly 5,7
|
||||||
|
|
||||||
|
vpbroadcastd (_ZETAS_QINV+2)*4(%rsi),%ymm1
|
||||||
|
vpbroadcastd (_ZETAS+2)*4(%rsi),%ymm2
|
||||||
|
butterfly 8,10
|
||||||
|
butterfly 9,11
|
||||||
|
|
||||||
|
/* level 7 */
|
||||||
|
vpbroadcastd (_ZETAS_QINV+0)*4(%rsi),%ymm1
|
||||||
|
vpbroadcastd (_ZETAS+0)*4(%rsi),%ymm2
|
||||||
|
|
||||||
|
butterfly 4,8
|
||||||
|
butterfly 5,9
|
||||||
|
butterfly 6,10
|
||||||
|
butterfly 7,11
|
||||||
|
|
||||||
|
vmovdqa %ymm8,512+32*\off(%rdi)
|
||||||
|
vmovdqa %ymm9,640+32*\off(%rdi)
|
||||||
|
vmovdqa %ymm10,768+32*\off(%rdi)
|
||||||
|
vmovdqa %ymm11,896+32*\off(%rdi)
|
||||||
|
|
||||||
|
vmovdqa (_8XDIV_QINV)*4(%rsi),%ymm1
|
||||||
|
vmovdqa (_8XDIV)*4(%rsi),%ymm2
|
||||||
|
vpmuldq %ymm1,%ymm4,%ymm12
|
||||||
|
vpmuldq %ymm1,%ymm5,%ymm13
|
||||||
|
vmovshdup %ymm4,%ymm8
|
||||||
|
vmovshdup %ymm5,%ymm9
|
||||||
|
vpmuldq %ymm1,%ymm8,%ymm14
|
||||||
|
vpmuldq %ymm1,%ymm9,%ymm15
|
||||||
|
vpmuldq %ymm2,%ymm4,%ymm4
|
||||||
|
vpmuldq %ymm2,%ymm5,%ymm5
|
||||||
|
vpmuldq %ymm2,%ymm8,%ymm8
|
||||||
|
vpmuldq %ymm2,%ymm9,%ymm9
|
||||||
|
vpmuldq %ymm0,%ymm12,%ymm12
|
||||||
|
vpmuldq %ymm0,%ymm13,%ymm13
|
||||||
|
vpmuldq %ymm0,%ymm14,%ymm14
|
||||||
|
vpmuldq %ymm0,%ymm15,%ymm15
|
||||||
|
vpsubd %ymm12,%ymm4,%ymm4
|
||||||
|
vpsubd %ymm13,%ymm5,%ymm5
|
||||||
|
vpsubd %ymm14,%ymm8,%ymm8
|
||||||
|
vpsubd %ymm15,%ymm9,%ymm9
|
||||||
|
vmovshdup %ymm4,%ymm4
|
||||||
|
vmovshdup %ymm5,%ymm5
|
||||||
|
vpblendd $0xAA,%ymm8,%ymm4,%ymm4
|
||||||
|
vpblendd $0xAA,%ymm9,%ymm5,%ymm5
|
||||||
|
|
||||||
|
vpmuldq %ymm1,%ymm6,%ymm12
|
||||||
|
vpmuldq %ymm1,%ymm7,%ymm13
|
||||||
|
vmovshdup %ymm6,%ymm8
|
||||||
|
vmovshdup %ymm7,%ymm9
|
||||||
|
vpmuldq %ymm1,%ymm8,%ymm14
|
||||||
|
vpmuldq %ymm1,%ymm9,%ymm15
|
||||||
|
vpmuldq %ymm2,%ymm6,%ymm6
|
||||||
|
vpmuldq %ymm2,%ymm7,%ymm7
|
||||||
|
vpmuldq %ymm2,%ymm8,%ymm8
|
||||||
|
vpmuldq %ymm2,%ymm9,%ymm9
|
||||||
|
vpmuldq %ymm0,%ymm12,%ymm12
|
||||||
|
vpmuldq %ymm0,%ymm13,%ymm13
|
||||||
|
vpmuldq %ymm0,%ymm14,%ymm14
|
||||||
|
vpmuldq %ymm0,%ymm15,%ymm15
|
||||||
|
vpsubd %ymm12,%ymm6,%ymm6
|
||||||
|
vpsubd %ymm13,%ymm7,%ymm7
|
||||||
|
vpsubd %ymm14,%ymm8,%ymm8
|
||||||
|
vpsubd %ymm15,%ymm9,%ymm9
|
||||||
|
vmovshdup %ymm6,%ymm6
|
||||||
|
vmovshdup %ymm7,%ymm7
|
||||||
|
vpblendd $0xAA,%ymm8,%ymm6,%ymm6
|
||||||
|
vpblendd $0xAA,%ymm9,%ymm7,%ymm7
|
||||||
|
|
||||||
|
vmovdqa %ymm4, 0+32*\off(%rdi)
|
||||||
|
vmovdqa %ymm5,128+32*\off(%rdi)
|
||||||
|
vmovdqa %ymm6,256+32*\off(%rdi)
|
||||||
|
vmovdqa %ymm7,384+32*\off(%rdi)
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.text
|
||||||
|
.global cdecl(invntt_avx)
|
||||||
|
cdecl(invntt_avx):
|
||||||
|
vmovdqa _8XQ*4(%rsi),%ymm0
|
||||||
|
|
||||||
|
levels0t5 0
|
||||||
|
levels0t5 1
|
||||||
|
levels0t5 2
|
||||||
|
levels0t5 3
|
||||||
|
|
||||||
|
levels6t7 0
|
||||||
|
levels6t7 1
|
||||||
|
levels6t7 2
|
||||||
|
levels6t7 3
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
.section .note.GNU-stack,"",@progbits
|
||||||
198
src/crypto/pq/_d/avx2/ntt.S
Normal file
198
src/crypto/pq/_d/avx2/ntt.S
Normal file
|
|
@ -0,0 +1,198 @@
|
||||||
|
#include "consts.h"
|
||||||
|
.include "shuffle.inc"
|
||||||
|
|
||||||
|
.macro butterfly l,h,zl0=1,zl1=1,zh0=2,zh1=2
|
||||||
|
vpmuldq %ymm\zl0,%ymm\h,%ymm13
|
||||||
|
vmovshdup %ymm\h,%ymm12
|
||||||
|
vpmuldq %ymm\zl1,%ymm12,%ymm14
|
||||||
|
|
||||||
|
vpmuldq %ymm\zh0,%ymm\h,%ymm\h
|
||||||
|
vpmuldq %ymm\zh1,%ymm12,%ymm12
|
||||||
|
|
||||||
|
vpmuldq %ymm0,%ymm13,%ymm13
|
||||||
|
vpmuldq %ymm0,%ymm14,%ymm14
|
||||||
|
|
||||||
|
vmovshdup %ymm\h,%ymm\h
|
||||||
|
vpblendd $0xAA,%ymm12,%ymm\h,%ymm\h
|
||||||
|
|
||||||
|
vpsubd %ymm\h,%ymm\l,%ymm12
|
||||||
|
vpaddd %ymm\h,%ymm\l,%ymm\l
|
||||||
|
|
||||||
|
vmovshdup %ymm13,%ymm13
|
||||||
|
vpblendd $0xAA,%ymm14,%ymm13,%ymm13
|
||||||
|
|
||||||
|
vpaddd %ymm13,%ymm12,%ymm\h
|
||||||
|
vpsubd %ymm13,%ymm\l,%ymm\l
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro levels0t1 off
|
||||||
|
/* level 0 */
|
||||||
|
vpbroadcastd (_ZETAS_QINV+1)*4(%rsi),%ymm1
|
||||||
|
vpbroadcastd (_ZETAS+1)*4(%rsi),%ymm2
|
||||||
|
|
||||||
|
vmovdqa 0+32*\off(%rdi),%ymm4
|
||||||
|
vmovdqa 128+32*\off(%rdi),%ymm5
|
||||||
|
vmovdqa 256+32*\off(%rdi),%ymm6
|
||||||
|
vmovdqa 384+32*\off(%rdi),%ymm7
|
||||||
|
vmovdqa 512+32*\off(%rdi),%ymm8
|
||||||
|
vmovdqa 640+32*\off(%rdi),%ymm9
|
||||||
|
vmovdqa 768+32*\off(%rdi),%ymm10
|
||||||
|
vmovdqa 896+32*\off(%rdi),%ymm11
|
||||||
|
|
||||||
|
butterfly 4,8
|
||||||
|
butterfly 5,9
|
||||||
|
butterfly 6,10
|
||||||
|
butterfly 7,11
|
||||||
|
|
||||||
|
/* level 1 */
|
||||||
|
vpbroadcastd (_ZETAS_QINV+2)*4(%rsi),%ymm1
|
||||||
|
vpbroadcastd (_ZETAS+2)*4(%rsi),%ymm2
|
||||||
|
butterfly 4,6
|
||||||
|
butterfly 5,7
|
||||||
|
|
||||||
|
vpbroadcastd (_ZETAS_QINV+3)*4(%rsi),%ymm1
|
||||||
|
vpbroadcastd (_ZETAS+3)*4(%rsi),%ymm2
|
||||||
|
butterfly 8,10
|
||||||
|
butterfly 9,11
|
||||||
|
|
||||||
|
vmovdqa %ymm4, 0+32*\off(%rdi)
|
||||||
|
vmovdqa %ymm5,128+32*\off(%rdi)
|
||||||
|
vmovdqa %ymm6,256+32*\off(%rdi)
|
||||||
|
vmovdqa %ymm7,384+32*\off(%rdi)
|
||||||
|
vmovdqa %ymm8,512+32*\off(%rdi)
|
||||||
|
vmovdqa %ymm9,640+32*\off(%rdi)
|
||||||
|
vmovdqa %ymm10,768+32*\off(%rdi)
|
||||||
|
vmovdqa %ymm11,896+32*\off(%rdi)
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro levels2t7 off
|
||||||
|
/* level 2 */
|
||||||
|
vmovdqa 256*\off+ 0(%rdi),%ymm4
|
||||||
|
vmovdqa 256*\off+ 32(%rdi),%ymm5
|
||||||
|
vmovdqa 256*\off+ 64(%rdi),%ymm6
|
||||||
|
vmovdqa 256*\off+ 96(%rdi),%ymm7
|
||||||
|
vmovdqa 256*\off+128(%rdi),%ymm8
|
||||||
|
vmovdqa 256*\off+160(%rdi),%ymm9
|
||||||
|
vmovdqa 256*\off+192(%rdi),%ymm10
|
||||||
|
vmovdqa 256*\off+224(%rdi),%ymm11
|
||||||
|
|
||||||
|
vpbroadcastd (_ZETAS_QINV+4+\off)*4(%rsi),%ymm1
|
||||||
|
vpbroadcastd (_ZETAS+4+\off)*4(%rsi),%ymm2
|
||||||
|
|
||||||
|
butterfly 4,8
|
||||||
|
butterfly 5,9
|
||||||
|
butterfly 6,10
|
||||||
|
butterfly 7,11
|
||||||
|
|
||||||
|
shuffle8 4,8,3,8
|
||||||
|
shuffle8 5,9,4,9
|
||||||
|
shuffle8 6,10,5,10
|
||||||
|
shuffle8 7,11,6,11
|
||||||
|
|
||||||
|
/* level 3 */
|
||||||
|
vmovdqa (_ZETAS_QINV+8+8*\off)*4(%rsi),%ymm1
|
||||||
|
vmovdqa (_ZETAS+8+8*\off)*4(%rsi),%ymm2
|
||||||
|
|
||||||
|
butterfly 3,5
|
||||||
|
butterfly 8,10
|
||||||
|
butterfly 4,6
|
||||||
|
butterfly 9,11
|
||||||
|
|
||||||
|
shuffle4 3,5,7,5
|
||||||
|
shuffle4 8,10,3,10
|
||||||
|
shuffle4 4,6,8,6
|
||||||
|
shuffle4 9,11,4,11
|
||||||
|
|
||||||
|
/* level 4 */
|
||||||
|
vmovdqa (_ZETAS_QINV+40+8*\off)*4(%rsi),%ymm1
|
||||||
|
vmovdqa (_ZETAS+40+8*\off)*4(%rsi),%ymm2
|
||||||
|
|
||||||
|
butterfly 7,8
|
||||||
|
butterfly 5,6
|
||||||
|
butterfly 3,4
|
||||||
|
butterfly 10,11
|
||||||
|
|
||||||
|
shuffle2 7,8,9,8
|
||||||
|
shuffle2 5,6,7,6
|
||||||
|
shuffle2 3,4,5,4
|
||||||
|
shuffle2 10,11,3,11
|
||||||
|
|
||||||
|
/* level 5 */
|
||||||
|
vmovdqa (_ZETAS_QINV+72+8*\off)*4(%rsi),%ymm1
|
||||||
|
vmovdqa (_ZETAS+72+8*\off)*4(%rsi),%ymm2
|
||||||
|
vpsrlq $32,%ymm1,%ymm10
|
||||||
|
vmovshdup %ymm2,%ymm15
|
||||||
|
|
||||||
|
butterfly 9,5,1,10,2,15
|
||||||
|
butterfly 8,4,1,10,2,15
|
||||||
|
butterfly 7,3,1,10,2,15
|
||||||
|
butterfly 6,11,1,10,2,15
|
||||||
|
|
||||||
|
/* level 6 */
|
||||||
|
vmovdqa (_ZETAS_QINV+104+8*\off)*4(%rsi),%ymm1
|
||||||
|
vmovdqa (_ZETAS+104+8*\off)*4(%rsi),%ymm2
|
||||||
|
vpsrlq $32,%ymm1,%ymm10
|
||||||
|
vmovshdup %ymm2,%ymm15
|
||||||
|
butterfly 9,7,1,10,2,15
|
||||||
|
butterfly 8,6,1,10,2,15
|
||||||
|
|
||||||
|
vmovdqa (_ZETAS_QINV+104+8*\off+32)*4(%rsi),%ymm1
|
||||||
|
vmovdqa (_ZETAS+104+8*\off+32)*4(%rsi),%ymm2
|
||||||
|
vpsrlq $32,%ymm1,%ymm10
|
||||||
|
vmovshdup %ymm2,%ymm15
|
||||||
|
butterfly 5,3,1,10,2,15
|
||||||
|
butterfly 4,11,1,10,2,15
|
||||||
|
|
||||||
|
/* level 7 */
|
||||||
|
vmovdqa (_ZETAS_QINV+168+8*\off)*4(%rsi),%ymm1
|
||||||
|
vmovdqa (_ZETAS+168+8*\off)*4(%rsi),%ymm2
|
||||||
|
vpsrlq $32,%ymm1,%ymm10
|
||||||
|
vmovshdup %ymm2,%ymm15
|
||||||
|
butterfly 9,8,1,10,2,15
|
||||||
|
|
||||||
|
vmovdqa (_ZETAS_QINV+168+8*\off+32)*4(%rsi),%ymm1
|
||||||
|
vmovdqa (_ZETAS+168+8*\off+32)*4(%rsi),%ymm2
|
||||||
|
vpsrlq $32,%ymm1,%ymm10
|
||||||
|
vmovshdup %ymm2,%ymm15
|
||||||
|
butterfly 7,6,1,10,2,15
|
||||||
|
|
||||||
|
vmovdqa (_ZETAS_QINV+168+8*\off+64)*4(%rsi),%ymm1
|
||||||
|
vmovdqa (_ZETAS+168+8*\off+64)*4(%rsi),%ymm2
|
||||||
|
vpsrlq $32,%ymm1,%ymm10
|
||||||
|
vmovshdup %ymm2,%ymm15
|
||||||
|
butterfly 5,4,1,10,2,15
|
||||||
|
|
||||||
|
vmovdqa (_ZETAS_QINV+168+8*\off+96)*4(%rsi),%ymm1
|
||||||
|
vmovdqa (_ZETAS+168+8*\off+96)*4(%rsi),%ymm2
|
||||||
|
vpsrlq $32,%ymm1,%ymm10
|
||||||
|
vmovshdup %ymm2,%ymm15
|
||||||
|
butterfly 3,11,1,10,2,15
|
||||||
|
|
||||||
|
vmovdqa %ymm9,256*\off+ 0(%rdi)
|
||||||
|
vmovdqa %ymm8,256*\off+ 32(%rdi)
|
||||||
|
vmovdqa %ymm7,256*\off+ 64(%rdi)
|
||||||
|
vmovdqa %ymm6,256*\off+ 96(%rdi)
|
||||||
|
vmovdqa %ymm5,256*\off+128(%rdi)
|
||||||
|
vmovdqa %ymm4,256*\off+160(%rdi)
|
||||||
|
vmovdqa %ymm3,256*\off+192(%rdi)
|
||||||
|
vmovdqa %ymm11,256*\off+224(%rdi)
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.text
|
||||||
|
.global cdecl(ntt_avx)
|
||||||
|
cdecl(ntt_avx):
|
||||||
|
vmovdqa _8XQ*4(%rsi),%ymm0
|
||||||
|
|
||||||
|
levels0t1 0
|
||||||
|
levels0t1 1
|
||||||
|
levels0t1 2
|
||||||
|
levels0t1 3
|
||||||
|
|
||||||
|
levels2t7 0
|
||||||
|
levels2t7 1
|
||||||
|
levels2t7 2
|
||||||
|
levels2t7 3
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
.section .note.GNU-stack,"",@progbits
|
||||||
19
src/crypto/pq/_d/avx2/ntt.h
Normal file
19
src/crypto/pq/_d/avx2/ntt.h
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
#ifndef NTT_H
|
||||||
|
#define NTT_H
|
||||||
|
|
||||||
|
#include <immintrin.h>
|
||||||
|
|
||||||
|
#define ntt_avx DILITHIUM_NAMESPACE(ntt_avx)
|
||||||
|
void ntt_avx(__m256i *a, const __m256i *qdata);
|
||||||
|
#define invntt_avx DILITHIUM_NAMESPACE(invntt_avx)
|
||||||
|
void invntt_avx(__m256i *a, const __m256i *qdata);
|
||||||
|
|
||||||
|
#define nttunpack_avx DILITHIUM_NAMESPACE(nttunpack_avx)
|
||||||
|
void nttunpack_avx(__m256i *a);
|
||||||
|
|
||||||
|
#define pointwise_avx DILITHIUM_NAMESPACE(pointwise_avx)
|
||||||
|
void pointwise_avx(__m256i *c, const __m256i *a, const __m256i *b, const __m256i *qdata);
|
||||||
|
#define pointwise_acc_avx DILITHIUM_NAMESPACE(pointwise_acc_avx)
|
||||||
|
void pointwise_acc_avx(__m256i *c, const __m256i *a, const __m256i *b, const __m256i *qdata);
|
||||||
|
|
||||||
|
#endif
|
||||||
1
src/crypto/pq/_d/avx2/packing.c
Symbolic link
1
src/crypto/pq/_d/avx2/packing.c
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
../ref/packing.c
|
||||||
1
src/crypto/pq/_d/avx2/packing.h
Symbolic link
1
src/crypto/pq/_d/avx2/packing.h
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
../ref/packing.h
|
||||||
1
src/crypto/pq/_d/avx2/params.h
Symbolic link
1
src/crypto/pq/_d/avx2/params.h
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
../ref/params.h
|
||||||
213
src/crypto/pq/_d/avx2/pointwise.S
Normal file
213
src/crypto/pq/_d/avx2/pointwise.S
Normal file
|
|
@ -0,0 +1,213 @@
|
||||||
|
#include "params.h"
|
||||||
|
#include "consts.h"
|
||||||
|
|
||||||
|
.text
|
||||||
|
.global cdecl(pointwise_avx)
|
||||||
|
cdecl(pointwise_avx):
|
||||||
|
#consts
|
||||||
|
vmovdqa _8XQINV*4(%rcx),%ymm0
|
||||||
|
vmovdqa _8XQ*4(%rcx),%ymm1
|
||||||
|
|
||||||
|
xor %eax,%eax
|
||||||
|
_looptop1:
|
||||||
|
#load
|
||||||
|
vmovdqa (%rsi),%ymm2
|
||||||
|
vmovdqa 32(%rsi),%ymm4
|
||||||
|
vmovdqa 64(%rsi),%ymm6
|
||||||
|
vmovdqa (%rdx),%ymm10
|
||||||
|
vmovdqa 32(%rdx),%ymm12
|
||||||
|
vmovdqa 64(%rdx),%ymm14
|
||||||
|
vpsrlq $32,%ymm2,%ymm3
|
||||||
|
vpsrlq $32,%ymm4,%ymm5
|
||||||
|
vmovshdup %ymm6,%ymm7
|
||||||
|
vpsrlq $32,%ymm10,%ymm11
|
||||||
|
vpsrlq $32,%ymm12,%ymm13
|
||||||
|
vmovshdup %ymm14,%ymm15
|
||||||
|
|
||||||
|
#mul
|
||||||
|
vpmuldq %ymm2,%ymm10,%ymm2
|
||||||
|
vpmuldq %ymm3,%ymm11,%ymm3
|
||||||
|
vpmuldq %ymm4,%ymm12,%ymm4
|
||||||
|
vpmuldq %ymm5,%ymm13,%ymm5
|
||||||
|
vpmuldq %ymm6,%ymm14,%ymm6
|
||||||
|
vpmuldq %ymm7,%ymm15,%ymm7
|
||||||
|
|
||||||
|
#reduce
|
||||||
|
vpmuldq %ymm0,%ymm2,%ymm10
|
||||||
|
vpmuldq %ymm0,%ymm3,%ymm11
|
||||||
|
vpmuldq %ymm0,%ymm4,%ymm12
|
||||||
|
vpmuldq %ymm0,%ymm5,%ymm13
|
||||||
|
vpmuldq %ymm0,%ymm6,%ymm14
|
||||||
|
vpmuldq %ymm0,%ymm7,%ymm15
|
||||||
|
vpmuldq %ymm1,%ymm10,%ymm10
|
||||||
|
vpmuldq %ymm1,%ymm11,%ymm11
|
||||||
|
vpmuldq %ymm1,%ymm12,%ymm12
|
||||||
|
vpmuldq %ymm1,%ymm13,%ymm13
|
||||||
|
vpmuldq %ymm1,%ymm14,%ymm14
|
||||||
|
vpmuldq %ymm1,%ymm15,%ymm15
|
||||||
|
vpsubq %ymm10,%ymm2,%ymm2
|
||||||
|
vpsubq %ymm11,%ymm3,%ymm3
|
||||||
|
vpsubq %ymm12,%ymm4,%ymm4
|
||||||
|
vpsubq %ymm13,%ymm5,%ymm5
|
||||||
|
vpsubq %ymm14,%ymm6,%ymm6
|
||||||
|
vpsubq %ymm15,%ymm7,%ymm7
|
||||||
|
vpsrlq $32,%ymm2,%ymm2
|
||||||
|
vpsrlq $32,%ymm4,%ymm4
|
||||||
|
vmovshdup %ymm6,%ymm6
|
||||||
|
|
||||||
|
#store
|
||||||
|
vpblendd $0xAA,%ymm3,%ymm2,%ymm2
|
||||||
|
vpblendd $0xAA,%ymm5,%ymm4,%ymm4
|
||||||
|
vpblendd $0xAA,%ymm7,%ymm6,%ymm6
|
||||||
|
vmovdqa %ymm2,(%rdi)
|
||||||
|
vmovdqa %ymm4,32(%rdi)
|
||||||
|
vmovdqa %ymm6,64(%rdi)
|
||||||
|
|
||||||
|
add $96,%rdi
|
||||||
|
add $96,%rsi
|
||||||
|
add $96,%rdx
|
||||||
|
add $1,%eax
|
||||||
|
cmp $10,%eax
|
||||||
|
jb _looptop1
|
||||||
|
|
||||||
|
vmovdqa (%rsi),%ymm2
|
||||||
|
vmovdqa 32(%rsi),%ymm4
|
||||||
|
vmovdqa (%rdx),%ymm10
|
||||||
|
vmovdqa 32(%rdx),%ymm12
|
||||||
|
vpsrlq $32,%ymm2,%ymm3
|
||||||
|
vpsrlq $32,%ymm4,%ymm5
|
||||||
|
vmovshdup %ymm10,%ymm11
|
||||||
|
vmovshdup %ymm12,%ymm13
|
||||||
|
|
||||||
|
#mul
|
||||||
|
vpmuldq %ymm2,%ymm10,%ymm2
|
||||||
|
vpmuldq %ymm3,%ymm11,%ymm3
|
||||||
|
vpmuldq %ymm4,%ymm12,%ymm4
|
||||||
|
vpmuldq %ymm5,%ymm13,%ymm5
|
||||||
|
|
||||||
|
#reduce
|
||||||
|
vpmuldq %ymm0,%ymm2,%ymm10
|
||||||
|
vpmuldq %ymm0,%ymm3,%ymm11
|
||||||
|
vpmuldq %ymm0,%ymm4,%ymm12
|
||||||
|
vpmuldq %ymm0,%ymm5,%ymm13
|
||||||
|
vpmuldq %ymm1,%ymm10,%ymm10
|
||||||
|
vpmuldq %ymm1,%ymm11,%ymm11
|
||||||
|
vpmuldq %ymm1,%ymm12,%ymm12
|
||||||
|
vpmuldq %ymm1,%ymm13,%ymm13
|
||||||
|
vpsubq %ymm10,%ymm2,%ymm2
|
||||||
|
vpsubq %ymm11,%ymm3,%ymm3
|
||||||
|
vpsubq %ymm12,%ymm4,%ymm4
|
||||||
|
vpsubq %ymm13,%ymm5,%ymm5
|
||||||
|
vpsrlq $32,%ymm2,%ymm2
|
||||||
|
vmovshdup %ymm4,%ymm4
|
||||||
|
|
||||||
|
#store
|
||||||
|
vpblendd $0x55,%ymm2,%ymm3,%ymm2
|
||||||
|
vpblendd $0x55,%ymm4,%ymm5,%ymm4
|
||||||
|
vmovdqa %ymm2,(%rdi)
|
||||||
|
vmovdqa %ymm4,32(%rdi)
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
.macro pointwise off
|
||||||
|
#load
|
||||||
|
vmovdqa \off(%rsi),%ymm6
|
||||||
|
vmovdqa \off+32(%rsi),%ymm8
|
||||||
|
vmovdqa \off(%rdx),%ymm10
|
||||||
|
vmovdqa \off+32(%rdx),%ymm12
|
||||||
|
vpsrlq $32,%ymm6,%ymm7
|
||||||
|
vpsrlq $32,%ymm8,%ymm9
|
||||||
|
vmovshdup %ymm10,%ymm11
|
||||||
|
vmovshdup %ymm12,%ymm13
|
||||||
|
|
||||||
|
#mul
|
||||||
|
vpmuldq %ymm6,%ymm10,%ymm6
|
||||||
|
vpmuldq %ymm7,%ymm11,%ymm7
|
||||||
|
vpmuldq %ymm8,%ymm12,%ymm8
|
||||||
|
vpmuldq %ymm9,%ymm13,%ymm9
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro acc
|
||||||
|
vpaddq %ymm6,%ymm2,%ymm2
|
||||||
|
vpaddq %ymm7,%ymm3,%ymm3
|
||||||
|
vpaddq %ymm8,%ymm4,%ymm4
|
||||||
|
vpaddq %ymm9,%ymm5,%ymm5
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.global cdecl(pointwise_acc_avx)
|
||||||
|
cdecl(pointwise_acc_avx):
|
||||||
|
#consts
|
||||||
|
vmovdqa _8XQINV*4(%rcx),%ymm0
|
||||||
|
vmovdqa _8XQ*4(%rcx),%ymm1
|
||||||
|
|
||||||
|
xor %eax,%eax
|
||||||
|
_looptop2:
|
||||||
|
pointwise 0
|
||||||
|
|
||||||
|
#mov
|
||||||
|
vmovdqa %ymm6,%ymm2
|
||||||
|
vmovdqa %ymm7,%ymm3
|
||||||
|
vmovdqa %ymm8,%ymm4
|
||||||
|
vmovdqa %ymm9,%ymm5
|
||||||
|
|
||||||
|
pointwise 1024
|
||||||
|
acc
|
||||||
|
|
||||||
|
#if L >= 3
|
||||||
|
pointwise 2048
|
||||||
|
acc
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if L >= 4
|
||||||
|
pointwise 3072
|
||||||
|
acc
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if L >= 5
|
||||||
|
pointwise 4096
|
||||||
|
acc
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if L >= 6
|
||||||
|
pointwise 5120
|
||||||
|
acc
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if L >= 7
|
||||||
|
pointwise 6144
|
||||||
|
acc
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#reduce
|
||||||
|
vpmuldq %ymm0,%ymm2,%ymm6
|
||||||
|
vpmuldq %ymm0,%ymm3,%ymm7
|
||||||
|
vpmuldq %ymm0,%ymm4,%ymm8
|
||||||
|
vpmuldq %ymm0,%ymm5,%ymm9
|
||||||
|
vpmuldq %ymm1,%ymm6,%ymm6
|
||||||
|
vpmuldq %ymm1,%ymm7,%ymm7
|
||||||
|
vpmuldq %ymm1,%ymm8,%ymm8
|
||||||
|
vpmuldq %ymm1,%ymm9,%ymm9
|
||||||
|
vpsubq %ymm6,%ymm2,%ymm2
|
||||||
|
vpsubq %ymm7,%ymm3,%ymm3
|
||||||
|
vpsubq %ymm8,%ymm4,%ymm4
|
||||||
|
vpsubq %ymm9,%ymm5,%ymm5
|
||||||
|
vpsrlq $32,%ymm2,%ymm2
|
||||||
|
vmovshdup %ymm4,%ymm4
|
||||||
|
|
||||||
|
#store
|
||||||
|
vpblendd $0xAA,%ymm3,%ymm2,%ymm2
|
||||||
|
vpblendd $0xAA,%ymm5,%ymm4,%ymm4
|
||||||
|
|
||||||
|
vmovdqa %ymm2,(%rdi)
|
||||||
|
vmovdqa %ymm4,32(%rdi)
|
||||||
|
|
||||||
|
add $64,%rsi
|
||||||
|
add $64,%rdx
|
||||||
|
add $64,%rdi
|
||||||
|
add $1,%eax
|
||||||
|
cmp $16,%eax
|
||||||
|
jb _looptop2
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
.section .note.GNU-stack,"",@progbits
|
||||||
1128
src/crypto/pq/_d/avx2/poly.c
Normal file
1128
src/crypto/pq/_d/avx2/poly.c
Normal file
File diff suppressed because it is too large
Load diff
112
src/crypto/pq/_d/avx2/poly.h
Normal file
112
src/crypto/pq/_d/avx2/poly.h
Normal file
|
|
@ -0,0 +1,112 @@
|
||||||
|
#ifndef POLY_H
|
||||||
|
#define POLY_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "align.h"
|
||||||
|
#include "params.h"
|
||||||
|
#include "symmetric.h"
|
||||||
|
|
||||||
|
typedef ALIGNED_INT32(N) poly;
|
||||||
|
|
||||||
|
#define poly_reduce DILITHIUM_NAMESPACE(poly_reduce)
|
||||||
|
void poly_reduce(poly *a);
|
||||||
|
#define poly_caddq DILITHIUM_NAMESPACE(poly_caddq)
|
||||||
|
void poly_caddq(poly *a);
|
||||||
|
|
||||||
|
#define poly_add DILITHIUM_NAMESPACE(poly_add)
|
||||||
|
void poly_add(poly *c, const poly *a, const poly *b);
|
||||||
|
#define poly_sub DILITHIUM_NAMESPACE(poly_sub)
|
||||||
|
void poly_sub(poly *c, const poly *a, const poly *b);
|
||||||
|
#define poly_shiftl DILITHIUM_NAMESPACE(poly_shiftl)
|
||||||
|
void poly_shiftl(poly *a);
|
||||||
|
|
||||||
|
#define poly_ntt DILITHIUM_NAMESPACE(poly_ntt)
|
||||||
|
void poly_ntt(poly *a);
|
||||||
|
#define poly_invntt_tomont DILITHIUM_NAMESPACE(poly_invntt_tomont)
|
||||||
|
void poly_invntt_tomont(poly *a);
|
||||||
|
#define poly_nttunpack DILITHIUM_NAMESPACE(poly_nttunpack)
|
||||||
|
void poly_nttunpack(poly *a);
|
||||||
|
#define poly_pointwise_montgomery DILITHIUM_NAMESPACE(poly_pointwise_montgomery)
|
||||||
|
void poly_pointwise_montgomery(poly *c, const poly *a, const poly *b);
|
||||||
|
|
||||||
|
#define poly_power2round DILITHIUM_NAMESPACE(poly_power2round)
|
||||||
|
void poly_power2round(poly *a1, poly *a0, const poly *a);
|
||||||
|
#define poly_decompose DILITHIUM_NAMESPACE(poly_decompose)
|
||||||
|
void poly_decompose(poly *a1, poly *a0, const poly *a);
|
||||||
|
#define poly_make_hint DILITHIUM_NAMESPACE(poly_make_hint)
|
||||||
|
unsigned int poly_make_hint(uint8_t hint[N], const poly *a0, const poly *a1);
|
||||||
|
#define poly_use_hint DILITHIUM_NAMESPACE(poly_use_hint)
|
||||||
|
void poly_use_hint(poly *b, const poly *a, const poly *h);
|
||||||
|
|
||||||
|
#define poly_chknorm DILITHIUM_NAMESPACE(poly_chknorm)
|
||||||
|
int poly_chknorm(const poly *a, int32_t B);
|
||||||
|
#define poly_uniform_preinit DILITHIUM_NAMESPACE(poly_uniform_preinit)
|
||||||
|
void poly_uniform_preinit(poly *a, stream128_state *state);
|
||||||
|
#define poly_uniform DILITHIUM_NAMESPACE(poly_uniform)
|
||||||
|
void poly_uniform(poly *a, const uint8_t seed[SEEDBYTES], uint16_t nonce);
|
||||||
|
#define poly_uniform_eta_preinit DILITHIUM_NAMESPACE(poly_uniform_eta_preinit)
|
||||||
|
void poly_uniform_eta_preinit(poly *a, stream256_state *state);
|
||||||
|
#define poly_uniform_eta DILITHIUM_NAMESPACE(poly_uniform_eta)
|
||||||
|
void poly_uniform_eta(poly *a, const uint8_t seed[CRHBYTES], uint16_t nonce);
|
||||||
|
#define poly_uniform_gamma1_preinit DILITHIUM_NAMESPACE(poly_uniform_gamma1_preinit)
|
||||||
|
void poly_uniform_gamma1_preinit(poly *a, stream256_state *state);
|
||||||
|
#define poly_uniform_gamma1 DILITHIUM_NAMESPACE(poly_uniform_gamma1)
|
||||||
|
void poly_uniform_gamma1(poly *a, const uint8_t seed[CRHBYTES], uint16_t nonce);
|
||||||
|
#define poly_challenge DILITHIUM_NAMESPACE(poly_challenge)
|
||||||
|
void poly_challenge(poly *c, const uint8_t seed[CTILDEBYTES]);
|
||||||
|
|
||||||
|
#define poly_uniform_4x DILITHIUM_NAMESPACE(poly_uniform_4x)
|
||||||
|
void poly_uniform_4x(poly *a0,
|
||||||
|
poly *a1,
|
||||||
|
poly *a2,
|
||||||
|
poly *a3,
|
||||||
|
const uint8_t seed[SEEDBYTES],
|
||||||
|
uint16_t nonce0,
|
||||||
|
uint16_t nonce1,
|
||||||
|
uint16_t nonce2,
|
||||||
|
uint16_t nonce3);
|
||||||
|
#define poly_uniform_eta_4x DILITHIUM_NAMESPACE(poly_uniform_eta_4x)
|
||||||
|
void poly_uniform_eta_4x(poly *a0,
|
||||||
|
poly *a1,
|
||||||
|
poly *a2,
|
||||||
|
poly *a3,
|
||||||
|
const uint8_t seed[CRHBYTES],
|
||||||
|
uint16_t nonce0,
|
||||||
|
uint16_t nonce1,
|
||||||
|
uint16_t nonce2,
|
||||||
|
uint16_t nonce3);
|
||||||
|
#define poly_uniform_gamma1_4x DILITHIUM_NAMESPACE(poly_uniform_gamma1_4x)
|
||||||
|
void poly_uniform_gamma1_4x(poly *a0,
|
||||||
|
poly *a1,
|
||||||
|
poly *a2,
|
||||||
|
poly *a3,
|
||||||
|
const uint8_t seed[CRHBYTES],
|
||||||
|
uint16_t nonce0,
|
||||||
|
uint16_t nonce1,
|
||||||
|
uint16_t nonce2,
|
||||||
|
uint16_t nonce3);
|
||||||
|
|
||||||
|
#define polyeta_pack DILITHIUM_NAMESPACE(polyeta_pack)
|
||||||
|
void polyeta_pack(uint8_t r[POLYETA_PACKEDBYTES], const poly *a);
|
||||||
|
#define polyeta_unpack DILITHIUM_NAMESPACE(polyeta_unpack)
|
||||||
|
void polyeta_unpack(poly *r, const uint8_t a[POLYETA_PACKEDBYTES]);
|
||||||
|
|
||||||
|
#define polyt1_pack DILITHIUM_NAMESPACE(polyt1_pack)
|
||||||
|
void polyt1_pack(uint8_t r[POLYT1_PACKEDBYTES], const poly *a);
|
||||||
|
#define polyt1_unpack DILITHIUM_NAMESPACE(polyt1_unpack)
|
||||||
|
void polyt1_unpack(poly *r, const uint8_t a[POLYT1_PACKEDBYTES]);
|
||||||
|
|
||||||
|
#define polyt0_pack DILITHIUM_NAMESPACE(polyt0_pack)
|
||||||
|
void polyt0_pack(uint8_t r[POLYT0_PACKEDBYTES], const poly *a);
|
||||||
|
#define polyt0_unpack DILITHIUM_NAMESPACE(polyt0_unpack)
|
||||||
|
void polyt0_unpack(poly *r, const uint8_t a[POLYT0_PACKEDBYTES]);
|
||||||
|
|
||||||
|
#define polyz_pack DILITHIUM_NAMESPACE(polyz_pack)
|
||||||
|
void polyz_pack(uint8_t r[POLYZ_PACKEDBYTES], const poly *a);
|
||||||
|
#define polyz_unpack DILITHIUM_NAMESPACE(polyz_unpack)
|
||||||
|
void polyz_unpack(poly *r, const uint8_t *a);
|
||||||
|
|
||||||
|
#define polyw1_pack DILITHIUM_NAMESPACE(polyw1_pack)
|
||||||
|
void polyw1_pack(uint8_t *r, const poly *a);
|
||||||
|
|
||||||
|
#endif
|
||||||
588
src/crypto/pq/_d/avx2/polyvec.c
Normal file
588
src/crypto/pq/_d/avx2/polyvec.c
Normal file
|
|
@ -0,0 +1,588 @@
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "params.h"
|
||||||
|
#include "polyvec.h"
|
||||||
|
#include "poly.h"
|
||||||
|
#include "ntt.h"
|
||||||
|
#include "consts.h"
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: expand_mat
|
||||||
|
*
|
||||||
|
* Description: Implementation of ExpandA. Generates matrix A with uniformly
|
||||||
|
* random coefficients a_{i,j} by performing rejection
|
||||||
|
* sampling on the output stream of SHAKE128(rho|j|i)
|
||||||
|
*
|
||||||
|
* Arguments: - polyvecl mat[K]: output matrix
|
||||||
|
* - const uint8_t rho[]: byte array containing seed rho
|
||||||
|
**************************************************/
|
||||||
|
|
||||||
|
#if K == 4 && L == 4
|
||||||
|
void polyvec_matrix_expand(polyvecl mat[K], const uint8_t rho[SEEDBYTES]) {
|
||||||
|
polyvec_matrix_expand_row0(&mat[0], NULL, rho);
|
||||||
|
polyvec_matrix_expand_row1(&mat[1], NULL, rho);
|
||||||
|
polyvec_matrix_expand_row2(&mat[2], NULL, rho);
|
||||||
|
polyvec_matrix_expand_row3(&mat[3], NULL, rho);
|
||||||
|
}
|
||||||
|
|
||||||
|
void polyvec_matrix_expand_row0(polyvecl *rowa, __attribute__((unused)) polyvecl *rowb, const uint8_t rho[SEEDBYTES]) {
|
||||||
|
poly_uniform_4x(&rowa->vec[0], &rowa->vec[1], &rowa->vec[2], &rowa->vec[3], rho, 0, 1, 2, 3);
|
||||||
|
poly_nttunpack(&rowa->vec[0]);
|
||||||
|
poly_nttunpack(&rowa->vec[1]);
|
||||||
|
poly_nttunpack(&rowa->vec[2]);
|
||||||
|
poly_nttunpack(&rowa->vec[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void polyvec_matrix_expand_row1(polyvecl *rowa, __attribute__((unused)) polyvecl *rowb, const uint8_t rho[SEEDBYTES]) {
|
||||||
|
poly_uniform_4x(&rowa->vec[0], &rowa->vec[1], &rowa->vec[2], &rowa->vec[3], rho, 256, 257, 258, 259);
|
||||||
|
poly_nttunpack(&rowa->vec[0]);
|
||||||
|
poly_nttunpack(&rowa->vec[1]);
|
||||||
|
poly_nttunpack(&rowa->vec[2]);
|
||||||
|
poly_nttunpack(&rowa->vec[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void polyvec_matrix_expand_row2(polyvecl *rowa, __attribute__((unused)) polyvecl *rowb, const uint8_t rho[SEEDBYTES]) {
|
||||||
|
poly_uniform_4x(&rowa->vec[0], &rowa->vec[1], &rowa->vec[2], &rowa->vec[3], rho, 512, 513, 514, 515);
|
||||||
|
poly_nttunpack(&rowa->vec[0]);
|
||||||
|
poly_nttunpack(&rowa->vec[1]);
|
||||||
|
poly_nttunpack(&rowa->vec[2]);
|
||||||
|
poly_nttunpack(&rowa->vec[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void polyvec_matrix_expand_row3(polyvecl *rowa, __attribute__((unused)) polyvecl *rowb, const uint8_t rho[SEEDBYTES]) {
|
||||||
|
poly_uniform_4x(&rowa->vec[0], &rowa->vec[1], &rowa->vec[2], &rowa->vec[3], rho, 768, 769, 770, 771);
|
||||||
|
poly_nttunpack(&rowa->vec[0]);
|
||||||
|
poly_nttunpack(&rowa->vec[1]);
|
||||||
|
poly_nttunpack(&rowa->vec[2]);
|
||||||
|
poly_nttunpack(&rowa->vec[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif K == 6 && L == 5
|
||||||
|
void polyvec_matrix_expand(polyvecl mat[K], const uint8_t rho[SEEDBYTES]) {
|
||||||
|
polyvecl tmp;
|
||||||
|
polyvec_matrix_expand_row0(&mat[0], &mat[1], rho);
|
||||||
|
polyvec_matrix_expand_row1(&mat[1], &mat[2], rho);
|
||||||
|
polyvec_matrix_expand_row2(&mat[2], &mat[3], rho);
|
||||||
|
polyvec_matrix_expand_row3(&mat[3], NULL, rho);
|
||||||
|
polyvec_matrix_expand_row4(&mat[4], &mat[5], rho);
|
||||||
|
polyvec_matrix_expand_row5(&mat[5], &tmp, rho);
|
||||||
|
}
|
||||||
|
|
||||||
|
void polyvec_matrix_expand_row0(polyvecl *rowa, polyvecl *rowb, const uint8_t rho[SEEDBYTES]) {
|
||||||
|
poly_uniform_4x(&rowa->vec[0], &rowa->vec[1], &rowa->vec[2], &rowa->vec[3], rho, 0, 1, 2, 3);
|
||||||
|
poly_uniform_4x(&rowa->vec[4], &rowb->vec[0], &rowb->vec[1], &rowb->vec[2], rho, 4, 256, 257, 258);
|
||||||
|
poly_nttunpack(&rowa->vec[0]);
|
||||||
|
poly_nttunpack(&rowa->vec[1]);
|
||||||
|
poly_nttunpack(&rowa->vec[2]);
|
||||||
|
poly_nttunpack(&rowa->vec[3]);
|
||||||
|
poly_nttunpack(&rowa->vec[4]);
|
||||||
|
poly_nttunpack(&rowb->vec[0]);
|
||||||
|
poly_nttunpack(&rowb->vec[1]);
|
||||||
|
poly_nttunpack(&rowb->vec[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void polyvec_matrix_expand_row1(polyvecl *rowa, polyvecl *rowb, const uint8_t rho[SEEDBYTES]) {
|
||||||
|
poly_uniform_4x(&rowa->vec[3], &rowa->vec[4], &rowb->vec[0], &rowb->vec[1], rho, 259, 260, 512, 513);
|
||||||
|
poly_nttunpack(&rowa->vec[3]);
|
||||||
|
poly_nttunpack(&rowa->vec[4]);
|
||||||
|
poly_nttunpack(&rowb->vec[0]);
|
||||||
|
poly_nttunpack(&rowb->vec[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void polyvec_matrix_expand_row2(polyvecl *rowa, polyvecl *rowb, const uint8_t rho[SEEDBYTES]) {
|
||||||
|
poly_uniform_4x(&rowa->vec[2], &rowa->vec[3], &rowa->vec[4], &rowb->vec[0], rho, 514, 515, 516, 768);
|
||||||
|
poly_nttunpack(&rowa->vec[2]);
|
||||||
|
poly_nttunpack(&rowa->vec[3]);
|
||||||
|
poly_nttunpack(&rowa->vec[4]);
|
||||||
|
poly_nttunpack(&rowb->vec[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void polyvec_matrix_expand_row3(polyvecl *rowa, __attribute__((unused)) polyvecl *rowb, const uint8_t rho[SEEDBYTES]) {
|
||||||
|
poly_uniform_4x(&rowa->vec[1], &rowa->vec[2], &rowa->vec[3], &rowa->vec[4], rho, 769, 770, 771, 772);
|
||||||
|
poly_nttunpack(&rowa->vec[1]);
|
||||||
|
poly_nttunpack(&rowa->vec[2]);
|
||||||
|
poly_nttunpack(&rowa->vec[3]);
|
||||||
|
poly_nttunpack(&rowa->vec[4]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void polyvec_matrix_expand_row4(polyvecl *rowa, polyvecl *rowb, const uint8_t rho[SEEDBYTES]) {
|
||||||
|
poly_uniform_4x(&rowa->vec[0], &rowa->vec[1], &rowa->vec[2], &rowa->vec[3], rho, 1024, 1025, 1026, 1027);
|
||||||
|
poly_uniform_4x(&rowa->vec[4], &rowb->vec[0], &rowb->vec[1], &rowb->vec[2], rho, 1028, 1280, 1281, 1282);
|
||||||
|
poly_nttunpack(&rowa->vec[0]);
|
||||||
|
poly_nttunpack(&rowa->vec[1]);
|
||||||
|
poly_nttunpack(&rowa->vec[2]);
|
||||||
|
poly_nttunpack(&rowa->vec[3]);
|
||||||
|
poly_nttunpack(&rowa->vec[4]);
|
||||||
|
poly_nttunpack(&rowb->vec[0]);
|
||||||
|
poly_nttunpack(&rowb->vec[1]);
|
||||||
|
poly_nttunpack(&rowb->vec[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void polyvec_matrix_expand_row5(polyvecl *rowa, polyvecl *rowb, const uint8_t rho[SEEDBYTES]) {
|
||||||
|
poly_uniform_4x(&rowa->vec[3], &rowa->vec[4], &rowb->vec[0], &rowb->vec[1], rho, 1283, 1284, 1536, 1537);
|
||||||
|
poly_nttunpack(&rowa->vec[3]);
|
||||||
|
poly_nttunpack(&rowa->vec[4]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif K == 8 && L == 7
|
||||||
|
void polyvec_matrix_expand(polyvecl mat[K], const uint8_t rho[SEEDBYTES]) {
|
||||||
|
polyvec_matrix_expand_row0(&mat[0], &mat[1], rho);
|
||||||
|
polyvec_matrix_expand_row1(&mat[1], &mat[2], rho);
|
||||||
|
polyvec_matrix_expand_row2(&mat[2], &mat[3], rho);
|
||||||
|
polyvec_matrix_expand_row3(&mat[3], NULL, rho);
|
||||||
|
polyvec_matrix_expand_row4(&mat[4], &mat[5], rho);
|
||||||
|
polyvec_matrix_expand_row5(&mat[5], &mat[6], rho);
|
||||||
|
polyvec_matrix_expand_row6(&mat[6], &mat[7], rho);
|
||||||
|
polyvec_matrix_expand_row7(&mat[7], NULL, rho);
|
||||||
|
}
|
||||||
|
|
||||||
|
void polyvec_matrix_expand_row0(polyvecl *rowa, polyvecl *rowb, const uint8_t rho[SEEDBYTES]) {
|
||||||
|
poly_uniform_4x(&rowa->vec[0], &rowa->vec[1], &rowa->vec[2], &rowa->vec[3], rho, 0, 1, 2, 3);
|
||||||
|
poly_uniform_4x(&rowa->vec[4], &rowa->vec[5], &rowa->vec[6], &rowb->vec[0], rho, 4, 5, 6, 256);
|
||||||
|
poly_nttunpack(&rowa->vec[0]);
|
||||||
|
poly_nttunpack(&rowa->vec[1]);
|
||||||
|
poly_nttunpack(&rowa->vec[2]);
|
||||||
|
poly_nttunpack(&rowa->vec[3]);
|
||||||
|
poly_nttunpack(&rowa->vec[4]);
|
||||||
|
poly_nttunpack(&rowa->vec[5]);
|
||||||
|
poly_nttunpack(&rowa->vec[6]);
|
||||||
|
poly_nttunpack(&rowb->vec[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void polyvec_matrix_expand_row1(polyvecl *rowa, polyvecl *rowb, const uint8_t rho[SEEDBYTES]) {
|
||||||
|
poly_uniform_4x(&rowa->vec[1], &rowa->vec[2], &rowa->vec[3], &rowa->vec[4], rho, 257, 258, 259, 260);
|
||||||
|
poly_uniform_4x(&rowa->vec[5], &rowa->vec[6], &rowb->vec[0], &rowb->vec[1], rho, 261, 262, 512, 513);
|
||||||
|
poly_nttunpack(&rowa->vec[1]);
|
||||||
|
poly_nttunpack(&rowa->vec[2]);
|
||||||
|
poly_nttunpack(&rowa->vec[3]);
|
||||||
|
poly_nttunpack(&rowa->vec[4]);
|
||||||
|
poly_nttunpack(&rowa->vec[5]);
|
||||||
|
poly_nttunpack(&rowa->vec[6]);
|
||||||
|
poly_nttunpack(&rowb->vec[0]);
|
||||||
|
poly_nttunpack(&rowb->vec[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void polyvec_matrix_expand_row2(polyvecl *rowa, polyvecl *rowb, const uint8_t rho[SEEDBYTES]) {
|
||||||
|
poly_uniform_4x(&rowa->vec[2], &rowa->vec[3], &rowa->vec[4], &rowa->vec[5], rho, 514, 515, 516, 517);
|
||||||
|
poly_uniform_4x(&rowa->vec[6], &rowb->vec[0], &rowb->vec[1], &rowb->vec[2], rho, 518, 768, 769, 770);
|
||||||
|
poly_nttunpack(&rowa->vec[2]);
|
||||||
|
poly_nttunpack(&rowa->vec[3]);
|
||||||
|
poly_nttunpack(&rowa->vec[4]);
|
||||||
|
poly_nttunpack(&rowa->vec[5]);
|
||||||
|
poly_nttunpack(&rowa->vec[6]);
|
||||||
|
poly_nttunpack(&rowb->vec[0]);
|
||||||
|
poly_nttunpack(&rowb->vec[1]);
|
||||||
|
poly_nttunpack(&rowb->vec[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void polyvec_matrix_expand_row3(polyvecl *rowa, __attribute__((unused)) polyvecl *rowb, const uint8_t rho[SEEDBYTES]) {
|
||||||
|
poly_uniform_4x(&rowa->vec[3], &rowa->vec[4], &rowa->vec[5], &rowa->vec[6], rho, 771, 772, 773, 774);
|
||||||
|
poly_nttunpack(&rowa->vec[3]);
|
||||||
|
poly_nttunpack(&rowa->vec[4]);
|
||||||
|
poly_nttunpack(&rowa->vec[5]);
|
||||||
|
poly_nttunpack(&rowa->vec[6]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void polyvec_matrix_expand_row4(polyvecl *rowa, polyvecl *rowb, const uint8_t rho[SEEDBYTES]) {
|
||||||
|
poly_uniform_4x(&rowa->vec[0], &rowa->vec[1], &rowa->vec[2], &rowa->vec[3], rho, 1024, 1025, 1026, 1027);
|
||||||
|
poly_uniform_4x(&rowa->vec[4], &rowa->vec[5], &rowa->vec[6], &rowb->vec[0], rho, 1028, 1029, 1030, 1280);
|
||||||
|
poly_nttunpack(&rowa->vec[0]);
|
||||||
|
poly_nttunpack(&rowa->vec[1]);
|
||||||
|
poly_nttunpack(&rowa->vec[2]);
|
||||||
|
poly_nttunpack(&rowa->vec[3]);
|
||||||
|
poly_nttunpack(&rowa->vec[4]);
|
||||||
|
poly_nttunpack(&rowa->vec[5]);
|
||||||
|
poly_nttunpack(&rowa->vec[6]);
|
||||||
|
poly_nttunpack(&rowb->vec[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void polyvec_matrix_expand_row5(polyvecl *rowa, polyvecl *rowb, const uint8_t rho[SEEDBYTES]) {
|
||||||
|
poly_uniform_4x(&rowa->vec[1], &rowa->vec[2], &rowa->vec[3], &rowa->vec[4], rho, 1281, 1282, 1283, 1284);
|
||||||
|
poly_uniform_4x(&rowa->vec[5], &rowa->vec[6], &rowb->vec[0], &rowb->vec[1], rho, 1285, 1286, 1536, 1537);
|
||||||
|
poly_nttunpack(&rowa->vec[1]);
|
||||||
|
poly_nttunpack(&rowa->vec[2]);
|
||||||
|
poly_nttunpack(&rowa->vec[3]);
|
||||||
|
poly_nttunpack(&rowa->vec[4]);
|
||||||
|
poly_nttunpack(&rowa->vec[5]);
|
||||||
|
poly_nttunpack(&rowa->vec[6]);
|
||||||
|
poly_nttunpack(&rowb->vec[0]);
|
||||||
|
poly_nttunpack(&rowb->vec[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void polyvec_matrix_expand_row6(polyvecl *rowa, polyvecl *rowb, const uint8_t rho[SEEDBYTES]) {
|
||||||
|
poly_uniform_4x(&rowa->vec[2], &rowa->vec[3], &rowa->vec[4], &rowa->vec[5], rho, 1538, 1539, 1540, 1541);
|
||||||
|
poly_uniform_4x(&rowa->vec[6], &rowb->vec[0], &rowb->vec[1], &rowb->vec[2], rho, 1542, 1792, 1793, 1794);
|
||||||
|
poly_nttunpack(&rowa->vec[2]);
|
||||||
|
poly_nttunpack(&rowa->vec[3]);
|
||||||
|
poly_nttunpack(&rowa->vec[4]);
|
||||||
|
poly_nttunpack(&rowa->vec[5]);
|
||||||
|
poly_nttunpack(&rowa->vec[6]);
|
||||||
|
poly_nttunpack(&rowb->vec[0]);
|
||||||
|
poly_nttunpack(&rowb->vec[1]);
|
||||||
|
poly_nttunpack(&rowb->vec[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void polyvec_matrix_expand_row7(polyvecl *rowa, __attribute__((unused)) polyvecl *rowb, const uint8_t rho[SEEDBYTES]) {
|
||||||
|
poly_uniform_4x(&rowa->vec[3], &rowa->vec[4], &rowa->vec[5], &rowa->vec[6], rho, 1795, 1796, 1797, 1798);
|
||||||
|
poly_nttunpack(&rowa->vec[3]);
|
||||||
|
poly_nttunpack(&rowa->vec[4]);
|
||||||
|
poly_nttunpack(&rowa->vec[5]);
|
||||||
|
poly_nttunpack(&rowa->vec[6]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
#error
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void polyvec_matrix_pointwise_montgomery(polyveck *t, const polyvecl mat[K], const polyvecl *v) {
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for(i = 0; i < K; ++i)
|
||||||
|
polyvecl_pointwise_acc_montgomery(&t->vec[i], &mat[i], v);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************************************************/
|
||||||
|
/************ Vectors of polynomials of length L **************/
|
||||||
|
/**************************************************************/
|
||||||
|
|
||||||
|
void polyvecl_uniform_eta(polyvecl *v, const uint8_t seed[CRHBYTES], uint16_t nonce) {
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for(i = 0; i < L; ++i)
|
||||||
|
poly_uniform_eta(&v->vec[i], seed, nonce++);
|
||||||
|
}
|
||||||
|
|
||||||
|
void polyvecl_uniform_gamma1(polyvecl *v, const uint8_t seed[CRHBYTES], uint16_t nonce) {
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for(i = 0; i < L; ++i)
|
||||||
|
poly_uniform_gamma1(&v->vec[i], seed, L*nonce + i);
|
||||||
|
}
|
||||||
|
|
||||||
|
void polyvecl_reduce(polyvecl *v) {
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for(i = 0; i < L; ++i)
|
||||||
|
poly_reduce(&v->vec[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: polyvecl_add
|
||||||
|
*
|
||||||
|
* Description: Add vectors of polynomials of length L.
|
||||||
|
* No modular reduction is performed.
|
||||||
|
*
|
||||||
|
* Arguments: - polyvecl *w: pointer to output vector
|
||||||
|
* - const polyvecl *u: pointer to first summand
|
||||||
|
* - const polyvecl *v: pointer to second summand
|
||||||
|
**************************************************/
|
||||||
|
void polyvecl_add(polyvecl *w, const polyvecl *u, const polyvecl *v) {
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for(i = 0; i < L; ++i)
|
||||||
|
poly_add(&w->vec[i], &u->vec[i], &v->vec[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: polyvecl_ntt
|
||||||
|
*
|
||||||
|
* Description: Forward NTT of all polynomials in vector of length L. Output
|
||||||
|
* coefficients can be up to 16*Q larger than input coefficients.
|
||||||
|
*
|
||||||
|
* Arguments: - polyvecl *v: pointer to input/output vector
|
||||||
|
**************************************************/
|
||||||
|
void polyvecl_ntt(polyvecl *v) {
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for(i = 0; i < L; ++i)
|
||||||
|
poly_ntt(&v->vec[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void polyvecl_invntt_tomont(polyvecl *v) {
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for(i = 0; i < L; ++i)
|
||||||
|
poly_invntt_tomont(&v->vec[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void polyvecl_pointwise_poly_montgomery(polyvecl *r, const poly *a, const polyvecl *v) {
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for(i = 0; i < L; ++i)
|
||||||
|
poly_pointwise_montgomery(&r->vec[i], a, &v->vec[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: polyvecl_pointwise_acc_montgomery
|
||||||
|
*
|
||||||
|
* Description: Pointwise multiply vectors of polynomials of length L, multiply
|
||||||
|
* resulting vector by 2^{-32} and add (accumulate) polynomials
|
||||||
|
* in it. Input/output vectors are in NTT domain representation.
|
||||||
|
*
|
||||||
|
* Arguments: - poly *w: output polynomial
|
||||||
|
* - const polyvecl *u: pointer to first input vector
|
||||||
|
* - const polyvecl *v: pointer to second input vector
|
||||||
|
**************************************************/
|
||||||
|
void polyvecl_pointwise_acc_montgomery(poly *w, const polyvecl *u, const polyvecl *v) {
|
||||||
|
pointwise_acc_avx(w->vec, u->vec->vec, v->vec->vec, qdata.vec);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: polyvecl_chknorm
|
||||||
|
*
|
||||||
|
* Description: Check infinity norm of polynomials in vector of length L.
|
||||||
|
* Assumes input polyvecl to be reduced by polyvecl_reduce().
|
||||||
|
*
|
||||||
|
* Arguments: - const polyvecl *v: pointer to vector
|
||||||
|
* - int32_t B: norm bound
|
||||||
|
*
|
||||||
|
* Returns 0 if norm of all polynomials is strictly smaller than B <= (Q-1)/8
|
||||||
|
* and 1 otherwise.
|
||||||
|
**************************************************/
|
||||||
|
int polyvecl_chknorm(const polyvecl *v, int32_t bound) {
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for(i = 0; i < L; ++i)
|
||||||
|
if(poly_chknorm(&v->vec[i], bound))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************************************************/
|
||||||
|
/************ Vectors of polynomials of length K **************/
|
||||||
|
/**************************************************************/
|
||||||
|
|
||||||
|
void polyveck_uniform_eta(polyveck *v, const uint8_t seed[CRHBYTES], uint16_t nonce) {
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for(i = 0; i < K; ++i)
|
||||||
|
poly_uniform_eta(&v->vec[i], seed, nonce++);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: polyveck_reduce
|
||||||
|
*
|
||||||
|
* Description: Reduce coefficients of polynomials in vector of length K
|
||||||
|
* to representatives in [-6283009,6283008].
|
||||||
|
*
|
||||||
|
* Arguments: - polyveck *v: pointer to input/output vector
|
||||||
|
**************************************************/
|
||||||
|
void polyveck_reduce(polyveck *v) {
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for(i = 0; i < K; ++i)
|
||||||
|
poly_reduce(&v->vec[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: polyveck_caddq
|
||||||
|
*
|
||||||
|
* Description: For all coefficients of polynomials in vector of length K
|
||||||
|
* add Q if coefficient is negative.
|
||||||
|
*
|
||||||
|
* Arguments: - polyveck *v: pointer to input/output vector
|
||||||
|
**************************************************/
|
||||||
|
void polyveck_caddq(polyveck *v) {
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for(i = 0; i < K; ++i)
|
||||||
|
poly_caddq(&v->vec[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: polyveck_add
|
||||||
|
*
|
||||||
|
* Description: Add vectors of polynomials of length K.
|
||||||
|
* No modular reduction is performed.
|
||||||
|
*
|
||||||
|
* Arguments: - polyveck *w: pointer to output vector
|
||||||
|
* - const polyveck *u: pointer to first summand
|
||||||
|
* - const polyveck *v: pointer to second summand
|
||||||
|
**************************************************/
|
||||||
|
void polyveck_add(polyveck *w, const polyveck *u, const polyveck *v) {
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for(i = 0; i < K; ++i)
|
||||||
|
poly_add(&w->vec[i], &u->vec[i], &v->vec[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: polyveck_sub
|
||||||
|
*
|
||||||
|
* Description: Subtract vectors of polynomials of length K.
|
||||||
|
* No modular reduction is performed.
|
||||||
|
*
|
||||||
|
* Arguments: - polyveck *w: pointer to output vector
|
||||||
|
* - const polyveck *u: pointer to first input vector
|
||||||
|
* - const polyveck *v: pointer to second input vector to be
|
||||||
|
* subtracted from first input vector
|
||||||
|
**************************************************/
|
||||||
|
void polyveck_sub(polyveck *w, const polyveck *u, const polyveck *v) {
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for(i = 0; i < K; ++i)
|
||||||
|
poly_sub(&w->vec[i], &u->vec[i], &v->vec[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: polyveck_shiftl
|
||||||
|
*
|
||||||
|
* Description: Multiply vector of polynomials of Length K by 2^D without modular
|
||||||
|
* reduction. Assumes input coefficients to be less than 2^{31-D}.
|
||||||
|
*
|
||||||
|
* Arguments: - polyveck *v: pointer to input/output vector
|
||||||
|
**************************************************/
|
||||||
|
void polyveck_shiftl(polyveck *v) {
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for(i = 0; i < K; ++i)
|
||||||
|
poly_shiftl(&v->vec[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: polyveck_ntt
|
||||||
|
*
|
||||||
|
* Description: Forward NTT of all polynomials in vector of length K. Output
|
||||||
|
* coefficients can be up to 16*Q larger than input coefficients.
|
||||||
|
*
|
||||||
|
* Arguments: - polyveck *v: pointer to input/output vector
|
||||||
|
**************************************************/
|
||||||
|
void polyveck_ntt(polyveck *v) {
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for(i = 0; i < K; ++i)
|
||||||
|
poly_ntt(&v->vec[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: polyveck_invntt_tomont
|
||||||
|
*
|
||||||
|
* Description: Inverse NTT and multiplication by 2^{32} of polynomials
|
||||||
|
* in vector of length K. Input coefficients need to be less
|
||||||
|
* than 2*Q.
|
||||||
|
*
|
||||||
|
* Arguments: - polyveck *v: pointer to input/output vector
|
||||||
|
**************************************************/
|
||||||
|
void polyveck_invntt_tomont(polyveck *v) {
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for(i = 0; i < K; ++i)
|
||||||
|
poly_invntt_tomont(&v->vec[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void polyveck_pointwise_poly_montgomery(polyveck *r, const poly *a, const polyveck *v) {
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for(i = 0; i < K; ++i)
|
||||||
|
poly_pointwise_montgomery(&r->vec[i], a, &v->vec[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: polyveck_chknorm
|
||||||
|
*
|
||||||
|
* Description: Check infinity norm of polynomials in vector of length K.
|
||||||
|
* Assumes input polyveck to be reduced by polyveck_reduce().
|
||||||
|
*
|
||||||
|
* Arguments: - const polyveck *v: pointer to vector
|
||||||
|
* - int32_t B: norm bound
|
||||||
|
*
|
||||||
|
* Returns 0 if norm of all polynomials are strictly smaller than B <= (Q-1)/8
|
||||||
|
* and 1 otherwise.
|
||||||
|
**************************************************/
|
||||||
|
int polyveck_chknorm(const polyveck *v, int32_t bound) {
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for(i = 0; i < K; ++i)
|
||||||
|
if(poly_chknorm(&v->vec[i], bound))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: polyveck_power2round
|
||||||
|
*
|
||||||
|
* Description: For all coefficients a of polynomials in vector of length K,
|
||||||
|
* compute a0, a1 such that a mod^+ Q = a1*2^D + a0
|
||||||
|
* with -2^{D-1} < a0 <= 2^{D-1}. Assumes coefficients to be
|
||||||
|
* standard representatives.
|
||||||
|
*
|
||||||
|
* Arguments: - polyveck *v1: pointer to output vector of polynomials with
|
||||||
|
* coefficients a1
|
||||||
|
* - polyveck *v0: pointer to output vector of polynomials with
|
||||||
|
* coefficients a0
|
||||||
|
* - const polyveck *v: pointer to input vector
|
||||||
|
**************************************************/
|
||||||
|
void polyveck_power2round(polyveck *v1, polyveck *v0, const polyveck *v) {
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for(i = 0; i < K; ++i)
|
||||||
|
poly_power2round(&v1->vec[i], &v0->vec[i], &v->vec[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: polyveck_decompose
|
||||||
|
*
|
||||||
|
* Description: For all coefficients a of polynomials in vector of length K,
|
||||||
|
* compute high and low bits a0, a1 such a mod^+ Q = a1*ALPHA + a0
|
||||||
|
* with -ALPHA/2 < a0 <= ALPHA/2 except a1 = (Q-1)/ALPHA where we
|
||||||
|
* set a1 = 0 and -ALPHA/2 <= a0 = a mod Q - Q < 0.
|
||||||
|
* Assumes coefficients to be standard representatives.
|
||||||
|
*
|
||||||
|
* Arguments: - polyveck *v1: pointer to output vector of polynomials with
|
||||||
|
* coefficients a1
|
||||||
|
* - polyveck *v0: pointer to output vector of polynomials with
|
||||||
|
* coefficients a0
|
||||||
|
* - const polyveck *v: pointer to input vector
|
||||||
|
**************************************************/
|
||||||
|
void polyveck_decompose(polyveck *v1, polyveck *v0, const polyveck *v) {
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for(i = 0; i < K; ++i)
|
||||||
|
poly_decompose(&v1->vec[i], &v0->vec[i], &v->vec[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: polyveck_make_hint
|
||||||
|
*
|
||||||
|
* Description: Compute hint vector.
|
||||||
|
*
|
||||||
|
* Arguments: - uint8_t *hint: pointer to output hint array
|
||||||
|
* - const polyveck *v0: pointer to low part of input vector
|
||||||
|
* - const polyveck *v1: pointer to high part of input vector
|
||||||
|
*
|
||||||
|
* Returns number of 1 bits.
|
||||||
|
**************************************************/
|
||||||
|
unsigned int polyveck_make_hint(uint8_t *hint, const polyveck *v0, const polyveck *v1)
|
||||||
|
{
|
||||||
|
unsigned int i, n = 0;
|
||||||
|
|
||||||
|
for(i = 0; i < K; ++i)
|
||||||
|
n += poly_make_hint(&hint[n], &v0->vec[i], &v1->vec[i]);
|
||||||
|
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: polyveck_use_hint
|
||||||
|
*
|
||||||
|
* Description: Use hint vector to correct the high bits of input vector.
|
||||||
|
*
|
||||||
|
* Arguments: - polyveck *w: pointer to output vector of polynomials with
|
||||||
|
* corrected high bits
|
||||||
|
* - const polyveck *u: pointer to input vector
|
||||||
|
* - const polyveck *h: pointer to input hint vector
|
||||||
|
**************************************************/
|
||||||
|
void polyveck_use_hint(polyveck *w, const polyveck *u, const polyveck *h) {
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for(i = 0; i < K; ++i)
|
||||||
|
poly_use_hint(&w->vec[i], &u->vec[i], &h->vec[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void polyveck_pack_w1(uint8_t r[K*POLYW1_PACKEDBYTES], const polyveck *w1) {
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for(i = 0; i < K; ++i)
|
||||||
|
polyw1_pack(&r[i*POLYW1_PACKEDBYTES], &w1->vec[i]);
|
||||||
|
}
|
||||||
105
src/crypto/pq/_d/avx2/polyvec.h
Normal file
105
src/crypto/pq/_d/avx2/polyvec.h
Normal file
|
|
@ -0,0 +1,105 @@
|
||||||
|
#ifndef POLYVEC_H
|
||||||
|
#define POLYVEC_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "params.h"
|
||||||
|
#include "poly.h"
|
||||||
|
|
||||||
|
/* Vectors of polynomials of length L */
|
||||||
|
typedef struct {
|
||||||
|
poly vec[L];
|
||||||
|
} polyvecl;
|
||||||
|
|
||||||
|
#define polyvecl_uniform_eta DILITHIUM_NAMESPACE(polyvecl_uniform_eta)
|
||||||
|
void polyvecl_uniform_eta(polyvecl *v, const uint8_t seed[CRHBYTES], uint16_t nonce);
|
||||||
|
|
||||||
|
#define polyvecl_uniform_gamma1 DILITHIUM_NAMESPACE(polyvecl_uniform_gamma1)
|
||||||
|
void polyvecl_uniform_gamma1(polyvecl *v, const uint8_t seed[CRHBYTES], uint16_t nonce);
|
||||||
|
|
||||||
|
#define polyvecl_reduce DILITHIUM_NAMESPACE(polyvecl_reduce)
|
||||||
|
void polyvecl_reduce(polyvecl *v);
|
||||||
|
|
||||||
|
#define polyvecl_add DILITHIUM_NAMESPACE(polyvecl_add)
|
||||||
|
void polyvecl_add(polyvecl *w, const polyvecl *u, const polyvecl *v);
|
||||||
|
|
||||||
|
#define polyvecl_ntt DILITHIUM_NAMESPACE(polyvecl_ntt)
|
||||||
|
void polyvecl_ntt(polyvecl *v);
|
||||||
|
#define polyvecl_invntt_tomont DILITHIUM_NAMESPACE(polyvecl_invntt_tomont)
|
||||||
|
void polyvecl_invntt_tomont(polyvecl *v);
|
||||||
|
#define polyvecl_pointwise_poly_montgomery DILITHIUM_NAMESPACE(polyvecl_pointwise_poly_montgomery)
|
||||||
|
void polyvecl_pointwise_poly_montgomery(polyvecl *r, const poly *a, const polyvecl *v);
|
||||||
|
#define polyvecl_pointwise_acc_montgomery \
|
||||||
|
DILITHIUM_NAMESPACE(polyvecl_pointwise_acc_montgomery)
|
||||||
|
void polyvecl_pointwise_acc_montgomery(poly *w,
|
||||||
|
const polyvecl *u,
|
||||||
|
const polyvecl *v);
|
||||||
|
|
||||||
|
#define polyvecl_chknorm DILITHIUM_NAMESPACE(polyvecl_chknorm)
|
||||||
|
int polyvecl_chknorm(const polyvecl *v, int32_t B);
|
||||||
|
|
||||||
|
/* Vectors of polynomials of length K */
|
||||||
|
typedef struct {
|
||||||
|
poly vec[K];
|
||||||
|
} polyveck;
|
||||||
|
|
||||||
|
#define polyveck_uniform_eta DILITHIUM_NAMESPACE(polyveck_uniform_eta)
|
||||||
|
void polyveck_uniform_eta(polyveck *v, const uint8_t seed[CRHBYTES], uint16_t nonce);
|
||||||
|
|
||||||
|
#define polyveck_reduce DILITHIUM_NAMESPACE(polyveck_reduce)
|
||||||
|
void polyveck_reduce(polyveck *v);
|
||||||
|
#define polyveck_caddq DILITHIUM_NAMESPACE(polyveck_caddq)
|
||||||
|
void polyveck_caddq(polyveck *v);
|
||||||
|
|
||||||
|
#define polyveck_add DILITHIUM_NAMESPACE(polyveck_add)
|
||||||
|
void polyveck_add(polyveck *w, const polyveck *u, const polyveck *v);
|
||||||
|
#define polyveck_sub DILITHIUM_NAMESPACE(polyveck_sub)
|
||||||
|
void polyveck_sub(polyveck *w, const polyveck *u, const polyveck *v);
|
||||||
|
#define polyveck_shiftl DILITHIUM_NAMESPACE(polyveck_shiftl)
|
||||||
|
void polyveck_shiftl(polyveck *v);
|
||||||
|
|
||||||
|
#define polyveck_ntt DILITHIUM_NAMESPACE(polyveck_ntt)
|
||||||
|
void polyveck_ntt(polyveck *v);
|
||||||
|
#define polyveck_invntt_tomont DILITHIUM_NAMESPACE(polyveck_invntt_tomont)
|
||||||
|
void polyveck_invntt_tomont(polyveck *v);
|
||||||
|
#define polyveck_pointwise_poly_montgomery DILITHIUM_NAMESPACE(polyveck_pointwise_poly_montgomery)
|
||||||
|
void polyveck_pointwise_poly_montgomery(polyveck *r, const poly *a, const polyveck *v);
|
||||||
|
|
||||||
|
#define polyveck_chknorm DILITHIUM_NAMESPACE(polyveck_chknorm)
|
||||||
|
int polyveck_chknorm(const polyveck *v, int32_t B);
|
||||||
|
|
||||||
|
#define polyveck_power2round DILITHIUM_NAMESPACE(polyveck_power2round)
|
||||||
|
void polyveck_power2round(polyveck *v1, polyveck *v0, const polyveck *v);
|
||||||
|
#define polyveck_decompose DILITHIUM_NAMESPACE(polyveck_decompose)
|
||||||
|
void polyveck_decompose(polyveck *v1, polyveck *v0, const polyveck *v);
|
||||||
|
#define polyveck_make_hint DILITHIUM_NAMESPACE(polyveck_make_hint)
|
||||||
|
unsigned int polyveck_make_hint(uint8_t *hint, const polyveck *v0, const polyveck *v1);
|
||||||
|
#define polyveck_use_hint DILITHIUM_NAMESPACE(polyveck_use_hint)
|
||||||
|
void polyveck_use_hint(polyveck *w, const polyveck *v, const polyveck *h);
|
||||||
|
|
||||||
|
#define polyveck_pack_w1 DILITHIUM_NAMESPACE(polyveck_pack_w1)
|
||||||
|
void polyveck_pack_w1(uint8_t r[K*POLYW1_PACKEDBYTES], const polyveck *w1);
|
||||||
|
|
||||||
|
#define polyvec_matrix_expand DILITHIUM_NAMESPACE(polyvec_matrix_expand)
|
||||||
|
void polyvec_matrix_expand(polyvecl mat[K], const uint8_t rho[SEEDBYTES]);
|
||||||
|
|
||||||
|
#define polyvec_matrix_expand_row0 DILITHIUM_NAMESPACE(polyvec_matrix_expand_row0)
|
||||||
|
void polyvec_matrix_expand_row0(polyvecl *rowa, polyvecl *rowb, const uint8_t rho[SEEDBYTES]);
|
||||||
|
#define polyvec_matrix_expand_row1 DILITHIUM_NAMESPACE(polyvec_matrix_expand_row1)
|
||||||
|
void polyvec_matrix_expand_row1(polyvecl *rowa, polyvecl *rowb, const uint8_t rho[SEEDBYTES]);
|
||||||
|
#define polyvec_matrix_expand_row2 DILITHIUM_NAMESPACE(polyvec_matrix_expand_row2)
|
||||||
|
void polyvec_matrix_expand_row2(polyvecl *rowa, polyvecl *rowb, const uint8_t rho[SEEDBYTES]);
|
||||||
|
#define polyvec_matrix_expand_row3 DILITHIUM_NAMESPACE(polyvec_matrix_expand_row3)
|
||||||
|
void polyvec_matrix_expand_row3(polyvecl *rowa, polyvecl *rowb, const uint8_t rho[SEEDBYTES]);
|
||||||
|
#define polyvec_matrix_expand_row4 DILITHIUM_NAMESPACE(polyvec_matrix_expand_row4)
|
||||||
|
void polyvec_matrix_expand_row4(polyvecl *rowa, polyvecl *rowb, const uint8_t rho[SEEDBYTES]);
|
||||||
|
#define polyvec_matrix_expand_row5 DILITHIUM_NAMESPACE(polyvec_matrix_expand_row5)
|
||||||
|
void polyvec_matrix_expand_row5(polyvecl *rowa, polyvecl *rowb, const uint8_t rho[SEEDBYTES]);
|
||||||
|
#define polyvec_matrix_expand_row6 DILITHIUM_NAMESPACE(polyvec_matrix_expand_row6)
|
||||||
|
void polyvec_matrix_expand_row6(polyvecl *rowa, polyvecl *rowb, const uint8_t rho[SEEDBYTES]);
|
||||||
|
#define polyvec_matrix_expand_row7 DILITHIUM_NAMESPACE(polyvec_matrix_expand_row7)
|
||||||
|
void polyvec_matrix_expand_row7(polyvecl *rowa, polyvecl *rowb, const uint8_t rho[SEEDBYTES]);
|
||||||
|
|
||||||
|
#define polyvec_matrix_pointwise_montgomery DILITHIUM_NAMESPACE(polyvec_matrix_pointwise_montgomery)
|
||||||
|
void polyvec_matrix_pointwise_montgomery(polyveck *t, const polyvecl mat[K], const polyvecl *v);
|
||||||
|
|
||||||
|
#endif
|
||||||
1
src/crypto/pq/_d/avx2/randombytes.c
Symbolic link
1
src/crypto/pq/_d/avx2/randombytes.c
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
../ref/randombytes.c
|
||||||
1
src/crypto/pq/_d/avx2/randombytes.h
Symbolic link
1
src/crypto/pq/_d/avx2/randombytes.h
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
../ref/randombytes.h
|
||||||
476
src/crypto/pq/_d/avx2/rejsample.c
Normal file
476
src/crypto/pq/_d/avx2/rejsample.c
Normal file
|
|
@ -0,0 +1,476 @@
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <immintrin.h>
|
||||||
|
#include "params.h"
|
||||||
|
#include "rejsample.h"
|
||||||
|
#include "symmetric.h"
|
||||||
|
|
||||||
|
const uint8_t idxlut[256][8] = {
|
||||||
|
{ 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, 1, 0, 0, 0, 0, 0, 0},
|
||||||
|
{ 2, 0, 0, 0, 0, 0, 0, 0},
|
||||||
|
{ 0, 2, 0, 0, 0, 0, 0, 0},
|
||||||
|
{ 1, 2, 0, 0, 0, 0, 0, 0},
|
||||||
|
{ 0, 1, 2, 0, 0, 0, 0, 0},
|
||||||
|
{ 3, 0, 0, 0, 0, 0, 0, 0},
|
||||||
|
{ 0, 3, 0, 0, 0, 0, 0, 0},
|
||||||
|
{ 1, 3, 0, 0, 0, 0, 0, 0},
|
||||||
|
{ 0, 1, 3, 0, 0, 0, 0, 0},
|
||||||
|
{ 2, 3, 0, 0, 0, 0, 0, 0},
|
||||||
|
{ 0, 2, 3, 0, 0, 0, 0, 0},
|
||||||
|
{ 1, 2, 3, 0, 0, 0, 0, 0},
|
||||||
|
{ 0, 1, 2, 3, 0, 0, 0, 0},
|
||||||
|
{ 4, 0, 0, 0, 0, 0, 0, 0},
|
||||||
|
{ 0, 4, 0, 0, 0, 0, 0, 0},
|
||||||
|
{ 1, 4, 0, 0, 0, 0, 0, 0},
|
||||||
|
{ 0, 1, 4, 0, 0, 0, 0, 0},
|
||||||
|
{ 2, 4, 0, 0, 0, 0, 0, 0},
|
||||||
|
{ 0, 2, 4, 0, 0, 0, 0, 0},
|
||||||
|
{ 1, 2, 4, 0, 0, 0, 0, 0},
|
||||||
|
{ 0, 1, 2, 4, 0, 0, 0, 0},
|
||||||
|
{ 3, 4, 0, 0, 0, 0, 0, 0},
|
||||||
|
{ 0, 3, 4, 0, 0, 0, 0, 0},
|
||||||
|
{ 1, 3, 4, 0, 0, 0, 0, 0},
|
||||||
|
{ 0, 1, 3, 4, 0, 0, 0, 0},
|
||||||
|
{ 2, 3, 4, 0, 0, 0, 0, 0},
|
||||||
|
{ 0, 2, 3, 4, 0, 0, 0, 0},
|
||||||
|
{ 1, 2, 3, 4, 0, 0, 0, 0},
|
||||||
|
{ 0, 1, 2, 3, 4, 0, 0, 0},
|
||||||
|
{ 5, 0, 0, 0, 0, 0, 0, 0},
|
||||||
|
{ 0, 5, 0, 0, 0, 0, 0, 0},
|
||||||
|
{ 1, 5, 0, 0, 0, 0, 0, 0},
|
||||||
|
{ 0, 1, 5, 0, 0, 0, 0, 0},
|
||||||
|
{ 2, 5, 0, 0, 0, 0, 0, 0},
|
||||||
|
{ 0, 2, 5, 0, 0, 0, 0, 0},
|
||||||
|
{ 1, 2, 5, 0, 0, 0, 0, 0},
|
||||||
|
{ 0, 1, 2, 5, 0, 0, 0, 0},
|
||||||
|
{ 3, 5, 0, 0, 0, 0, 0, 0},
|
||||||
|
{ 0, 3, 5, 0, 0, 0, 0, 0},
|
||||||
|
{ 1, 3, 5, 0, 0, 0, 0, 0},
|
||||||
|
{ 0, 1, 3, 5, 0, 0, 0, 0},
|
||||||
|
{ 2, 3, 5, 0, 0, 0, 0, 0},
|
||||||
|
{ 0, 2, 3, 5, 0, 0, 0, 0},
|
||||||
|
{ 1, 2, 3, 5, 0, 0, 0, 0},
|
||||||
|
{ 0, 1, 2, 3, 5, 0, 0, 0},
|
||||||
|
{ 4, 5, 0, 0, 0, 0, 0, 0},
|
||||||
|
{ 0, 4, 5, 0, 0, 0, 0, 0},
|
||||||
|
{ 1, 4, 5, 0, 0, 0, 0, 0},
|
||||||
|
{ 0, 1, 4, 5, 0, 0, 0, 0},
|
||||||
|
{ 2, 4, 5, 0, 0, 0, 0, 0},
|
||||||
|
{ 0, 2, 4, 5, 0, 0, 0, 0},
|
||||||
|
{ 1, 2, 4, 5, 0, 0, 0, 0},
|
||||||
|
{ 0, 1, 2, 4, 5, 0, 0, 0},
|
||||||
|
{ 3, 4, 5, 0, 0, 0, 0, 0},
|
||||||
|
{ 0, 3, 4, 5, 0, 0, 0, 0},
|
||||||
|
{ 1, 3, 4, 5, 0, 0, 0, 0},
|
||||||
|
{ 0, 1, 3, 4, 5, 0, 0, 0},
|
||||||
|
{ 2, 3, 4, 5, 0, 0, 0, 0},
|
||||||
|
{ 0, 2, 3, 4, 5, 0, 0, 0},
|
||||||
|
{ 1, 2, 3, 4, 5, 0, 0, 0},
|
||||||
|
{ 0, 1, 2, 3, 4, 5, 0, 0},
|
||||||
|
{ 6, 0, 0, 0, 0, 0, 0, 0},
|
||||||
|
{ 0, 6, 0, 0, 0, 0, 0, 0},
|
||||||
|
{ 1, 6, 0, 0, 0, 0, 0, 0},
|
||||||
|
{ 0, 1, 6, 0, 0, 0, 0, 0},
|
||||||
|
{ 2, 6, 0, 0, 0, 0, 0, 0},
|
||||||
|
{ 0, 2, 6, 0, 0, 0, 0, 0},
|
||||||
|
{ 1, 2, 6, 0, 0, 0, 0, 0},
|
||||||
|
{ 0, 1, 2, 6, 0, 0, 0, 0},
|
||||||
|
{ 3, 6, 0, 0, 0, 0, 0, 0},
|
||||||
|
{ 0, 3, 6, 0, 0, 0, 0, 0},
|
||||||
|
{ 1, 3, 6, 0, 0, 0, 0, 0},
|
||||||
|
{ 0, 1, 3, 6, 0, 0, 0, 0},
|
||||||
|
{ 2, 3, 6, 0, 0, 0, 0, 0},
|
||||||
|
{ 0, 2, 3, 6, 0, 0, 0, 0},
|
||||||
|
{ 1, 2, 3, 6, 0, 0, 0, 0},
|
||||||
|
{ 0, 1, 2, 3, 6, 0, 0, 0},
|
||||||
|
{ 4, 6, 0, 0, 0, 0, 0, 0},
|
||||||
|
{ 0, 4, 6, 0, 0, 0, 0, 0},
|
||||||
|
{ 1, 4, 6, 0, 0, 0, 0, 0},
|
||||||
|
{ 0, 1, 4, 6, 0, 0, 0, 0},
|
||||||
|
{ 2, 4, 6, 0, 0, 0, 0, 0},
|
||||||
|
{ 0, 2, 4, 6, 0, 0, 0, 0},
|
||||||
|
{ 1, 2, 4, 6, 0, 0, 0, 0},
|
||||||
|
{ 0, 1, 2, 4, 6, 0, 0, 0},
|
||||||
|
{ 3, 4, 6, 0, 0, 0, 0, 0},
|
||||||
|
{ 0, 3, 4, 6, 0, 0, 0, 0},
|
||||||
|
{ 1, 3, 4, 6, 0, 0, 0, 0},
|
||||||
|
{ 0, 1, 3, 4, 6, 0, 0, 0},
|
||||||
|
{ 2, 3, 4, 6, 0, 0, 0, 0},
|
||||||
|
{ 0, 2, 3, 4, 6, 0, 0, 0},
|
||||||
|
{ 1, 2, 3, 4, 6, 0, 0, 0},
|
||||||
|
{ 0, 1, 2, 3, 4, 6, 0, 0},
|
||||||
|
{ 5, 6, 0, 0, 0, 0, 0, 0},
|
||||||
|
{ 0, 5, 6, 0, 0, 0, 0, 0},
|
||||||
|
{ 1, 5, 6, 0, 0, 0, 0, 0},
|
||||||
|
{ 0, 1, 5, 6, 0, 0, 0, 0},
|
||||||
|
{ 2, 5, 6, 0, 0, 0, 0, 0},
|
||||||
|
{ 0, 2, 5, 6, 0, 0, 0, 0},
|
||||||
|
{ 1, 2, 5, 6, 0, 0, 0, 0},
|
||||||
|
{ 0, 1, 2, 5, 6, 0, 0, 0},
|
||||||
|
{ 3, 5, 6, 0, 0, 0, 0, 0},
|
||||||
|
{ 0, 3, 5, 6, 0, 0, 0, 0},
|
||||||
|
{ 1, 3, 5, 6, 0, 0, 0, 0},
|
||||||
|
{ 0, 1, 3, 5, 6, 0, 0, 0},
|
||||||
|
{ 2, 3, 5, 6, 0, 0, 0, 0},
|
||||||
|
{ 0, 2, 3, 5, 6, 0, 0, 0},
|
||||||
|
{ 1, 2, 3, 5, 6, 0, 0, 0},
|
||||||
|
{ 0, 1, 2, 3, 5, 6, 0, 0},
|
||||||
|
{ 4, 5, 6, 0, 0, 0, 0, 0},
|
||||||
|
{ 0, 4, 5, 6, 0, 0, 0, 0},
|
||||||
|
{ 1, 4, 5, 6, 0, 0, 0, 0},
|
||||||
|
{ 0, 1, 4, 5, 6, 0, 0, 0},
|
||||||
|
{ 2, 4, 5, 6, 0, 0, 0, 0},
|
||||||
|
{ 0, 2, 4, 5, 6, 0, 0, 0},
|
||||||
|
{ 1, 2, 4, 5, 6, 0, 0, 0},
|
||||||
|
{ 0, 1, 2, 4, 5, 6, 0, 0},
|
||||||
|
{ 3, 4, 5, 6, 0, 0, 0, 0},
|
||||||
|
{ 0, 3, 4, 5, 6, 0, 0, 0},
|
||||||
|
{ 1, 3, 4, 5, 6, 0, 0, 0},
|
||||||
|
{ 0, 1, 3, 4, 5, 6, 0, 0},
|
||||||
|
{ 2, 3, 4, 5, 6, 0, 0, 0},
|
||||||
|
{ 0, 2, 3, 4, 5, 6, 0, 0},
|
||||||
|
{ 1, 2, 3, 4, 5, 6, 0, 0},
|
||||||
|
{ 0, 1, 2, 3, 4, 5, 6, 0},
|
||||||
|
{ 7, 0, 0, 0, 0, 0, 0, 0},
|
||||||
|
{ 0, 7, 0, 0, 0, 0, 0, 0},
|
||||||
|
{ 1, 7, 0, 0, 0, 0, 0, 0},
|
||||||
|
{ 0, 1, 7, 0, 0, 0, 0, 0},
|
||||||
|
{ 2, 7, 0, 0, 0, 0, 0, 0},
|
||||||
|
{ 0, 2, 7, 0, 0, 0, 0, 0},
|
||||||
|
{ 1, 2, 7, 0, 0, 0, 0, 0},
|
||||||
|
{ 0, 1, 2, 7, 0, 0, 0, 0},
|
||||||
|
{ 3, 7, 0, 0, 0, 0, 0, 0},
|
||||||
|
{ 0, 3, 7, 0, 0, 0, 0, 0},
|
||||||
|
{ 1, 3, 7, 0, 0, 0, 0, 0},
|
||||||
|
{ 0, 1, 3, 7, 0, 0, 0, 0},
|
||||||
|
{ 2, 3, 7, 0, 0, 0, 0, 0},
|
||||||
|
{ 0, 2, 3, 7, 0, 0, 0, 0},
|
||||||
|
{ 1, 2, 3, 7, 0, 0, 0, 0},
|
||||||
|
{ 0, 1, 2, 3, 7, 0, 0, 0},
|
||||||
|
{ 4, 7, 0, 0, 0, 0, 0, 0},
|
||||||
|
{ 0, 4, 7, 0, 0, 0, 0, 0},
|
||||||
|
{ 1, 4, 7, 0, 0, 0, 0, 0},
|
||||||
|
{ 0, 1, 4, 7, 0, 0, 0, 0},
|
||||||
|
{ 2, 4, 7, 0, 0, 0, 0, 0},
|
||||||
|
{ 0, 2, 4, 7, 0, 0, 0, 0},
|
||||||
|
{ 1, 2, 4, 7, 0, 0, 0, 0},
|
||||||
|
{ 0, 1, 2, 4, 7, 0, 0, 0},
|
||||||
|
{ 3, 4, 7, 0, 0, 0, 0, 0},
|
||||||
|
{ 0, 3, 4, 7, 0, 0, 0, 0},
|
||||||
|
{ 1, 3, 4, 7, 0, 0, 0, 0},
|
||||||
|
{ 0, 1, 3, 4, 7, 0, 0, 0},
|
||||||
|
{ 2, 3, 4, 7, 0, 0, 0, 0},
|
||||||
|
{ 0, 2, 3, 4, 7, 0, 0, 0},
|
||||||
|
{ 1, 2, 3, 4, 7, 0, 0, 0},
|
||||||
|
{ 0, 1, 2, 3, 4, 7, 0, 0},
|
||||||
|
{ 5, 7, 0, 0, 0, 0, 0, 0},
|
||||||
|
{ 0, 5, 7, 0, 0, 0, 0, 0},
|
||||||
|
{ 1, 5, 7, 0, 0, 0, 0, 0},
|
||||||
|
{ 0, 1, 5, 7, 0, 0, 0, 0},
|
||||||
|
{ 2, 5, 7, 0, 0, 0, 0, 0},
|
||||||
|
{ 0, 2, 5, 7, 0, 0, 0, 0},
|
||||||
|
{ 1, 2, 5, 7, 0, 0, 0, 0},
|
||||||
|
{ 0, 1, 2, 5, 7, 0, 0, 0},
|
||||||
|
{ 3, 5, 7, 0, 0, 0, 0, 0},
|
||||||
|
{ 0, 3, 5, 7, 0, 0, 0, 0},
|
||||||
|
{ 1, 3, 5, 7, 0, 0, 0, 0},
|
||||||
|
{ 0, 1, 3, 5, 7, 0, 0, 0},
|
||||||
|
{ 2, 3, 5, 7, 0, 0, 0, 0},
|
||||||
|
{ 0, 2, 3, 5, 7, 0, 0, 0},
|
||||||
|
{ 1, 2, 3, 5, 7, 0, 0, 0},
|
||||||
|
{ 0, 1, 2, 3, 5, 7, 0, 0},
|
||||||
|
{ 4, 5, 7, 0, 0, 0, 0, 0},
|
||||||
|
{ 0, 4, 5, 7, 0, 0, 0, 0},
|
||||||
|
{ 1, 4, 5, 7, 0, 0, 0, 0},
|
||||||
|
{ 0, 1, 4, 5, 7, 0, 0, 0},
|
||||||
|
{ 2, 4, 5, 7, 0, 0, 0, 0},
|
||||||
|
{ 0, 2, 4, 5, 7, 0, 0, 0},
|
||||||
|
{ 1, 2, 4, 5, 7, 0, 0, 0},
|
||||||
|
{ 0, 1, 2, 4, 5, 7, 0, 0},
|
||||||
|
{ 3, 4, 5, 7, 0, 0, 0, 0},
|
||||||
|
{ 0, 3, 4, 5, 7, 0, 0, 0},
|
||||||
|
{ 1, 3, 4, 5, 7, 0, 0, 0},
|
||||||
|
{ 0, 1, 3, 4, 5, 7, 0, 0},
|
||||||
|
{ 2, 3, 4, 5, 7, 0, 0, 0},
|
||||||
|
{ 0, 2, 3, 4, 5, 7, 0, 0},
|
||||||
|
{ 1, 2, 3, 4, 5, 7, 0, 0},
|
||||||
|
{ 0, 1, 2, 3, 4, 5, 7, 0},
|
||||||
|
{ 6, 7, 0, 0, 0, 0, 0, 0},
|
||||||
|
{ 0, 6, 7, 0, 0, 0, 0, 0},
|
||||||
|
{ 1, 6, 7, 0, 0, 0, 0, 0},
|
||||||
|
{ 0, 1, 6, 7, 0, 0, 0, 0},
|
||||||
|
{ 2, 6, 7, 0, 0, 0, 0, 0},
|
||||||
|
{ 0, 2, 6, 7, 0, 0, 0, 0},
|
||||||
|
{ 1, 2, 6, 7, 0, 0, 0, 0},
|
||||||
|
{ 0, 1, 2, 6, 7, 0, 0, 0},
|
||||||
|
{ 3, 6, 7, 0, 0, 0, 0, 0},
|
||||||
|
{ 0, 3, 6, 7, 0, 0, 0, 0},
|
||||||
|
{ 1, 3, 6, 7, 0, 0, 0, 0},
|
||||||
|
{ 0, 1, 3, 6, 7, 0, 0, 0},
|
||||||
|
{ 2, 3, 6, 7, 0, 0, 0, 0},
|
||||||
|
{ 0, 2, 3, 6, 7, 0, 0, 0},
|
||||||
|
{ 1, 2, 3, 6, 7, 0, 0, 0},
|
||||||
|
{ 0, 1, 2, 3, 6, 7, 0, 0},
|
||||||
|
{ 4, 6, 7, 0, 0, 0, 0, 0},
|
||||||
|
{ 0, 4, 6, 7, 0, 0, 0, 0},
|
||||||
|
{ 1, 4, 6, 7, 0, 0, 0, 0},
|
||||||
|
{ 0, 1, 4, 6, 7, 0, 0, 0},
|
||||||
|
{ 2, 4, 6, 7, 0, 0, 0, 0},
|
||||||
|
{ 0, 2, 4, 6, 7, 0, 0, 0},
|
||||||
|
{ 1, 2, 4, 6, 7, 0, 0, 0},
|
||||||
|
{ 0, 1, 2, 4, 6, 7, 0, 0},
|
||||||
|
{ 3, 4, 6, 7, 0, 0, 0, 0},
|
||||||
|
{ 0, 3, 4, 6, 7, 0, 0, 0},
|
||||||
|
{ 1, 3, 4, 6, 7, 0, 0, 0},
|
||||||
|
{ 0, 1, 3, 4, 6, 7, 0, 0},
|
||||||
|
{ 2, 3, 4, 6, 7, 0, 0, 0},
|
||||||
|
{ 0, 2, 3, 4, 6, 7, 0, 0},
|
||||||
|
{ 1, 2, 3, 4, 6, 7, 0, 0},
|
||||||
|
{ 0, 1, 2, 3, 4, 6, 7, 0},
|
||||||
|
{ 5, 6, 7, 0, 0, 0, 0, 0},
|
||||||
|
{ 0, 5, 6, 7, 0, 0, 0, 0},
|
||||||
|
{ 1, 5, 6, 7, 0, 0, 0, 0},
|
||||||
|
{ 0, 1, 5, 6, 7, 0, 0, 0},
|
||||||
|
{ 2, 5, 6, 7, 0, 0, 0, 0},
|
||||||
|
{ 0, 2, 5, 6, 7, 0, 0, 0},
|
||||||
|
{ 1, 2, 5, 6, 7, 0, 0, 0},
|
||||||
|
{ 0, 1, 2, 5, 6, 7, 0, 0},
|
||||||
|
{ 3, 5, 6, 7, 0, 0, 0, 0},
|
||||||
|
{ 0, 3, 5, 6, 7, 0, 0, 0},
|
||||||
|
{ 1, 3, 5, 6, 7, 0, 0, 0},
|
||||||
|
{ 0, 1, 3, 5, 6, 7, 0, 0},
|
||||||
|
{ 2, 3, 5, 6, 7, 0, 0, 0},
|
||||||
|
{ 0, 2, 3, 5, 6, 7, 0, 0},
|
||||||
|
{ 1, 2, 3, 5, 6, 7, 0, 0},
|
||||||
|
{ 0, 1, 2, 3, 5, 6, 7, 0},
|
||||||
|
{ 4, 5, 6, 7, 0, 0, 0, 0},
|
||||||
|
{ 0, 4, 5, 6, 7, 0, 0, 0},
|
||||||
|
{ 1, 4, 5, 6, 7, 0, 0, 0},
|
||||||
|
{ 0, 1, 4, 5, 6, 7, 0, 0},
|
||||||
|
{ 2, 4, 5, 6, 7, 0, 0, 0},
|
||||||
|
{ 0, 2, 4, 5, 6, 7, 0, 0},
|
||||||
|
{ 1, 2, 4, 5, 6, 7, 0, 0},
|
||||||
|
{ 0, 1, 2, 4, 5, 6, 7, 0},
|
||||||
|
{ 3, 4, 5, 6, 7, 0, 0, 0},
|
||||||
|
{ 0, 3, 4, 5, 6, 7, 0, 0},
|
||||||
|
{ 1, 3, 4, 5, 6, 7, 0, 0},
|
||||||
|
{ 0, 1, 3, 4, 5, 6, 7, 0},
|
||||||
|
{ 2, 3, 4, 5, 6, 7, 0, 0},
|
||||||
|
{ 0, 2, 3, 4, 5, 6, 7, 0},
|
||||||
|
{ 1, 2, 3, 4, 5, 6, 7, 0},
|
||||||
|
{ 0, 1, 2, 3, 4, 5, 6, 7}
|
||||||
|
};
|
||||||
|
|
||||||
|
unsigned int rej_uniform_avx(int32_t * restrict r, const uint8_t buf[REJ_UNIFORM_BUFLEN+8])
|
||||||
|
{
|
||||||
|
unsigned int ctr, pos;
|
||||||
|
uint32_t good;
|
||||||
|
__m256i d, tmp;
|
||||||
|
const __m256i bound = _mm256_set1_epi32(Q);
|
||||||
|
const __m256i mask = _mm256_set1_epi32(0x7FFFFF);
|
||||||
|
const __m256i idx8 = _mm256_set_epi8(-1,15,14,13,-1,12,11,10,
|
||||||
|
-1, 9, 8, 7,-1, 6, 5, 4,
|
||||||
|
-1,11,10, 9,-1, 8, 7, 6,
|
||||||
|
-1, 5, 4, 3,-1, 2, 1, 0);
|
||||||
|
|
||||||
|
ctr = pos = 0;
|
||||||
|
while(pos <= REJ_UNIFORM_BUFLEN - 24) {
|
||||||
|
d = _mm256_loadu_si256((__m256i *)&buf[pos]);
|
||||||
|
d = _mm256_permute4x64_epi64(d, 0x94);
|
||||||
|
d = _mm256_shuffle_epi8(d, idx8);
|
||||||
|
d = _mm256_and_si256(d, mask);
|
||||||
|
pos += 24;
|
||||||
|
|
||||||
|
tmp = _mm256_sub_epi32(d, bound);
|
||||||
|
good = _mm256_movemask_ps((__m256)tmp);
|
||||||
|
tmp = _mm256_cvtepu8_epi32(_mm_loadl_epi64((__m128i *)&idxlut[good]));
|
||||||
|
d = _mm256_permutevar8x32_epi32(d, tmp);
|
||||||
|
|
||||||
|
_mm256_storeu_si256((__m256i *)&r[ctr], d);
|
||||||
|
ctr += _mm_popcnt_u32(good);
|
||||||
|
|
||||||
|
if(ctr > N - 8) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t t;
|
||||||
|
while(ctr < N && pos <= REJ_UNIFORM_BUFLEN - 3) {
|
||||||
|
t = buf[pos++];
|
||||||
|
t |= (uint32_t)buf[pos++] << 8;
|
||||||
|
t |= (uint32_t)buf[pos++] << 16;
|
||||||
|
t &= 0x7FFFFF;
|
||||||
|
|
||||||
|
if(t < Q)
|
||||||
|
r[ctr++] = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ctr;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if ETA == 2
|
||||||
|
unsigned int rej_eta_avx(int32_t * restrict r, const uint8_t buf[REJ_UNIFORM_ETA_BUFLEN]) {
|
||||||
|
unsigned int ctr, pos;
|
||||||
|
uint32_t good;
|
||||||
|
__m256i f0, f1, f2;
|
||||||
|
__m128i g0, g1;
|
||||||
|
const __m256i mask = _mm256_set1_epi8(15);
|
||||||
|
const __m256i eta = _mm256_set1_epi8(ETA);
|
||||||
|
const __m256i bound = mask;
|
||||||
|
const __m256i v = _mm256_set1_epi32(-6560);
|
||||||
|
const __m256i p = _mm256_set1_epi32(5);
|
||||||
|
|
||||||
|
ctr = pos = 0;
|
||||||
|
while(ctr <= N - 8 && pos <= REJ_UNIFORM_ETA_BUFLEN - 16) {
|
||||||
|
f0 = _mm256_cvtepu8_epi16(_mm_loadu_si128((__m128i *)&buf[pos]));
|
||||||
|
f1 = _mm256_slli_epi16(f0,4);
|
||||||
|
f0 = _mm256_or_si256(f0,f1);
|
||||||
|
f0 = _mm256_and_si256(f0,mask);
|
||||||
|
|
||||||
|
f1 = _mm256_sub_epi8(f0,bound);
|
||||||
|
f0 = _mm256_sub_epi8(eta,f0);
|
||||||
|
good = _mm256_movemask_epi8(f1);
|
||||||
|
|
||||||
|
g0 = _mm256_castsi256_si128(f0);
|
||||||
|
g1 = _mm_loadl_epi64((__m128i *)&idxlut[good & 0xFF]);
|
||||||
|
g1 = _mm_shuffle_epi8(g0,g1);
|
||||||
|
f1 = _mm256_cvtepi8_epi32(g1);
|
||||||
|
f2 = _mm256_mulhrs_epi16(f1,v);
|
||||||
|
f2 = _mm256_mullo_epi16(f2,p);
|
||||||
|
f1 = _mm256_add_epi32(f1,f2);
|
||||||
|
_mm256_storeu_si256((__m256i *)&r[ctr],f1);
|
||||||
|
ctr += _mm_popcnt_u32(good & 0xFF);
|
||||||
|
good >>= 8;
|
||||||
|
pos += 4;
|
||||||
|
|
||||||
|
if(ctr > N - 8) break;
|
||||||
|
g0 = _mm_bsrli_si128(g0,8);
|
||||||
|
g1 = _mm_loadl_epi64((__m128i *)&idxlut[good & 0xFF]);
|
||||||
|
g1 = _mm_shuffle_epi8(g0,g1);
|
||||||
|
f1 = _mm256_cvtepi8_epi32(g1);
|
||||||
|
f2 = _mm256_mulhrs_epi16(f1,v);
|
||||||
|
f2 = _mm256_mullo_epi16(f2,p);
|
||||||
|
f1 = _mm256_add_epi32(f1,f2);
|
||||||
|
_mm256_storeu_si256((__m256i *)&r[ctr],f1);
|
||||||
|
ctr += _mm_popcnt_u32(good & 0xFF);
|
||||||
|
good >>= 8;
|
||||||
|
pos += 4;
|
||||||
|
|
||||||
|
if(ctr > N - 8) break;
|
||||||
|
g0 = _mm256_extracti128_si256(f0,1);
|
||||||
|
g1 = _mm_loadl_epi64((__m128i *)&idxlut[good & 0xFF]);
|
||||||
|
g1 = _mm_shuffle_epi8(g0,g1);
|
||||||
|
f1 = _mm256_cvtepi8_epi32(g1);
|
||||||
|
f2 = _mm256_mulhrs_epi16(f1,v);
|
||||||
|
f2 = _mm256_mullo_epi16(f2,p);
|
||||||
|
f1 = _mm256_add_epi32(f1,f2);
|
||||||
|
_mm256_storeu_si256((__m256i *)&r[ctr],f1);
|
||||||
|
ctr += _mm_popcnt_u32(good & 0xFF);
|
||||||
|
good >>= 8;
|
||||||
|
pos += 4;
|
||||||
|
|
||||||
|
if(ctr > N - 8) break;
|
||||||
|
g0 = _mm_bsrli_si128(g0,8);
|
||||||
|
g1 = _mm_loadl_epi64((__m128i *)&idxlut[good]);
|
||||||
|
g1 = _mm_shuffle_epi8(g0,g1);
|
||||||
|
f1 = _mm256_cvtepi8_epi32(g1);
|
||||||
|
f2 = _mm256_mulhrs_epi16(f1,v);
|
||||||
|
f2 = _mm256_mullo_epi16(f2,p);
|
||||||
|
f1 = _mm256_add_epi32(f1,f2);
|
||||||
|
_mm256_storeu_si256((__m256i *)&r[ctr],f1);
|
||||||
|
ctr += _mm_popcnt_u32(good);
|
||||||
|
pos += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t t0, t1;
|
||||||
|
while(ctr < N && pos < REJ_UNIFORM_ETA_BUFLEN) {
|
||||||
|
t0 = buf[pos] & 0x0F;
|
||||||
|
t1 = buf[pos++] >> 4;
|
||||||
|
|
||||||
|
if(t0 < 15) {
|
||||||
|
t0 = t0 - (205*t0 >> 10)*5;
|
||||||
|
r[ctr++] = 2 - t0;
|
||||||
|
}
|
||||||
|
if(t1 < 15 && ctr < N) {
|
||||||
|
t1 = t1 - (205*t1 >> 10)*5;
|
||||||
|
r[ctr++] = 2 - t1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ctr;
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif ETA == 4
|
||||||
|
unsigned int rej_eta_avx(int32_t * restrict r, const uint8_t buf[REJ_UNIFORM_ETA_BUFLEN]) {
|
||||||
|
unsigned int ctr, pos;
|
||||||
|
uint32_t good;
|
||||||
|
__m256i f0, f1;
|
||||||
|
__m128i g0, g1;
|
||||||
|
const __m256i mask = _mm256_set1_epi8(15);
|
||||||
|
const __m256i eta = _mm256_set1_epi8(4);
|
||||||
|
const __m256i bound = _mm256_set1_epi8(9);
|
||||||
|
|
||||||
|
ctr = pos = 0;
|
||||||
|
while(ctr <= N - 8 && pos <= REJ_UNIFORM_ETA_BUFLEN - 16) {
|
||||||
|
f0 = _mm256_cvtepu8_epi16(_mm_loadu_si128((__m128i *)&buf[pos]));
|
||||||
|
f1 = _mm256_slli_epi16(f0,4);
|
||||||
|
f0 = _mm256_or_si256(f0,f1);
|
||||||
|
f0 = _mm256_and_si256(f0,mask);
|
||||||
|
|
||||||
|
f1 = _mm256_sub_epi8(f0,bound);
|
||||||
|
f0 = _mm256_sub_epi8(eta,f0);
|
||||||
|
good = _mm256_movemask_epi8(f1);
|
||||||
|
|
||||||
|
g0 = _mm256_castsi256_si128(f0);
|
||||||
|
g1 = _mm_loadl_epi64((__m128i *)&idxlut[good & 0xFF]);
|
||||||
|
g1 = _mm_shuffle_epi8(g0,g1);
|
||||||
|
f1 = _mm256_cvtepi8_epi32(g1);
|
||||||
|
_mm256_storeu_si256((__m256i *)&r[ctr],f1);
|
||||||
|
ctr += _mm_popcnt_u32(good & 0xFF);
|
||||||
|
good >>= 8;
|
||||||
|
pos += 4;
|
||||||
|
|
||||||
|
if(ctr > N - 8) break;
|
||||||
|
g0 = _mm_bsrli_si128(g0,8);
|
||||||
|
g1 = _mm_loadl_epi64((__m128i *)&idxlut[good & 0xFF]);
|
||||||
|
g1 = _mm_shuffle_epi8(g0,g1);
|
||||||
|
f1 = _mm256_cvtepi8_epi32(g1);
|
||||||
|
_mm256_storeu_si256((__m256i *)&r[ctr],f1);
|
||||||
|
ctr += _mm_popcnt_u32(good & 0xFF);
|
||||||
|
good >>= 8;
|
||||||
|
pos += 4;
|
||||||
|
|
||||||
|
if(ctr > N - 8) break;
|
||||||
|
g0 = _mm256_extracti128_si256(f0,1);
|
||||||
|
g1 = _mm_loadl_epi64((__m128i *)&idxlut[good & 0xFF]);
|
||||||
|
g1 = _mm_shuffle_epi8(g0,g1);
|
||||||
|
f1 = _mm256_cvtepi8_epi32(g1);
|
||||||
|
_mm256_storeu_si256((__m256i *)&r[ctr],f1);
|
||||||
|
ctr += _mm_popcnt_u32(good & 0xFF);
|
||||||
|
good >>= 8;
|
||||||
|
pos += 4;
|
||||||
|
|
||||||
|
if(ctr > N - 8) break;
|
||||||
|
g0 = _mm_bsrli_si128(g0,8);
|
||||||
|
g1 = _mm_loadl_epi64((__m128i *)&idxlut[good]);
|
||||||
|
g1 = _mm_shuffle_epi8(g0,g1);
|
||||||
|
f1 = _mm256_cvtepi8_epi32(g1);
|
||||||
|
_mm256_storeu_si256((__m256i *)&r[ctr],f1);
|
||||||
|
ctr += _mm_popcnt_u32(good);
|
||||||
|
pos += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t t0, t1;
|
||||||
|
while(ctr < N && pos < REJ_UNIFORM_ETA_BUFLEN) {
|
||||||
|
t0 = buf[pos] & 0x0F;
|
||||||
|
t1 = buf[pos++] >> 4;
|
||||||
|
|
||||||
|
if(t0 < 9)
|
||||||
|
r[ctr++] = 4 - t0;
|
||||||
|
if(t1 < 9 && ctr < N)
|
||||||
|
r[ctr++] = 4 - t1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ctr;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
28
src/crypto/pq/_d/avx2/rejsample.h
Normal file
28
src/crypto/pq/_d/avx2/rejsample.h
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
#ifndef REJSAMPLE_H
|
||||||
|
#define REJSAMPLE_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "params.h"
|
||||||
|
#include "symmetric.h"
|
||||||
|
|
||||||
|
#define REJ_UNIFORM_NBLOCKS ((768+STREAM128_BLOCKBYTES-1)/STREAM128_BLOCKBYTES)
|
||||||
|
#define REJ_UNIFORM_BUFLEN (REJ_UNIFORM_NBLOCKS*STREAM128_BLOCKBYTES)
|
||||||
|
|
||||||
|
#if ETA == 2
|
||||||
|
#define REJ_UNIFORM_ETA_NBLOCKS ((136+STREAM256_BLOCKBYTES-1)/STREAM256_BLOCKBYTES)
|
||||||
|
#elif ETA == 4
|
||||||
|
#define REJ_UNIFORM_ETA_NBLOCKS ((227+STREAM256_BLOCKBYTES-1)/STREAM256_BLOCKBYTES)
|
||||||
|
#endif
|
||||||
|
#define REJ_UNIFORM_ETA_BUFLEN (REJ_UNIFORM_ETA_NBLOCKS*STREAM256_BLOCKBYTES)
|
||||||
|
|
||||||
|
#define idxlut DILITHIUM_NAMESPACE(idxlut)
|
||||||
|
extern const uint8_t idxlut[256][8];
|
||||||
|
|
||||||
|
#define rej_uniform_avx DILITHIUM_NAMESPACE(rej_uniform_avx)
|
||||||
|
unsigned int rej_uniform_avx(int32_t *r, const uint8_t buf[REJ_UNIFORM_BUFLEN+8]);
|
||||||
|
|
||||||
|
#define rej_eta_avx DILITHIUM_NAMESPACE(rej_eta_avx)
|
||||||
|
unsigned int rej_eta_avx(int32_t *r, const uint8_t buf[REJ_UNIFORM_ETA_BUFLEN]);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
201
src/crypto/pq/_d/avx2/rounding.c
Normal file
201
src/crypto/pq/_d/avx2/rounding.c
Normal file
|
|
@ -0,0 +1,201 @@
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <immintrin.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "params.h"
|
||||||
|
#include "rounding.h"
|
||||||
|
#include "rejsample.h"
|
||||||
|
#include "consts.h"
|
||||||
|
|
||||||
|
#define _mm256_blendv_epi32(a,b,mask) \
|
||||||
|
_mm256_castps_si256(_mm256_blendv_ps(_mm256_castsi256_ps(a), \
|
||||||
|
_mm256_castsi256_ps(b), \
|
||||||
|
_mm256_castsi256_ps(mask)))
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: power2round
|
||||||
|
*
|
||||||
|
* Description: For finite field elements a, compute a0, a1 such that
|
||||||
|
* a mod^+ Q = a1*2^D + a0 with -2^{D-1} < a0 <= 2^{D-1}.
|
||||||
|
* Assumes a to be positive standard representative.
|
||||||
|
*
|
||||||
|
* Arguments: - __m256i *a1: output array of length N/8 with high bits
|
||||||
|
* - __m256i *a0: output array of length N/8 with low bits a0
|
||||||
|
* - const __m256i *a: input array of length N/8
|
||||||
|
*
|
||||||
|
**************************************************/
|
||||||
|
void power2round_avx(__m256i *a1, __m256i *a0, const __m256i *a)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
__m256i f,f0,f1;
|
||||||
|
const __m256i mask = _mm256_set1_epi32(-(1 << D));
|
||||||
|
const __m256i half = _mm256_set1_epi32((1 << (D-1)) - 1);
|
||||||
|
|
||||||
|
for(i = 0; i < N/8; ++i) {
|
||||||
|
f = _mm256_load_si256(&a[i]);
|
||||||
|
f1 = _mm256_add_epi32(f,half);
|
||||||
|
f0 = _mm256_and_si256(f1,mask);
|
||||||
|
f1 = _mm256_srli_epi32(f1,D);
|
||||||
|
f0 = _mm256_sub_epi32(f,f0);
|
||||||
|
_mm256_store_si256(&a1[i],f1);
|
||||||
|
_mm256_store_si256(&a0[i],f0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: decompose
|
||||||
|
*
|
||||||
|
* Description: For finite field element a, compute high and low parts a0, a1 such
|
||||||
|
* that a mod^+ Q = a1*ALPHA + a0 with -ALPHA/2 < a0 <= ALPHA/2 except
|
||||||
|
* if a1 = (Q-1)/ALPHA where we set a1 = 0 and
|
||||||
|
* -ALPHA/2 <= a0 = a mod Q - Q < 0. Assumes a to be positive standard
|
||||||
|
* representative.
|
||||||
|
*
|
||||||
|
* Arguments: - __m256i *a1: output array of length N/8 with high parts
|
||||||
|
* - __m256i *a0: output array of length N/8 with low parts a0
|
||||||
|
* - const __m256i *a: input array of length N/8
|
||||||
|
*
|
||||||
|
**************************************************/
|
||||||
|
#if GAMMA2 == (Q-1)/32
|
||||||
|
void decompose_avx(__m256i *a1, __m256i *a0, const __m256i *a)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
__m256i f,f0,f1;
|
||||||
|
const __m256i q = _mm256_load_si256(&qdata.vec[_8XQ/8]);
|
||||||
|
const __m256i hq = _mm256_srli_epi32(q,1);
|
||||||
|
const __m256i v = _mm256_set1_epi32(1025);
|
||||||
|
const __m256i alpha = _mm256_set1_epi32(2*GAMMA2);
|
||||||
|
const __m256i off = _mm256_set1_epi32(127);
|
||||||
|
const __m256i shift = _mm256_set1_epi32(512);
|
||||||
|
const __m256i mask = _mm256_set1_epi32(15);
|
||||||
|
|
||||||
|
for(i=0;i<N/8;i++) {
|
||||||
|
f = _mm256_load_si256(&a[i]);
|
||||||
|
f1 = _mm256_add_epi32(f,off);
|
||||||
|
f1 = _mm256_srli_epi32(f1,7);
|
||||||
|
f1 = _mm256_mulhi_epu16(f1,v);
|
||||||
|
f1 = _mm256_mulhrs_epi16(f1,shift);
|
||||||
|
f1 = _mm256_and_si256(f1,mask);
|
||||||
|
f0 = _mm256_mullo_epi32(f1,alpha);
|
||||||
|
f0 = _mm256_sub_epi32(f,f0);
|
||||||
|
f = _mm256_cmpgt_epi32(f0,hq);
|
||||||
|
f = _mm256_and_si256(f,q);
|
||||||
|
f0 = _mm256_sub_epi32(f0,f);
|
||||||
|
_mm256_store_si256(&a1[i],f1);
|
||||||
|
_mm256_store_si256(&a0[i],f0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif GAMMA2 == (Q-1)/88
|
||||||
|
void decompose_avx(__m256i *a1, __m256i *a0, const __m256i *a)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
__m256i f,f0,f1,t;
|
||||||
|
const __m256i q = _mm256_load_si256(&qdata.vec[_8XQ/8]);
|
||||||
|
const __m256i hq = _mm256_srli_epi32(q,1);
|
||||||
|
const __m256i v = _mm256_set1_epi32(11275);
|
||||||
|
const __m256i alpha = _mm256_set1_epi32(2*GAMMA2);
|
||||||
|
const __m256i off = _mm256_set1_epi32(127);
|
||||||
|
const __m256i shift = _mm256_set1_epi32(128);
|
||||||
|
const __m256i max = _mm256_set1_epi32(43);
|
||||||
|
const __m256i zero = _mm256_setzero_si256();
|
||||||
|
|
||||||
|
for(i=0;i<N/8;i++) {
|
||||||
|
f = _mm256_load_si256(&a[i]);
|
||||||
|
f1 = _mm256_add_epi32(f,off);
|
||||||
|
f1 = _mm256_srli_epi32(f1,7);
|
||||||
|
f1 = _mm256_mulhi_epu16(f1,v);
|
||||||
|
f1 = _mm256_mulhrs_epi16(f1,shift);
|
||||||
|
t = _mm256_sub_epi32(max,f1);
|
||||||
|
f1 = _mm256_blendv_epi32(f1,zero,t);
|
||||||
|
f0 = _mm256_mullo_epi32(f1,alpha);
|
||||||
|
f0 = _mm256_sub_epi32(f,f0);
|
||||||
|
f = _mm256_cmpgt_epi32(f0,hq);
|
||||||
|
f = _mm256_and_si256(f,q);
|
||||||
|
f0 = _mm256_sub_epi32(f0,f);
|
||||||
|
_mm256_store_si256(&a1[i],f1);
|
||||||
|
_mm256_store_si256(&a0[i],f0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: make_hint
|
||||||
|
*
|
||||||
|
* Description: Compute indices of polynomial coefficients whose low bits
|
||||||
|
* overflow into the high bits.
|
||||||
|
*
|
||||||
|
* Arguments: - uint8_t *hint: hint array
|
||||||
|
* - const __m256i *a0: low bits of input elements
|
||||||
|
* - const __m256i *a1: high bits of input elements
|
||||||
|
*
|
||||||
|
* Returns number of overflowing low bits
|
||||||
|
**************************************************/
|
||||||
|
unsigned int make_hint_avx(uint8_t hint[N], const __m256i * restrict a0, const __m256i * restrict a1)
|
||||||
|
{
|
||||||
|
unsigned int i, n = 0;
|
||||||
|
__m256i f0, f1, g0, g1;
|
||||||
|
uint32_t bad;
|
||||||
|
uint64_t idx;
|
||||||
|
const __m256i low = _mm256_set1_epi32(-GAMMA2);
|
||||||
|
const __m256i high = _mm256_set1_epi32(GAMMA2);
|
||||||
|
|
||||||
|
for(i = 0; i < N/8; ++i) {
|
||||||
|
f0 = _mm256_load_si256(&a0[i]);
|
||||||
|
f1 = _mm256_load_si256(&a1[i]);
|
||||||
|
g0 = _mm256_abs_epi32(f0);
|
||||||
|
g0 = _mm256_cmpgt_epi32(g0,high);
|
||||||
|
g1 = _mm256_cmpeq_epi32(f0,low);
|
||||||
|
g1 = _mm256_sign_epi32(g1,f1);
|
||||||
|
g0 = _mm256_or_si256(g0,g1);
|
||||||
|
|
||||||
|
bad = _mm256_movemask_ps((__m256)g0);
|
||||||
|
memcpy(&idx,idxlut[bad],8);
|
||||||
|
idx += (uint64_t)0x0808080808080808*i;
|
||||||
|
memcpy(&hint[n],&idx,8);
|
||||||
|
n += _mm_popcnt_u32(bad);
|
||||||
|
}
|
||||||
|
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: use_hint
|
||||||
|
*
|
||||||
|
* Description: Correct high parts according to hint.
|
||||||
|
*
|
||||||
|
* Arguments: - __m256i *b: output array of length N/8 with corrected high parts
|
||||||
|
* - const __m256i *a: input array of length N/8
|
||||||
|
* - const __m256i *a: input array of length N/8 with hint bits
|
||||||
|
*
|
||||||
|
**************************************************/
|
||||||
|
void use_hint_avx(__m256i *b, const __m256i *a, const __m256i * restrict hint) {
|
||||||
|
unsigned int i;
|
||||||
|
__m256i a0[N/8];
|
||||||
|
__m256i f,g,h,t;
|
||||||
|
const __m256i zero = _mm256_setzero_si256();
|
||||||
|
#if GAMMA2 == (Q-1)/32
|
||||||
|
const __m256i mask = _mm256_set1_epi32(15);
|
||||||
|
#elif GAMMA2 == (Q-1)/88
|
||||||
|
const __m256i max = _mm256_set1_epi32(43);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
decompose_avx(b, a0, a);
|
||||||
|
for(i=0;i<N/8;i++) {
|
||||||
|
f = _mm256_load_si256(&a0[i]);
|
||||||
|
g = _mm256_load_si256(&b[i]);
|
||||||
|
h = _mm256_load_si256(&hint[i]);
|
||||||
|
f = _mm256_sub_epi32(f,h);
|
||||||
|
t = _mm256_blendv_epi32(zero,h,f);
|
||||||
|
t = _mm256_slli_epi32(t,1);
|
||||||
|
h = _mm256_sub_epi32(h,t);
|
||||||
|
g = _mm256_add_epi32(g,h);
|
||||||
|
#if GAMMA2 == (Q-1)/32
|
||||||
|
g = _mm256_and_si256(g,mask);
|
||||||
|
#elif GAMMA2 == (Q-1)/88
|
||||||
|
g = _mm256_blendv_epi32(g,max,g);
|
||||||
|
f = _mm256_cmpgt_epi32(g,max);
|
||||||
|
g = _mm256_blendv_epi32(g,zero,f);
|
||||||
|
#endif
|
||||||
|
_mm256_store_si256(&b[i],g);
|
||||||
|
}
|
||||||
|
}
|
||||||
17
src/crypto/pq/_d/avx2/rounding.h
Normal file
17
src/crypto/pq/_d/avx2/rounding.h
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
#ifndef ROUNDING_H
|
||||||
|
#define ROUNDING_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <immintrin.h>
|
||||||
|
#include "params.h"
|
||||||
|
|
||||||
|
#define power2round_avx DILITHIUM_NAMESPACE(power2round_avx)
|
||||||
|
void power2round_avx(__m256i *a1, __m256i *a0, const __m256i *a);
|
||||||
|
#define decompose_avx DILITHIUM_NAMESPACE(decompose_avx)
|
||||||
|
void decompose_avx(__m256i *a1, __m256i *a0, const __m256i *a);
|
||||||
|
#define make_hint_avx DILITHIUM_NAMESPACE(make_hint_avx)
|
||||||
|
unsigned int make_hint_avx(uint8_t hint[N], const __m256i *a0, const __m256i *a1);
|
||||||
|
#define use_hint_avx DILITHIUM_NAMESPACE(use_hint_avx)
|
||||||
|
void use_hint_avx(__m256i *b, const __m256i *a, const __m256i *hint);
|
||||||
|
|
||||||
|
#endif
|
||||||
54
src/crypto/pq/_d/avx2/shuffle.S
Normal file
54
src/crypto/pq/_d/avx2/shuffle.S
Normal file
|
|
@ -0,0 +1,54 @@
|
||||||
|
#include "consts.h"
|
||||||
|
.include "shuffle.inc"
|
||||||
|
|
||||||
|
.text
|
||||||
|
nttunpack128_avx:
|
||||||
|
#load
|
||||||
|
vmovdqa (%rdi),%ymm4
|
||||||
|
vmovdqa 32(%rdi),%ymm5
|
||||||
|
vmovdqa 64(%rdi),%ymm6
|
||||||
|
vmovdqa 96(%rdi),%ymm7
|
||||||
|
vmovdqa 128(%rdi),%ymm8
|
||||||
|
vmovdqa 160(%rdi),%ymm9
|
||||||
|
vmovdqa 192(%rdi),%ymm10
|
||||||
|
vmovdqa 224(%rdi),%ymm11
|
||||||
|
|
||||||
|
shuffle8 4,8,3,8
|
||||||
|
shuffle8 5,9,4,9
|
||||||
|
shuffle8 6,10,5,10
|
||||||
|
shuffle8 7,11,6,11
|
||||||
|
|
||||||
|
shuffle4 3,5,7,5
|
||||||
|
shuffle4 8,10,3,10
|
||||||
|
shuffle4 4,6,8,6
|
||||||
|
shuffle4 9,11,4,11
|
||||||
|
|
||||||
|
shuffle2 7,8,9,8
|
||||||
|
shuffle2 5,6,7,6
|
||||||
|
shuffle2 3,4,5,4
|
||||||
|
shuffle2 10,11,3,11
|
||||||
|
|
||||||
|
#store
|
||||||
|
vmovdqa %ymm9,(%rdi)
|
||||||
|
vmovdqa %ymm8,32(%rdi)
|
||||||
|
vmovdqa %ymm7,64(%rdi)
|
||||||
|
vmovdqa %ymm6,96(%rdi)
|
||||||
|
vmovdqa %ymm5,128(%rdi)
|
||||||
|
vmovdqa %ymm4,160(%rdi)
|
||||||
|
vmovdqa %ymm3,192(%rdi)
|
||||||
|
vmovdqa %ymm11,224(%rdi)
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
.global cdecl(nttunpack_avx)
|
||||||
|
cdecl(nttunpack_avx):
|
||||||
|
call nttunpack128_avx
|
||||||
|
add $256,%rdi
|
||||||
|
call nttunpack128_avx
|
||||||
|
add $256,%rdi
|
||||||
|
call nttunpack128_avx
|
||||||
|
add $256,%rdi
|
||||||
|
call nttunpack128_avx
|
||||||
|
ret
|
||||||
|
|
||||||
|
.section .note.GNU-stack,"",@progbits
|
||||||
25
src/crypto/pq/_d/avx2/shuffle.inc
Normal file
25
src/crypto/pq/_d/avx2/shuffle.inc
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
.macro shuffle8 r0,r1,r2,r3
|
||||||
|
vperm2i128 $0x20,%ymm\r1,%ymm\r0,%ymm\r2
|
||||||
|
vperm2i128 $0x31,%ymm\r1,%ymm\r0,%ymm\r3
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro shuffle4 r0,r1,r2,r3
|
||||||
|
vpunpcklqdq %ymm\r1,%ymm\r0,%ymm\r2
|
||||||
|
vpunpckhqdq %ymm\r1,%ymm\r0,%ymm\r3
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro shuffle2 r0,r1,r2,r3
|
||||||
|
#vpsllq $32,%ymm\r1,%ymm\r2
|
||||||
|
vmovsldup %ymm\r1,%ymm\r2
|
||||||
|
vpblendd $0xAA,%ymm\r2,%ymm\r0,%ymm\r2
|
||||||
|
vpsrlq $32,%ymm\r0,%ymm\r0
|
||||||
|
#vmovshdup %ymm\r0,%ymm\r0
|
||||||
|
vpblendd $0xAA,%ymm\r1,%ymm\r0,%ymm\r3
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro shuffle1 r0,r1,r2,r3
|
||||||
|
vpslld $16,%ymm\r1,%ymm\r2
|
||||||
|
vpblendw $0xAA,%ymm\r2,%ymm\r0,%ymm\r2
|
||||||
|
vpsrld $16,%ymm\r0,%ymm\r0
|
||||||
|
vpblendw $0xAA,%ymm\r1,%ymm\r0,%ymm\r3
|
||||||
|
.endm
|
||||||
532
src/crypto/pq/_d/avx2/sign.c
Normal file
532
src/crypto/pq/_d/avx2/sign.c
Normal file
|
|
@ -0,0 +1,532 @@
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "align.h"
|
||||||
|
#include "params.h"
|
||||||
|
#include "sign.h"
|
||||||
|
#include "packing.h"
|
||||||
|
#include "polyvec.h"
|
||||||
|
#include "poly.h"
|
||||||
|
#include "randombytes.h"
|
||||||
|
#include "symmetric.h"
|
||||||
|
#include "fips202.h"
|
||||||
|
|
||||||
|
static inline void polyvec_matrix_expand_row(polyvecl **row, polyvecl buf[2], const uint8_t rho[SEEDBYTES], unsigned int i) {
|
||||||
|
switch(i) {
|
||||||
|
case 0:
|
||||||
|
polyvec_matrix_expand_row0(buf, buf + 1, rho);
|
||||||
|
*row = buf;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
polyvec_matrix_expand_row1(buf + 1, buf, rho);
|
||||||
|
*row = buf + 1;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
polyvec_matrix_expand_row2(buf, buf + 1, rho);
|
||||||
|
*row = buf;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
polyvec_matrix_expand_row3(buf + 1, buf, rho);
|
||||||
|
*row = buf + 1;
|
||||||
|
break;
|
||||||
|
#if K > 4
|
||||||
|
case 4:
|
||||||
|
polyvec_matrix_expand_row4(buf, buf + 1, rho);
|
||||||
|
*row = buf;
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
polyvec_matrix_expand_row5(buf + 1, buf, rho);
|
||||||
|
*row = buf + 1;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#if K > 6
|
||||||
|
case 6:
|
||||||
|
polyvec_matrix_expand_row6(buf, buf + 1, rho);
|
||||||
|
*row = buf;
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
polyvec_matrix_expand_row7(buf + 1, buf, rho);
|
||||||
|
*row = buf + 1;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: crypto_sign_keypair
|
||||||
|
*
|
||||||
|
* Description: Generates public and private key.
|
||||||
|
*
|
||||||
|
* Arguments: - uint8_t *pk: pointer to output public key (allocated
|
||||||
|
* array of CRYPTO_PUBLICKEYBYTES bytes)
|
||||||
|
* - uint8_t *sk: pointer to output private key (allocated
|
||||||
|
* array of CRYPTO_SECRETKEYBYTES bytes)
|
||||||
|
*
|
||||||
|
* Returns 0 (success)
|
||||||
|
**************************************************/
|
||||||
|
int crypto_sign_keypair(uint8_t *pk, uint8_t *sk) {
|
||||||
|
unsigned int i;
|
||||||
|
uint8_t seedbuf[2*SEEDBYTES + CRHBYTES];
|
||||||
|
const uint8_t *rho, *rhoprime, *key;
|
||||||
|
polyvecl rowbuf[2];
|
||||||
|
polyvecl s1, *row = rowbuf;
|
||||||
|
polyveck s2;
|
||||||
|
poly t1, t0;
|
||||||
|
|
||||||
|
/* Get randomness for rho, rhoprime and key */
|
||||||
|
randombytes(seedbuf, SEEDBYTES);
|
||||||
|
seedbuf[SEEDBYTES+0] = K;
|
||||||
|
seedbuf[SEEDBYTES+1] = L;
|
||||||
|
shake256(seedbuf, 2*SEEDBYTES + CRHBYTES, seedbuf, SEEDBYTES+2);
|
||||||
|
rho = seedbuf;
|
||||||
|
rhoprime = rho + SEEDBYTES;
|
||||||
|
key = rhoprime + CRHBYTES;
|
||||||
|
|
||||||
|
/* Store rho, key */
|
||||||
|
memcpy(pk, rho, SEEDBYTES);
|
||||||
|
memcpy(sk, rho, SEEDBYTES);
|
||||||
|
memcpy(sk + SEEDBYTES, key, SEEDBYTES);
|
||||||
|
|
||||||
|
/* Sample short vectors s1 and s2 */
|
||||||
|
#if K == 4 && L == 4
|
||||||
|
poly_uniform_eta_4x(&s1.vec[0], &s1.vec[1], &s1.vec[2], &s1.vec[3], rhoprime, 0, 1, 2, 3);
|
||||||
|
poly_uniform_eta_4x(&s2.vec[0], &s2.vec[1], &s2.vec[2], &s2.vec[3], rhoprime, 4, 5, 6, 7);
|
||||||
|
#elif K == 6 && L == 5
|
||||||
|
poly_uniform_eta_4x(&s1.vec[0], &s1.vec[1], &s1.vec[2], &s1.vec[3], rhoprime, 0, 1, 2, 3);
|
||||||
|
poly_uniform_eta_4x(&s1.vec[4], &s2.vec[0], &s2.vec[1], &s2.vec[2], rhoprime, 4, 5, 6, 7);
|
||||||
|
poly_uniform_eta_4x(&s2.vec[3], &s2.vec[4], &s2.vec[5], &t0, rhoprime, 8, 9, 10, 11);
|
||||||
|
#elif K == 8 && L == 7
|
||||||
|
poly_uniform_eta_4x(&s1.vec[0], &s1.vec[1], &s1.vec[2], &s1.vec[3], rhoprime, 0, 1, 2, 3);
|
||||||
|
poly_uniform_eta_4x(&s1.vec[4], &s1.vec[5], &s1.vec[6], &s2.vec[0], rhoprime, 4, 5, 6, 7);
|
||||||
|
poly_uniform_eta_4x(&s2.vec[1], &s2.vec[2], &s2.vec[3], &s2.vec[4], rhoprime, 8, 9, 10, 11);
|
||||||
|
poly_uniform_eta_4x(&s2.vec[5], &s2.vec[6], &s2.vec[7], &t0, rhoprime, 12, 13, 14, 15);
|
||||||
|
#else
|
||||||
|
#error
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Pack secret vectors */
|
||||||
|
for(i = 0; i < L; i++)
|
||||||
|
polyeta_pack(sk + 2*SEEDBYTES + TRBYTES + i*POLYETA_PACKEDBYTES, &s1.vec[i]);
|
||||||
|
for(i = 0; i < K; i++)
|
||||||
|
polyeta_pack(sk + 2*SEEDBYTES + TRBYTES + (L + i)*POLYETA_PACKEDBYTES, &s2.vec[i]);
|
||||||
|
|
||||||
|
/* Transform s1 */
|
||||||
|
polyvecl_ntt(&s1);
|
||||||
|
|
||||||
|
for(i = 0; i < K; i++) {
|
||||||
|
/* Expand matrix row */
|
||||||
|
polyvec_matrix_expand_row(&row, rowbuf, rho, i);
|
||||||
|
|
||||||
|
/* Compute inner-product */
|
||||||
|
polyvecl_pointwise_acc_montgomery(&t1, row, &s1);
|
||||||
|
poly_invntt_tomont(&t1);
|
||||||
|
|
||||||
|
/* Add error polynomial */
|
||||||
|
poly_add(&t1, &t1, &s2.vec[i]);
|
||||||
|
|
||||||
|
/* Round t and pack t1, t0 */
|
||||||
|
poly_caddq(&t1);
|
||||||
|
poly_power2round(&t1, &t0, &t1);
|
||||||
|
polyt1_pack(pk + SEEDBYTES + i*POLYT1_PACKEDBYTES, &t1);
|
||||||
|
polyt0_pack(sk + 2*SEEDBYTES + TRBYTES + (L+K)*POLYETA_PACKEDBYTES + i*POLYT0_PACKEDBYTES, &t0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Compute H(rho, t1) and store in secret key */
|
||||||
|
shake256(sk + 2*SEEDBYTES, TRBYTES, pk, CRYPTO_PUBLICKEYBYTES);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: crypto_sign_signature_internal
|
||||||
|
*
|
||||||
|
* Description: Computes signature. Internal API.
|
||||||
|
*
|
||||||
|
* Arguments: - uint8_t *sig: pointer to output signature (of length CRYPTO_BYTES)
|
||||||
|
* - size_t *siglen: pointer to output length of signature
|
||||||
|
* - uint8_t *m: pointer to message to be signed
|
||||||
|
* - size_t mlen: length of message
|
||||||
|
* - uint8_t *pre: pointer to prefix string
|
||||||
|
* - size_t prelen: length of prefix string
|
||||||
|
* - uint8_t *rnd: pointer to random seed
|
||||||
|
* - uint8_t *sk: pointer to bit-packed secret key
|
||||||
|
*
|
||||||
|
* Returns 0 (success)
|
||||||
|
**************************************************/
|
||||||
|
int crypto_sign_signature_internal(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen,
|
||||||
|
const uint8_t *pre, size_t prelen, const uint8_t rnd[RNDBYTES], const uint8_t *sk)
|
||||||
|
{
|
||||||
|
unsigned int i, n, pos;
|
||||||
|
uint8_t seedbuf[2*SEEDBYTES + TRBYTES + 2*CRHBYTES];
|
||||||
|
uint8_t *rho, *tr, *key, *mu, *rhoprime;
|
||||||
|
uint8_t hintbuf[N];
|
||||||
|
uint8_t *hint = sig + CTILDEBYTES + L*POLYZ_PACKEDBYTES;
|
||||||
|
uint64_t nonce = 0;
|
||||||
|
polyvecl mat[K], s1, z;
|
||||||
|
polyveck t0, s2, w1;
|
||||||
|
poly c, tmp;
|
||||||
|
union {
|
||||||
|
polyvecl y;
|
||||||
|
polyveck w0;
|
||||||
|
} tmpv;
|
||||||
|
keccak_state state;
|
||||||
|
|
||||||
|
rho = seedbuf;
|
||||||
|
tr = rho + SEEDBYTES;
|
||||||
|
key = tr + TRBYTES;
|
||||||
|
mu = key + SEEDBYTES;
|
||||||
|
rhoprime = mu + CRHBYTES;
|
||||||
|
unpack_sk(rho, tr, key, &t0, &s1, &s2, sk);
|
||||||
|
|
||||||
|
/* Compute mu = CRH(tr, pre, msg) */
|
||||||
|
shake256_init(&state);
|
||||||
|
shake256_absorb(&state, tr, TRBYTES);
|
||||||
|
shake256_absorb(&state, pre, prelen);
|
||||||
|
shake256_absorb(&state, m, mlen);
|
||||||
|
shake256_finalize(&state);
|
||||||
|
shake256_squeeze(mu, CRHBYTES, &state);
|
||||||
|
|
||||||
|
/* Compute rhoprime = CRH(key, rnd, mu) */
|
||||||
|
shake256_init(&state);
|
||||||
|
shake256_absorb(&state, key, SEEDBYTES);
|
||||||
|
shake256_absorb(&state, rnd, RNDBYTES);
|
||||||
|
shake256_absorb(&state, mu, CRHBYTES);
|
||||||
|
shake256_finalize(&state);
|
||||||
|
shake256_squeeze(rhoprime, CRHBYTES, &state);
|
||||||
|
|
||||||
|
/* Expand matrix and transform vectors */
|
||||||
|
polyvec_matrix_expand(mat, rho);
|
||||||
|
polyvecl_ntt(&s1);
|
||||||
|
polyveck_ntt(&s2);
|
||||||
|
polyveck_ntt(&t0);
|
||||||
|
|
||||||
|
rej:
|
||||||
|
/* Sample intermediate vector y */
|
||||||
|
#if L == 4
|
||||||
|
poly_uniform_gamma1_4x(&z.vec[0], &z.vec[1], &z.vec[2], &z.vec[3],
|
||||||
|
rhoprime, nonce, nonce + 1, nonce + 2, nonce + 3);
|
||||||
|
nonce += 4;
|
||||||
|
#elif L == 5
|
||||||
|
poly_uniform_gamma1_4x(&z.vec[0], &z.vec[1], &z.vec[2], &z.vec[3],
|
||||||
|
rhoprime, nonce, nonce + 1, nonce + 2, nonce + 3);
|
||||||
|
poly_uniform_gamma1(&z.vec[4], rhoprime, nonce + 4);
|
||||||
|
nonce += 5;
|
||||||
|
#elif L == 7
|
||||||
|
poly_uniform_gamma1_4x(&z.vec[0], &z.vec[1], &z.vec[2], &z.vec[3],
|
||||||
|
rhoprime, nonce, nonce + 1, nonce + 2, nonce + 3);
|
||||||
|
poly_uniform_gamma1_4x(&z.vec[4], &z.vec[5], &z.vec[6], &tmp,
|
||||||
|
rhoprime, nonce + 4, nonce + 5, nonce + 6, 0);
|
||||||
|
nonce += 7;
|
||||||
|
#else
|
||||||
|
#error
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Matrix-vector product */
|
||||||
|
tmpv.y = z;
|
||||||
|
polyvecl_ntt(&tmpv.y);
|
||||||
|
polyvec_matrix_pointwise_montgomery(&w1, mat, &tmpv.y);
|
||||||
|
polyveck_invntt_tomont(&w1);
|
||||||
|
|
||||||
|
/* Decompose w and call the random oracle */
|
||||||
|
polyveck_caddq(&w1);
|
||||||
|
polyveck_decompose(&w1, &tmpv.w0, &w1);
|
||||||
|
polyveck_pack_w1(sig, &w1);
|
||||||
|
|
||||||
|
shake256_init(&state);
|
||||||
|
shake256_absorb(&state, mu, CRHBYTES);
|
||||||
|
shake256_absorb(&state, sig, K*POLYW1_PACKEDBYTES);
|
||||||
|
shake256_finalize(&state);
|
||||||
|
shake256_squeeze(sig, CTILDEBYTES, &state);
|
||||||
|
poly_challenge(&c, sig);
|
||||||
|
poly_ntt(&c);
|
||||||
|
|
||||||
|
/* Compute z, reject if it reveals secret */
|
||||||
|
for(i = 0; i < L; i++) {
|
||||||
|
poly_pointwise_montgomery(&tmp, &c, &s1.vec[i]);
|
||||||
|
poly_invntt_tomont(&tmp);
|
||||||
|
poly_add(&z.vec[i], &z.vec[i], &tmp);
|
||||||
|
poly_reduce(&z.vec[i]);
|
||||||
|
if(poly_chknorm(&z.vec[i], GAMMA1 - BETA))
|
||||||
|
goto rej;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Zero hint vector in signature */
|
||||||
|
pos = 0;
|
||||||
|
memset(hint, 0, OMEGA);
|
||||||
|
|
||||||
|
for(i = 0; i < K; i++) {
|
||||||
|
/* Check that subtracting cs2 does not change high bits of w and low bits
|
||||||
|
* do not reveal secret information */
|
||||||
|
poly_pointwise_montgomery(&tmp, &c, &s2.vec[i]);
|
||||||
|
poly_invntt_tomont(&tmp);
|
||||||
|
poly_sub(&tmpv.w0.vec[i], &tmpv.w0.vec[i], &tmp);
|
||||||
|
poly_reduce(&tmpv.w0.vec[i]);
|
||||||
|
if(poly_chknorm(&tmpv.w0.vec[i], GAMMA2 - BETA))
|
||||||
|
goto rej;
|
||||||
|
|
||||||
|
/* Compute hints */
|
||||||
|
poly_pointwise_montgomery(&tmp, &c, &t0.vec[i]);
|
||||||
|
poly_invntt_tomont(&tmp);
|
||||||
|
poly_reduce(&tmp);
|
||||||
|
if(poly_chknorm(&tmp, GAMMA2))
|
||||||
|
goto rej;
|
||||||
|
|
||||||
|
poly_add(&tmpv.w0.vec[i], &tmpv.w0.vec[i], &tmp);
|
||||||
|
n = poly_make_hint(hintbuf, &tmpv.w0.vec[i], &w1.vec[i]);
|
||||||
|
if(pos + n > OMEGA)
|
||||||
|
goto rej;
|
||||||
|
|
||||||
|
/* Store hints in signature */
|
||||||
|
memcpy(&hint[pos], hintbuf, n);
|
||||||
|
hint[OMEGA + i] = pos = pos + n;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Pack z into signature */
|
||||||
|
for(i = 0; i < L; i++)
|
||||||
|
polyz_pack(sig + CTILDEBYTES + i*POLYZ_PACKEDBYTES, &z.vec[i]);
|
||||||
|
|
||||||
|
*siglen = CRYPTO_BYTES;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: crypto_sign_signature
|
||||||
|
*
|
||||||
|
* Description: Computes signature.
|
||||||
|
*
|
||||||
|
* Arguments: - uint8_t *sig: pointer to output signature (of length CRYPTO_BYTES)
|
||||||
|
* - size_t *siglen: pointer to output length of signature
|
||||||
|
* - uint8_t *m: pointer to message to be signed
|
||||||
|
* - size_t mlen: length of message
|
||||||
|
* - uint8_t *ctx: pointer to context string
|
||||||
|
* - size_t ctxlen: length of context string
|
||||||
|
* - uint8_t *sk: pointer to bit-packed secret key
|
||||||
|
*
|
||||||
|
* Returns 0 (success) or -1 (context string too long)
|
||||||
|
**************************************************/
|
||||||
|
int crypto_sign_signature(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen,
|
||||||
|
const uint8_t *ctx, size_t ctxlen, const uint8_t *sk)
|
||||||
|
{
|
||||||
|
uint8_t pre[257];
|
||||||
|
uint8_t rnd[RNDBYTES];
|
||||||
|
|
||||||
|
if(ctxlen > 255)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* Prepare pre = (0, ctxlen, ctx) */
|
||||||
|
pre[0] = 0;
|
||||||
|
pre[1] = ctxlen;
|
||||||
|
memcpy(&pre[2], ctx, ctxlen);
|
||||||
|
|
||||||
|
#ifdef DILITHIUM_RANDOMIZED_SIGNING
|
||||||
|
randombytes(rnd, RNDBYTES);
|
||||||
|
#else
|
||||||
|
memset(rnd, 0, RNDBYTES);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
crypto_sign_signature_internal(sig,siglen,m,mlen,pre,2+ctxlen,rnd,sk);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: crypto_sign
|
||||||
|
*
|
||||||
|
* Description: Compute signed message.
|
||||||
|
*
|
||||||
|
* Arguments: - uint8_t *sm: pointer to output signed message (allocated
|
||||||
|
* array with CRYPTO_BYTES + mlen bytes),
|
||||||
|
* can be equal to m
|
||||||
|
* - size_t *smlen: pointer to output length of signed
|
||||||
|
* message
|
||||||
|
* - const uint8_t *m: pointer to message to be signed
|
||||||
|
* - size_t mlen: length of message
|
||||||
|
* - const uint8_t *ctx: pointer to context string
|
||||||
|
* - size_t ctxlen: length of context string
|
||||||
|
* - const uint8_t *sk: pointer to bit-packed secret key
|
||||||
|
*
|
||||||
|
* Returns 0 (success)
|
||||||
|
**************************************************/
|
||||||
|
int crypto_sign(uint8_t *sm, size_t *smlen, const uint8_t *m, size_t mlen, const uint8_t *ctx, size_t ctxlen,
|
||||||
|
const uint8_t *sk)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
for(i = 0; i < mlen; ++i)
|
||||||
|
sm[CRYPTO_BYTES + mlen - 1 - i] = m[mlen - 1 - i];
|
||||||
|
ret = crypto_sign_signature(sm, smlen, sm + CRYPTO_BYTES, mlen, ctx, ctxlen, sk);
|
||||||
|
*smlen += mlen;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: crypto_sign_verify_internal
|
||||||
|
*
|
||||||
|
* Description: Verifies signature. Internal API.
|
||||||
|
*
|
||||||
|
* Arguments: - uint8_t *m: pointer to input signature
|
||||||
|
* - size_t siglen: length of signature
|
||||||
|
* - const uint8_t *m: pointer to message
|
||||||
|
* - size_t mlen: length of message
|
||||||
|
* - const uint8_t *pre: pointer to prefix string
|
||||||
|
* - size_t prelen: length of prefix string
|
||||||
|
* - const uint8_t *pk: pointer to bit-packed public key
|
||||||
|
*
|
||||||
|
* Returns 0 if signature could be verified correctly and -1 otherwise
|
||||||
|
**************************************************/
|
||||||
|
int crypto_sign_verify_internal(const uint8_t *sig, size_t siglen, const uint8_t *m, size_t mlen,
|
||||||
|
const uint8_t *pre, size_t prelen, const uint8_t *pk) {
|
||||||
|
unsigned int i, j, pos = 0;
|
||||||
|
/* polyw1_pack writes additional 14 bytes */
|
||||||
|
ALIGNED_UINT8(K*POLYW1_PACKEDBYTES+14) buf;
|
||||||
|
uint8_t mu[CRHBYTES];
|
||||||
|
const uint8_t *hint = sig + CTILDEBYTES + L*POLYZ_PACKEDBYTES;
|
||||||
|
polyvecl rowbuf[2];
|
||||||
|
polyvecl *row = rowbuf;
|
||||||
|
polyvecl z;
|
||||||
|
poly c, w1, h;
|
||||||
|
keccak_state state;
|
||||||
|
|
||||||
|
if(siglen != CRYPTO_BYTES)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* Compute CRH(H(rho, t1), pre, msg) */
|
||||||
|
shake256(mu, TRBYTES, pk, CRYPTO_PUBLICKEYBYTES);
|
||||||
|
shake256_init(&state);
|
||||||
|
shake256_absorb(&state, mu, CRHBYTES);
|
||||||
|
shake256_absorb(&state, pre, prelen);
|
||||||
|
shake256_absorb(&state, m, mlen);
|
||||||
|
shake256_finalize(&state);
|
||||||
|
shake256_squeeze(mu, CRHBYTES, &state);
|
||||||
|
|
||||||
|
/* Expand challenge */
|
||||||
|
poly_challenge(&c, sig);
|
||||||
|
poly_ntt(&c);
|
||||||
|
|
||||||
|
/* Unpack z; shortness follows from unpacking */
|
||||||
|
for(i = 0; i < L; i++) {
|
||||||
|
polyz_unpack(&z.vec[i], sig + CTILDEBYTES + i*POLYZ_PACKEDBYTES);
|
||||||
|
if(poly_chknorm(&z.vec[i], GAMMA1 - BETA))
|
||||||
|
return -1;
|
||||||
|
poly_ntt(&z.vec[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i = 0; i < K; i++) {
|
||||||
|
/* Expand matrix row */
|
||||||
|
polyvec_matrix_expand_row(&row, rowbuf, pk, i);
|
||||||
|
|
||||||
|
/* Compute i-th row of Az - c2^Dt1 */
|
||||||
|
polyvecl_pointwise_acc_montgomery(&w1, row, &z);
|
||||||
|
|
||||||
|
polyt1_unpack(&h, pk + SEEDBYTES + i*POLYT1_PACKEDBYTES);
|
||||||
|
poly_shiftl(&h);
|
||||||
|
poly_ntt(&h);
|
||||||
|
poly_pointwise_montgomery(&h, &c, &h);
|
||||||
|
|
||||||
|
poly_sub(&w1, &w1, &h);
|
||||||
|
poly_reduce(&w1);
|
||||||
|
poly_invntt_tomont(&w1);
|
||||||
|
|
||||||
|
/* Get hint polynomial and reconstruct w1 */
|
||||||
|
memset(h.vec, 0, sizeof(poly));
|
||||||
|
if(hint[OMEGA + i] < pos || hint[OMEGA + i] > OMEGA)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
for(j = pos; j < hint[OMEGA + i]; ++j) {
|
||||||
|
/* Coefficients are ordered for strong unforgeability */
|
||||||
|
if(j > pos && hint[j] <= hint[j-1]) return -1;
|
||||||
|
h.coeffs[hint[j]] = 1;
|
||||||
|
}
|
||||||
|
pos = hint[OMEGA + i];
|
||||||
|
|
||||||
|
poly_caddq(&w1);
|
||||||
|
poly_use_hint(&w1, &w1, &h);
|
||||||
|
polyw1_pack(buf.coeffs + i*POLYW1_PACKEDBYTES, &w1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Extra indices are zero for strong unforgeability */
|
||||||
|
for(j = pos; j < OMEGA; ++j)
|
||||||
|
if(hint[j]) return -1;
|
||||||
|
|
||||||
|
/* Call random oracle and verify challenge */
|
||||||
|
shake256_init(&state);
|
||||||
|
shake256_absorb(&state, mu, CRHBYTES);
|
||||||
|
shake256_absorb(&state, buf.coeffs, K*POLYW1_PACKEDBYTES);
|
||||||
|
shake256_finalize(&state);
|
||||||
|
shake256_squeeze(buf.coeffs, CTILDEBYTES, &state);
|
||||||
|
for(i = 0; i < CTILDEBYTES; ++i)
|
||||||
|
if(buf.coeffs[i] != sig[i])
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: crypto_sign_verify
|
||||||
|
*
|
||||||
|
* Description: Verifies signature.
|
||||||
|
*
|
||||||
|
* Arguments: - uint8_t *m: pointer to input signature
|
||||||
|
* - size_t siglen: length of signature
|
||||||
|
* - const uint8_t *m: pointer to message
|
||||||
|
* - size_t mlen: length of message
|
||||||
|
* - const uint8_t *ctx: pointer to context string
|
||||||
|
* - size_t ctxlen: length of context string
|
||||||
|
* - const uint8_t *pk: pointer to bit-packed public key
|
||||||
|
*
|
||||||
|
* Returns 0 if signature could be verified correctly and -1 otherwise
|
||||||
|
**************************************************/
|
||||||
|
int crypto_sign_verify(const uint8_t *sig, size_t siglen, const uint8_t *m, size_t mlen,
|
||||||
|
const uint8_t *ctx, size_t ctxlen, const uint8_t *pk)
|
||||||
|
{
|
||||||
|
uint8_t pre[257];
|
||||||
|
|
||||||
|
if(ctxlen > 255)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
pre[0] = 0;
|
||||||
|
pre[1] = ctxlen;
|
||||||
|
memcpy(&pre[2], ctx, ctxlen);
|
||||||
|
return crypto_sign_verify_internal(sig,siglen,m,mlen,pre,2+ctxlen,pk);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: crypto_sign_open
|
||||||
|
*
|
||||||
|
* Description: Verify signed message.
|
||||||
|
*
|
||||||
|
* Arguments: - uint8_t *m: pointer to output message (allocated
|
||||||
|
* array with smlen bytes), can be equal to sm
|
||||||
|
* - size_t *mlen: pointer to output length of message
|
||||||
|
* - const uint8_t *sm: pointer to signed message
|
||||||
|
* - size_t smlen: length of signed message
|
||||||
|
* - const uint8_t *ctx: pointer to context string
|
||||||
|
* - size_t ctxlen: length of context string
|
||||||
|
* - const uint8_t *pk: pointer to bit-packed public key
|
||||||
|
*
|
||||||
|
* Returns 0 if signed message could be verified correctly and -1 otherwise
|
||||||
|
**************************************************/
|
||||||
|
int crypto_sign_open(uint8_t *m, size_t *mlen, const uint8_t *sm, size_t smlen,
|
||||||
|
const uint8_t *ctx, size_t ctxlen, const uint8_t *pk) {
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
if(smlen < CRYPTO_BYTES)
|
||||||
|
goto badsig;
|
||||||
|
|
||||||
|
*mlen = smlen - CRYPTO_BYTES;
|
||||||
|
if(crypto_sign_verify(sm, CRYPTO_BYTES, sm + CRYPTO_BYTES, *mlen, ctx, ctxlen, pk))
|
||||||
|
goto badsig;
|
||||||
|
else {
|
||||||
|
/* All good, copy msg, return 0 */
|
||||||
|
for(i = 0; i < *mlen; ++i)
|
||||||
|
m[i] = sm[CRYPTO_BYTES + i];
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
badsig:
|
||||||
|
/* Signature verification failed */
|
||||||
|
*mlen = 0;
|
||||||
|
for(i = 0; i < smlen; ++i)
|
||||||
|
m[i] = 0;
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
1
src/crypto/pq/_d/avx2/sign.h
Symbolic link
1
src/crypto/pq/_d/avx2/sign.h
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
../ref/sign.h
|
||||||
1
src/crypto/pq/_d/avx2/symmetric-shake.c
Symbolic link
1
src/crypto/pq/_d/avx2/symmetric-shake.c
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
../ref/symmetric-shake.c
|
||||||
26
src/crypto/pq/_d/avx2/symmetric.h
Normal file
26
src/crypto/pq/_d/avx2/symmetric.h
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
#ifndef SYMMETRIC_H
|
||||||
|
#define SYMMETRIC_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "params.h"
|
||||||
|
|
||||||
|
#include "fips202.h"
|
||||||
|
|
||||||
|
typedef keccak_state stream128_state;
|
||||||
|
typedef keccak_state stream256_state;
|
||||||
|
|
||||||
|
#define dilithium_shake128_stream_init DILITHIUM_NAMESPACE(dilithium_shake128_stream_init)
|
||||||
|
void dilithium_shake128_stream_init(keccak_state *state, const uint8_t seed[SEEDBYTES], uint16_t nonce);
|
||||||
|
|
||||||
|
#define dilithium_shake256_stream_init DILITHIUM_NAMESPACE(dilithium_shake256_stream_init)
|
||||||
|
void dilithium_shake256_stream_init(keccak_state *state, const uint8_t seed[CRHBYTES], uint16_t nonce);
|
||||||
|
|
||||||
|
#define STREAM128_BLOCKBYTES SHAKE128_RATE
|
||||||
|
#define STREAM256_BLOCKBYTES SHAKE256_RATE
|
||||||
|
|
||||||
|
#define stream128_init(STATE, SEED, NONCE) dilithium_shake128_stream_init(STATE, SEED, NONCE)
|
||||||
|
#define stream128_squeezeblocks(OUT, OUTBLOCKS, STATE) shake128_squeezeblocks(OUT, OUTBLOCKS, STATE)
|
||||||
|
#define stream256_init(STATE, SEED, NONCE) dilithium_shake256_stream_init(STATE, SEED, NONCE)
|
||||||
|
#define stream256_squeezeblocks(OUT, OUTBLOCKS, STATE) shake256_squeezeblocks(OUT, OUTBLOCKS, STATE)
|
||||||
|
|
||||||
|
#endif
|
||||||
10
src/crypto/pq/_d/avx2/test/.gitignore
vendored
Normal file
10
src/crypto/pq/_d/avx2/test/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
test_dilithium2
|
||||||
|
test_dilithium3
|
||||||
|
test_dilithium5
|
||||||
|
test_vectors2
|
||||||
|
test_vectors3
|
||||||
|
test_vectors5
|
||||||
|
test_speed2
|
||||||
|
test_speed3
|
||||||
|
test_speed5
|
||||||
|
test_mul
|
||||||
1
src/crypto/pq/_d/avx2/test/cpucycles.c
Symbolic link
1
src/crypto/pq/_d/avx2/test/cpucycles.c
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
../../ref/test/cpucycles.c
|
||||||
1
src/crypto/pq/_d/avx2/test/cpucycles.h
Symbolic link
1
src/crypto/pq/_d/avx2/test/cpucycles.h
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
../../ref/test/cpucycles.h
|
||||||
1
src/crypto/pq/_d/avx2/test/speed_print.c
Symbolic link
1
src/crypto/pq/_d/avx2/test/speed_print.c
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
../../ref/test/speed_print.c
|
||||||
1
src/crypto/pq/_d/avx2/test/speed_print.h
Symbolic link
1
src/crypto/pq/_d/avx2/test/speed_print.h
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
../../ref/test/speed_print.h
|
||||||
1
src/crypto/pq/_d/avx2/test/test_dilithium.c
Symbolic link
1
src/crypto/pq/_d/avx2/test/test_dilithium.c
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
../../ref/test/test_dilithium.c
|
||||||
1
src/crypto/pq/_d/avx2/test/test_mul.c
Symbolic link
1
src/crypto/pq/_d/avx2/test/test_mul.c
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
../../ref/test/test_mul.c
|
||||||
1
src/crypto/pq/_d/avx2/test/test_speed.c
Symbolic link
1
src/crypto/pq/_d/avx2/test/test_speed.c
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
../../ref/test/test_speed.c
|
||||||
275
src/crypto/pq/_d/avx2/test/test_vectors.c
Normal file
275
src/crypto/pq/_d/avx2/test/test_vectors.c
Normal file
|
|
@ -0,0 +1,275 @@
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "../randombytes.h"
|
||||||
|
#include "../fips202.h"
|
||||||
|
#include "../params.h"
|
||||||
|
#include "../sign.h"
|
||||||
|
#include "../poly.h"
|
||||||
|
#include "../polyvec.h"
|
||||||
|
#include "../packing.h"
|
||||||
|
|
||||||
|
#define MLEN 32
|
||||||
|
#define CTXLEN 13
|
||||||
|
#define NVECTORS 10000
|
||||||
|
|
||||||
|
static unsigned int nttidx(unsigned int k) {
|
||||||
|
unsigned int r;
|
||||||
|
r = k/64*64;
|
||||||
|
k %= 64;
|
||||||
|
r += k/8;
|
||||||
|
k %= 8;
|
||||||
|
r += k*8;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initital state after absorbing empty string
|
||||||
|
* Permute before squeeze is achieved by setting pos to SHAKE128_RATE */
|
||||||
|
static keccak_state rngstate = {{0x1F, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, (1ULL << 63), 0, 0, 0, 0}, SHAKE128_RATE};
|
||||||
|
|
||||||
|
void randombytes(uint8_t *x,size_t xlen) {
|
||||||
|
shake128_squeeze(x, xlen, &rngstate);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
unsigned int i, j, k, l;
|
||||||
|
uint8_t pk[CRYPTO_PUBLICKEYBYTES];
|
||||||
|
uint8_t sk[CRYPTO_SECRETKEYBYTES];
|
||||||
|
uint8_t sig[CRYPTO_BYTES];
|
||||||
|
uint8_t m[MLEN];
|
||||||
|
uint8_t ctx[CTXLEN] = {0};
|
||||||
|
uint8_t seed[CRHBYTES];
|
||||||
|
uint8_t buf[CRYPTO_SECRETKEYBYTES];
|
||||||
|
size_t siglen;
|
||||||
|
poly c, tmp;
|
||||||
|
polyvecl s, y, mat[K];
|
||||||
|
polyveck w, w1, w0, t1, t0;
|
||||||
|
|
||||||
|
snprintf((char*)ctx,CTXLEN,"test_vectors");
|
||||||
|
|
||||||
|
for(i = 0; i < NVECTORS; ++i) {
|
||||||
|
printf("count = %u\n", i);
|
||||||
|
|
||||||
|
randombytes(m, MLEN);
|
||||||
|
printf("m = ");
|
||||||
|
for(j = 0; j < MLEN; ++j)
|
||||||
|
printf("%02x", m[j]);
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
crypto_sign_keypair(pk, sk);
|
||||||
|
shake256(buf, 32, pk, CRYPTO_PUBLICKEYBYTES);
|
||||||
|
printf("pk = ");
|
||||||
|
for(j = 0; j < 32; ++j)
|
||||||
|
printf("%02x", buf[j]);
|
||||||
|
printf("\n");
|
||||||
|
shake256(buf, 32, sk, CRYPTO_SECRETKEYBYTES);
|
||||||
|
printf("sk = ");
|
||||||
|
for(j = 0; j < 32; ++j)
|
||||||
|
printf("%02x", buf[j]);
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
crypto_sign_signature(sig, &siglen, m, MLEN, ctx, CTXLEN, sk);
|
||||||
|
shake256(buf, 32, sig, CRYPTO_BYTES);
|
||||||
|
printf("sig = ");
|
||||||
|
for(j = 0; j < 32; ++j)
|
||||||
|
printf("%02x", buf[j]);
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
if(crypto_sign_verify(sig, siglen, m, MLEN, ctx, CTXLEN, pk))
|
||||||
|
fprintf(stderr,"Signature verification failed!\n");
|
||||||
|
|
||||||
|
randombytes(seed, sizeof(seed));
|
||||||
|
printf("seed = ");
|
||||||
|
for(j = 0; j < sizeof(seed); ++j)
|
||||||
|
printf("%02X", seed[j]);
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
polyvec_matrix_expand(mat, seed);
|
||||||
|
printf("A = ([");
|
||||||
|
for(j = 0; j < K; ++j) {
|
||||||
|
for(k = 0; k < L; ++k) {
|
||||||
|
for(l = 0; l < N; ++l) {
|
||||||
|
printf("%8d", mat[j].vec[k].coeffs[nttidx(l)]);
|
||||||
|
if(l < N-1) printf(", ");
|
||||||
|
else if(k < L-1) printf("], [");
|
||||||
|
else if(j < K-1) printf("];\n [");
|
||||||
|
else printf("])\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if L == 4
|
||||||
|
poly_uniform_eta_4x(&s.vec[0], &s.vec[1], &s.vec[2], &s.vec[3], seed, 0, 1, 2, 3);
|
||||||
|
#elif L == 5
|
||||||
|
poly_uniform_eta_4x(&s.vec[0], &s.vec[1], &s.vec[2], &s.vec[3], seed, 0, 1, 2, 3);
|
||||||
|
poly_uniform_eta(&s.vec[4], seed, 4);
|
||||||
|
#elif L == 7
|
||||||
|
poly_uniform_eta_4x(&s.vec[0], &s.vec[1], &s.vec[2], &s.vec[3], seed, 0, 1, 2, 3);
|
||||||
|
poly_uniform_eta_4x(&s.vec[4], &s.vec[5], &s.vec[6], &tmp, seed, 4, 5, 6, 7);
|
||||||
|
#else
|
||||||
|
#error
|
||||||
|
#endif
|
||||||
|
|
||||||
|
polyeta_pack(buf, &s.vec[0]);
|
||||||
|
polyeta_unpack(&tmp, buf);
|
||||||
|
for(j = 0; j < N; ++j)
|
||||||
|
if(tmp.coeffs[j] != s.vec[0].coeffs[j])
|
||||||
|
fprintf(stderr, "ERROR in polyeta_(un)pack!\n");
|
||||||
|
|
||||||
|
if(polyvecl_chknorm(&s, ETA+1))
|
||||||
|
fprintf(stderr, "ERROR in polyvecl_chknorm(&s ,ETA+1)!\n");
|
||||||
|
|
||||||
|
printf("s = ([");
|
||||||
|
for(j = 0; j < L; ++j) {
|
||||||
|
for(k = 0; k < N; ++k) {
|
||||||
|
printf("%3d", s.vec[j].coeffs[k]);
|
||||||
|
if(k < N-1) printf(", ");
|
||||||
|
else if(j < L-1) printf("],\n [");
|
||||||
|
else printf("])\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if L == 4
|
||||||
|
poly_uniform_gamma1_4x(&y.vec[0], &y.vec[1], &y.vec[2], &y.vec[3], seed, 0, 1, 2, 3);
|
||||||
|
#elif L == 5
|
||||||
|
poly_uniform_gamma1_4x(&y.vec[0], &y.vec[1], &y.vec[2], &y.vec[3], seed, 0, 1, 2, 3);
|
||||||
|
poly_uniform_gamma1(&y.vec[4], seed, 4);
|
||||||
|
#elif L == 7
|
||||||
|
poly_uniform_gamma1_4x(&y.vec[0], &y.vec[1], &y.vec[2], &y.vec[3], seed, 0, 1, 2, 3);
|
||||||
|
poly_uniform_gamma1_4x(&y.vec[4], &y.vec[5], &y.vec[6], &tmp, seed, 4, 5, 6, 7);
|
||||||
|
#else
|
||||||
|
#error
|
||||||
|
#endif
|
||||||
|
|
||||||
|
polyz_pack(buf, &y.vec[0]);
|
||||||
|
polyz_unpack(&tmp, buf);
|
||||||
|
for(j = 0; j < N; ++j)
|
||||||
|
if(tmp.coeffs[j] != y.vec[0].coeffs[j])
|
||||||
|
fprintf(stderr, "ERROR in polyz_(un)pack!\n");
|
||||||
|
|
||||||
|
if(polyvecl_chknorm(&y, GAMMA1+1))
|
||||||
|
fprintf(stderr, "ERROR in polyvecl_chknorm(&y, GAMMA1)!\n");
|
||||||
|
|
||||||
|
printf("y = ([");
|
||||||
|
for(j = 0; j < L; ++j) {
|
||||||
|
for(k = 0; k < N; ++k) {
|
||||||
|
printf("%8d", y.vec[j].coeffs[k]);
|
||||||
|
if(k < N-1) printf(", ");
|
||||||
|
else if(j < L-1) printf("],\n [");
|
||||||
|
else printf("])\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
polyvecl_ntt(&y);
|
||||||
|
polyvec_matrix_pointwise_montgomery(&w, mat, &y);
|
||||||
|
polyveck_invntt_tomont(&w);
|
||||||
|
polyveck_caddq(&w);
|
||||||
|
polyveck_decompose(&w1, &w0, &w);
|
||||||
|
|
||||||
|
for(j = 0; j < N; ++j) {
|
||||||
|
tmp.coeffs[j] = w1.vec[0].coeffs[j]*2*GAMMA2 + w0.vec[0].coeffs[j];
|
||||||
|
if(tmp.coeffs[j] < 0) tmp.coeffs[j] += Q;
|
||||||
|
if(tmp.coeffs[j] != w.vec[0].coeffs[j])
|
||||||
|
fprintf(stderr, "ERROR in poly_decompose!\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
polyw1_pack(buf, &w1.vec[0]);
|
||||||
|
#if GAMMA2 == (Q-1)/32
|
||||||
|
for(j = 0; j < N/2; ++j) {
|
||||||
|
tmp.coeffs[2*j+0] = buf[j] & 0xF;
|
||||||
|
tmp.coeffs[2*j+1] = buf[j] >> 4;
|
||||||
|
if(tmp.coeffs[2*j+0] != w1.vec[0].coeffs[2*j+0]
|
||||||
|
|| tmp.coeffs[2*j+1] != w1.vec[0].coeffs[2*j+1])
|
||||||
|
fprintf(stderr, "ERROR in polyw1_pack!\n");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if GAMMA2 == (Q-1)/32
|
||||||
|
if(polyveck_chknorm(&w1, 16))
|
||||||
|
fprintf(stderr, "ERROR in polyveck_chknorm(&w1, 16)!\n");
|
||||||
|
#elif GAMMA2 == (Q-1)/88
|
||||||
|
if(polyveck_chknorm(&w1, 44))
|
||||||
|
fprintf(stderr, "ERROR in polyveck_chknorm(&w1, 44)!\n");
|
||||||
|
#endif
|
||||||
|
if(polyveck_chknorm(&w0, GAMMA2 + 1))
|
||||||
|
fprintf(stderr, "ERROR in polyveck_chknorm(&w0, GAMMA2+1)!\n");
|
||||||
|
|
||||||
|
printf("w1 = ([");
|
||||||
|
for(j = 0; j < K; ++j) {
|
||||||
|
for(k = 0; k < N; ++k) {
|
||||||
|
printf("%2d", w1.vec[j].coeffs[k]);
|
||||||
|
if(k < N-1) printf(", ");
|
||||||
|
else if(j < K-1) printf("],\n [");
|
||||||
|
else printf("])\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("w0 = ([");
|
||||||
|
for(j = 0; j < K; ++j) {
|
||||||
|
for(k = 0; k < N; ++k) {
|
||||||
|
printf("%8d", w0.vec[j].coeffs[k]);
|
||||||
|
if(k < N-1) printf(", ");
|
||||||
|
else if(j < K-1) printf("],\n [");
|
||||||
|
else printf("])\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
polyveck_power2round(&t1, &t0, &w);
|
||||||
|
|
||||||
|
for(j = 0; j < N; ++j) {
|
||||||
|
tmp.coeffs[j] = (t1.vec[0].coeffs[j] << D) + t0.vec[0].coeffs[j];
|
||||||
|
if(tmp.coeffs[j] != w.vec[0].coeffs[j])
|
||||||
|
fprintf(stderr, "ERROR in poly_power2round!\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
polyt1_pack(buf, &t1.vec[0]);
|
||||||
|
polyt1_unpack(&tmp, buf);
|
||||||
|
for(j = 0; j < N; ++j) {
|
||||||
|
if(tmp.coeffs[j] != t1.vec[0].coeffs[j])
|
||||||
|
fprintf(stderr, "ERROR in polyt1_(un)pack!\n");
|
||||||
|
}
|
||||||
|
polyt0_pack(buf, &t0.vec[0]);
|
||||||
|
polyt0_unpack(&tmp, buf);
|
||||||
|
for(j = 0; j < N; ++j) {
|
||||||
|
if(tmp.coeffs[j] != t0.vec[0].coeffs[j])
|
||||||
|
fprintf(stderr, "ERROR in polyt0_(un)pack!\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(polyveck_chknorm(&t1, 1024))
|
||||||
|
fprintf(stderr, "ERROR in polyveck_chknorm(&t1, 1024)!\n");
|
||||||
|
if(polyveck_chknorm(&t0, (1U << (D-1)) + 1))
|
||||||
|
fprintf(stderr, "ERROR in polyveck_chknorm(&t0, (1 << (D-1)) + 1)!\n");
|
||||||
|
|
||||||
|
printf("t1 = ([");
|
||||||
|
for(j = 0; j < K; ++j) {
|
||||||
|
for(k = 0; k < N; ++k) {
|
||||||
|
printf("%3d", t1.vec[j].coeffs[k]);
|
||||||
|
if(k < N-1) printf(", ");
|
||||||
|
else if(j < K-1) printf("],\n [");
|
||||||
|
else printf("])\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("t0 = ([");
|
||||||
|
for(j = 0; j < K; ++j) {
|
||||||
|
for(k = 0; k < N; ++k) {
|
||||||
|
printf("%5d", t0.vec[j].coeffs[k]);
|
||||||
|
if(k < N-1) printf(", ");
|
||||||
|
else if(j < K-1) printf("],\n [");
|
||||||
|
else printf("])\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
poly_challenge(&c, seed);
|
||||||
|
printf("c = [");
|
||||||
|
for(j = 0; j < N; ++j) {
|
||||||
|
printf("%2d", c.coeffs[j]);
|
||||||
|
if(j < N-1) printf(", ");
|
||||||
|
else printf("]\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
2
src/crypto/pq/_d/ref/.gitignore
vendored
Normal file
2
src/crypto/pq/_d/ref/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
*.so
|
||||||
|
*.o
|
||||||
98
src/crypto/pq/_d/ref/api.h
Normal file
98
src/crypto/pq/_d/ref/api.h
Normal file
|
|
@ -0,0 +1,98 @@
|
||||||
|
#ifndef API_H
|
||||||
|
#define API_H
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define pqcrystals_dilithium2_PUBLICKEYBYTES 1312
|
||||||
|
#define pqcrystals_dilithium2_SECRETKEYBYTES 2560
|
||||||
|
#define pqcrystals_dilithium2_BYTES 2420
|
||||||
|
|
||||||
|
#define pqcrystals_dilithium2_ref_PUBLICKEYBYTES pqcrystals_dilithium2_PUBLICKEYBYTES
|
||||||
|
#define pqcrystals_dilithium2_ref_SECRETKEYBYTES pqcrystals_dilithium2_SECRETKEYBYTES
|
||||||
|
#define pqcrystals_dilithium2_ref_BYTES pqcrystals_dilithium2_BYTES
|
||||||
|
|
||||||
|
int pqcrystals_dilithium2_ref_keypair(uint8_t *pk, uint8_t *sk);
|
||||||
|
|
||||||
|
int pqcrystals_dilithium2_ref_signature(uint8_t *sig, size_t *siglen,
|
||||||
|
const uint8_t *m, size_t mlen,
|
||||||
|
const uint8_t *ctx, size_t ctxlen,
|
||||||
|
const uint8_t *sk);
|
||||||
|
|
||||||
|
int pqcrystals_dilithium2_ref(uint8_t *sm, size_t *smlen,
|
||||||
|
const uint8_t *m, size_t mlen,
|
||||||
|
const uint8_t *ctx, size_t ctxlen,
|
||||||
|
const uint8_t *sk);
|
||||||
|
|
||||||
|
int pqcrystals_dilithium2_ref_verify(const uint8_t *sig, size_t siglen,
|
||||||
|
const uint8_t *m, size_t mlen,
|
||||||
|
const uint8_t *ctx, size_t ctxlen,
|
||||||
|
const uint8_t *pk);
|
||||||
|
|
||||||
|
int pqcrystals_dilithium2_ref_open(uint8_t *m, size_t *mlen,
|
||||||
|
const uint8_t *sm, size_t smlen,
|
||||||
|
const uint8_t *ctx, size_t ctxlen,
|
||||||
|
const uint8_t *pk);
|
||||||
|
|
||||||
|
#define pqcrystals_dilithium3_PUBLICKEYBYTES 1952
|
||||||
|
#define pqcrystals_dilithium3_SECRETKEYBYTES 4032
|
||||||
|
#define pqcrystals_dilithium3_BYTES 3309
|
||||||
|
|
||||||
|
#define pqcrystals_dilithium3_ref_PUBLICKEYBYTES pqcrystals_dilithium3_PUBLICKEYBYTES
|
||||||
|
#define pqcrystals_dilithium3_ref_SECRETKEYBYTES pqcrystals_dilithium3_SECRETKEYBYTES
|
||||||
|
#define pqcrystals_dilithium3_ref_BYTES pqcrystals_dilithium3_BYTES
|
||||||
|
|
||||||
|
int pqcrystals_dilithium3_ref_keypair(uint8_t *pk, uint8_t *sk);
|
||||||
|
|
||||||
|
int pqcrystals_dilithium3_ref_signature(uint8_t *sig, size_t *siglen,
|
||||||
|
const uint8_t *m, size_t mlen,
|
||||||
|
const uint8_t *ctx, size_t ctxlen,
|
||||||
|
const uint8_t *sk);
|
||||||
|
|
||||||
|
int pqcrystals_dilithium3_ref(uint8_t *sm, size_t *smlen,
|
||||||
|
const uint8_t *m, size_t mlen,
|
||||||
|
const uint8_t *ctx, size_t ctxlen,
|
||||||
|
const uint8_t *sk);
|
||||||
|
|
||||||
|
int pqcrystals_dilithium3_ref_verify(const uint8_t *sig, size_t siglen,
|
||||||
|
const uint8_t *m, size_t mlen,
|
||||||
|
const uint8_t *ctx, size_t ctxlen,
|
||||||
|
const uint8_t *pk);
|
||||||
|
|
||||||
|
int pqcrystals_dilithium3_ref_open(uint8_t *m, size_t *mlen,
|
||||||
|
const uint8_t *sm, size_t smlen,
|
||||||
|
const uint8_t *ctx, size_t ctxlen,
|
||||||
|
const uint8_t *pk);
|
||||||
|
|
||||||
|
#define pqcrystals_dilithium5_PUBLICKEYBYTES 2592
|
||||||
|
#define pqcrystals_dilithium5_SECRETKEYBYTES 4896
|
||||||
|
#define pqcrystals_dilithium5_BYTES 4627
|
||||||
|
|
||||||
|
#define pqcrystals_dilithium5_ref_PUBLICKEYBYTES pqcrystals_dilithium5_PUBLICKEYBYTES
|
||||||
|
#define pqcrystals_dilithium5_ref_SECRETKEYBYTES pqcrystals_dilithium5_SECRETKEYBYTES
|
||||||
|
#define pqcrystals_dilithium5_ref_BYTES pqcrystals_dilithium5_BYTES
|
||||||
|
|
||||||
|
int pqcrystals_dilithium5_ref_keypair(uint8_t *pk, uint8_t *sk);
|
||||||
|
|
||||||
|
int pqcrystals_dilithium5_ref_signature(uint8_t *sig, size_t *siglen,
|
||||||
|
const uint8_t *m, size_t mlen,
|
||||||
|
const uint8_t *ctx, size_t ctxlen,
|
||||||
|
const uint8_t *sk);
|
||||||
|
|
||||||
|
int pqcrystals_dilithium5_ref(uint8_t *sm, size_t *smlen,
|
||||||
|
const uint8_t *m, size_t mlen,
|
||||||
|
const uint8_t *ctx, size_t ctxlen,
|
||||||
|
const uint8_t *sk);
|
||||||
|
|
||||||
|
int pqcrystals_dilithium5_ref_verify(const uint8_t *sig, size_t siglen,
|
||||||
|
const uint8_t *m, size_t mlen,
|
||||||
|
const uint8_t *ctx, size_t ctxlen,
|
||||||
|
const uint8_t *pk);
|
||||||
|
|
||||||
|
int pqcrystals_dilithium5_ref_open(uint8_t *m, size_t *mlen,
|
||||||
|
const uint8_t *sm, size_t smlen,
|
||||||
|
const uint8_t *ctx, size_t ctxlen,
|
||||||
|
const uint8_t *pk);
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
27
src/crypto/pq/_d/ref/config.h
Normal file
27
src/crypto/pq/_d/ref/config.h
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
#ifndef CONFIG_H
|
||||||
|
#define CONFIG_H
|
||||||
|
|
||||||
|
//#define DILITHIUM_MODE 2
|
||||||
|
#define DILITHIUM_RANDOMIZED_SIGNING
|
||||||
|
//#define USE_RDPMC
|
||||||
|
//#define DBENCH
|
||||||
|
|
||||||
|
#ifndef DILITHIUM_MODE
|
||||||
|
#define DILITHIUM_MODE 2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if DILITHIUM_MODE == 2
|
||||||
|
#define CRYPTO_ALGNAME "Dilithium2"
|
||||||
|
#define DILITHIUM_NAMESPACETOP pqcrystals_dilithium2_ref
|
||||||
|
#define DILITHIUM_NAMESPACE(s) pqcrystals_dilithium2_ref_##s
|
||||||
|
#elif DILITHIUM_MODE == 3
|
||||||
|
#define CRYPTO_ALGNAME "Dilithium3"
|
||||||
|
#define DILITHIUM_NAMESPACETOP pqcrystals_dilithium3_ref
|
||||||
|
#define DILITHIUM_NAMESPACE(s) pqcrystals_dilithium3_ref_##s
|
||||||
|
#elif DILITHIUM_MODE == 5
|
||||||
|
#define CRYPTO_ALGNAME "Dilithium5"
|
||||||
|
#define DILITHIUM_NAMESPACETOP pqcrystals_dilithium5_ref
|
||||||
|
#define DILITHIUM_NAMESPACE(s) pqcrystals_dilithium5_ref_##s
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
774
src/crypto/pq/_d/ref/fips202.c
Normal file
774
src/crypto/pq/_d/ref/fips202.c
Normal file
|
|
@ -0,0 +1,774 @@
|
||||||
|
/* Based on the public domain implementation in crypto_hash/keccakc512/simple/ from
|
||||||
|
* http://bench.cr.yp.to/supercop.html by Ronny Van Keer and the public domain "TweetFips202"
|
||||||
|
* implementation from https://twitter.com/tweetfips202 by Gilles Van Assche, Daniel J. Bernstein,
|
||||||
|
* and Peter Schwabe */
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "fips202.h"
|
||||||
|
|
||||||
|
#define NROUNDS 24
|
||||||
|
#define ROL(a, offset) ((a << offset) ^ (a >> (64-offset)))
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: load64
|
||||||
|
*
|
||||||
|
* Description: Load 8 bytes into uint64_t in little-endian order
|
||||||
|
*
|
||||||
|
* Arguments: - const uint8_t *x: pointer to input byte array
|
||||||
|
*
|
||||||
|
* Returns the loaded 64-bit unsigned integer
|
||||||
|
**************************************************/
|
||||||
|
static uint64_t load64(const uint8_t x[8]) {
|
||||||
|
unsigned int i;
|
||||||
|
uint64_t r = 0;
|
||||||
|
|
||||||
|
for(i=0;i<8;i++)
|
||||||
|
r |= (uint64_t)x[i] << 8*i;
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: store64
|
||||||
|
*
|
||||||
|
* Description: Store a 64-bit integer to array of 8 bytes in little-endian order
|
||||||
|
*
|
||||||
|
* Arguments: - uint8_t *x: pointer to the output byte array (allocated)
|
||||||
|
* - uint64_t u: input 64-bit unsigned integer
|
||||||
|
**************************************************/
|
||||||
|
static void store64(uint8_t x[8], uint64_t u) {
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for(i=0;i<8;i++)
|
||||||
|
x[i] = u >> 8*i;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Keccak round constants */
|
||||||
|
const uint64_t KeccakF_RoundConstants[NROUNDS] = {
|
||||||
|
(uint64_t)0x0000000000000001ULL,
|
||||||
|
(uint64_t)0x0000000000008082ULL,
|
||||||
|
(uint64_t)0x800000000000808aULL,
|
||||||
|
(uint64_t)0x8000000080008000ULL,
|
||||||
|
(uint64_t)0x000000000000808bULL,
|
||||||
|
(uint64_t)0x0000000080000001ULL,
|
||||||
|
(uint64_t)0x8000000080008081ULL,
|
||||||
|
(uint64_t)0x8000000000008009ULL,
|
||||||
|
(uint64_t)0x000000000000008aULL,
|
||||||
|
(uint64_t)0x0000000000000088ULL,
|
||||||
|
(uint64_t)0x0000000080008009ULL,
|
||||||
|
(uint64_t)0x000000008000000aULL,
|
||||||
|
(uint64_t)0x000000008000808bULL,
|
||||||
|
(uint64_t)0x800000000000008bULL,
|
||||||
|
(uint64_t)0x8000000000008089ULL,
|
||||||
|
(uint64_t)0x8000000000008003ULL,
|
||||||
|
(uint64_t)0x8000000000008002ULL,
|
||||||
|
(uint64_t)0x8000000000000080ULL,
|
||||||
|
(uint64_t)0x000000000000800aULL,
|
||||||
|
(uint64_t)0x800000008000000aULL,
|
||||||
|
(uint64_t)0x8000000080008081ULL,
|
||||||
|
(uint64_t)0x8000000000008080ULL,
|
||||||
|
(uint64_t)0x0000000080000001ULL,
|
||||||
|
(uint64_t)0x8000000080008008ULL
|
||||||
|
};
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: KeccakF1600_StatePermute
|
||||||
|
*
|
||||||
|
* Description: The Keccak F1600 Permutation
|
||||||
|
*
|
||||||
|
* Arguments: - uint64_t *state: pointer to input/output Keccak state
|
||||||
|
**************************************************/
|
||||||
|
static void KeccakF1600_StatePermute(uint64_t state[25])
|
||||||
|
{
|
||||||
|
int round;
|
||||||
|
|
||||||
|
uint64_t Aba, Abe, Abi, Abo, Abu;
|
||||||
|
uint64_t Aga, Age, Agi, Ago, Agu;
|
||||||
|
uint64_t Aka, Ake, Aki, Ako, Aku;
|
||||||
|
uint64_t Ama, Ame, Ami, Amo, Amu;
|
||||||
|
uint64_t Asa, Ase, Asi, Aso, Asu;
|
||||||
|
uint64_t BCa, BCe, BCi, BCo, BCu;
|
||||||
|
uint64_t Da, De, Di, Do, Du;
|
||||||
|
uint64_t Eba, Ebe, Ebi, Ebo, Ebu;
|
||||||
|
uint64_t Ega, Ege, Egi, Ego, Egu;
|
||||||
|
uint64_t Eka, Eke, Eki, Eko, Eku;
|
||||||
|
uint64_t Ema, Eme, Emi, Emo, Emu;
|
||||||
|
uint64_t Esa, Ese, Esi, Eso, Esu;
|
||||||
|
|
||||||
|
//copyFromState(A, state)
|
||||||
|
Aba = state[ 0];
|
||||||
|
Abe = state[ 1];
|
||||||
|
Abi = state[ 2];
|
||||||
|
Abo = state[ 3];
|
||||||
|
Abu = state[ 4];
|
||||||
|
Aga = state[ 5];
|
||||||
|
Age = state[ 6];
|
||||||
|
Agi = state[ 7];
|
||||||
|
Ago = state[ 8];
|
||||||
|
Agu = state[ 9];
|
||||||
|
Aka = state[10];
|
||||||
|
Ake = state[11];
|
||||||
|
Aki = state[12];
|
||||||
|
Ako = state[13];
|
||||||
|
Aku = state[14];
|
||||||
|
Ama = state[15];
|
||||||
|
Ame = state[16];
|
||||||
|
Ami = state[17];
|
||||||
|
Amo = state[18];
|
||||||
|
Amu = state[19];
|
||||||
|
Asa = state[20];
|
||||||
|
Ase = state[21];
|
||||||
|
Asi = state[22];
|
||||||
|
Aso = state[23];
|
||||||
|
Asu = state[24];
|
||||||
|
|
||||||
|
for(round = 0; round < NROUNDS; round += 2) {
|
||||||
|
// prepareTheta
|
||||||
|
BCa = Aba^Aga^Aka^Ama^Asa;
|
||||||
|
BCe = Abe^Age^Ake^Ame^Ase;
|
||||||
|
BCi = Abi^Agi^Aki^Ami^Asi;
|
||||||
|
BCo = Abo^Ago^Ako^Amo^Aso;
|
||||||
|
BCu = Abu^Agu^Aku^Amu^Asu;
|
||||||
|
|
||||||
|
//thetaRhoPiChiIotaPrepareTheta(round, A, E)
|
||||||
|
Da = BCu^ROL(BCe, 1);
|
||||||
|
De = BCa^ROL(BCi, 1);
|
||||||
|
Di = BCe^ROL(BCo, 1);
|
||||||
|
Do = BCi^ROL(BCu, 1);
|
||||||
|
Du = BCo^ROL(BCa, 1);
|
||||||
|
|
||||||
|
Aba ^= Da;
|
||||||
|
BCa = Aba;
|
||||||
|
Age ^= De;
|
||||||
|
BCe = ROL(Age, 44);
|
||||||
|
Aki ^= Di;
|
||||||
|
BCi = ROL(Aki, 43);
|
||||||
|
Amo ^= Do;
|
||||||
|
BCo = ROL(Amo, 21);
|
||||||
|
Asu ^= Du;
|
||||||
|
BCu = ROL(Asu, 14);
|
||||||
|
Eba = BCa ^((~BCe)& BCi );
|
||||||
|
Eba ^= (uint64_t)KeccakF_RoundConstants[round];
|
||||||
|
Ebe = BCe ^((~BCi)& BCo );
|
||||||
|
Ebi = BCi ^((~BCo)& BCu );
|
||||||
|
Ebo = BCo ^((~BCu)& BCa );
|
||||||
|
Ebu = BCu ^((~BCa)& BCe );
|
||||||
|
|
||||||
|
Abo ^= Do;
|
||||||
|
BCa = ROL(Abo, 28);
|
||||||
|
Agu ^= Du;
|
||||||
|
BCe = ROL(Agu, 20);
|
||||||
|
Aka ^= Da;
|
||||||
|
BCi = ROL(Aka, 3);
|
||||||
|
Ame ^= De;
|
||||||
|
BCo = ROL(Ame, 45);
|
||||||
|
Asi ^= Di;
|
||||||
|
BCu = ROL(Asi, 61);
|
||||||
|
Ega = BCa ^((~BCe)& BCi );
|
||||||
|
Ege = BCe ^((~BCi)& BCo );
|
||||||
|
Egi = BCi ^((~BCo)& BCu );
|
||||||
|
Ego = BCo ^((~BCu)& BCa );
|
||||||
|
Egu = BCu ^((~BCa)& BCe );
|
||||||
|
|
||||||
|
Abe ^= De;
|
||||||
|
BCa = ROL(Abe, 1);
|
||||||
|
Agi ^= Di;
|
||||||
|
BCe = ROL(Agi, 6);
|
||||||
|
Ako ^= Do;
|
||||||
|
BCi = ROL(Ako, 25);
|
||||||
|
Amu ^= Du;
|
||||||
|
BCo = ROL(Amu, 8);
|
||||||
|
Asa ^= Da;
|
||||||
|
BCu = ROL(Asa, 18);
|
||||||
|
Eka = BCa ^((~BCe)& BCi );
|
||||||
|
Eke = BCe ^((~BCi)& BCo );
|
||||||
|
Eki = BCi ^((~BCo)& BCu );
|
||||||
|
Eko = BCo ^((~BCu)& BCa );
|
||||||
|
Eku = BCu ^((~BCa)& BCe );
|
||||||
|
|
||||||
|
Abu ^= Du;
|
||||||
|
BCa = ROL(Abu, 27);
|
||||||
|
Aga ^= Da;
|
||||||
|
BCe = ROL(Aga, 36);
|
||||||
|
Ake ^= De;
|
||||||
|
BCi = ROL(Ake, 10);
|
||||||
|
Ami ^= Di;
|
||||||
|
BCo = ROL(Ami, 15);
|
||||||
|
Aso ^= Do;
|
||||||
|
BCu = ROL(Aso, 56);
|
||||||
|
Ema = BCa ^((~BCe)& BCi );
|
||||||
|
Eme = BCe ^((~BCi)& BCo );
|
||||||
|
Emi = BCi ^((~BCo)& BCu );
|
||||||
|
Emo = BCo ^((~BCu)& BCa );
|
||||||
|
Emu = BCu ^((~BCa)& BCe );
|
||||||
|
|
||||||
|
Abi ^= Di;
|
||||||
|
BCa = ROL(Abi, 62);
|
||||||
|
Ago ^= Do;
|
||||||
|
BCe = ROL(Ago, 55);
|
||||||
|
Aku ^= Du;
|
||||||
|
BCi = ROL(Aku, 39);
|
||||||
|
Ama ^= Da;
|
||||||
|
BCo = ROL(Ama, 41);
|
||||||
|
Ase ^= De;
|
||||||
|
BCu = ROL(Ase, 2);
|
||||||
|
Esa = BCa ^((~BCe)& BCi );
|
||||||
|
Ese = BCe ^((~BCi)& BCo );
|
||||||
|
Esi = BCi ^((~BCo)& BCu );
|
||||||
|
Eso = BCo ^((~BCu)& BCa );
|
||||||
|
Esu = BCu ^((~BCa)& BCe );
|
||||||
|
|
||||||
|
// prepareTheta
|
||||||
|
BCa = Eba^Ega^Eka^Ema^Esa;
|
||||||
|
BCe = Ebe^Ege^Eke^Eme^Ese;
|
||||||
|
BCi = Ebi^Egi^Eki^Emi^Esi;
|
||||||
|
BCo = Ebo^Ego^Eko^Emo^Eso;
|
||||||
|
BCu = Ebu^Egu^Eku^Emu^Esu;
|
||||||
|
|
||||||
|
//thetaRhoPiChiIotaPrepareTheta(round+1, E, A)
|
||||||
|
Da = BCu^ROL(BCe, 1);
|
||||||
|
De = BCa^ROL(BCi, 1);
|
||||||
|
Di = BCe^ROL(BCo, 1);
|
||||||
|
Do = BCi^ROL(BCu, 1);
|
||||||
|
Du = BCo^ROL(BCa, 1);
|
||||||
|
|
||||||
|
Eba ^= Da;
|
||||||
|
BCa = Eba;
|
||||||
|
Ege ^= De;
|
||||||
|
BCe = ROL(Ege, 44);
|
||||||
|
Eki ^= Di;
|
||||||
|
BCi = ROL(Eki, 43);
|
||||||
|
Emo ^= Do;
|
||||||
|
BCo = ROL(Emo, 21);
|
||||||
|
Esu ^= Du;
|
||||||
|
BCu = ROL(Esu, 14);
|
||||||
|
Aba = BCa ^((~BCe)& BCi );
|
||||||
|
Aba ^= (uint64_t)KeccakF_RoundConstants[round+1];
|
||||||
|
Abe = BCe ^((~BCi)& BCo );
|
||||||
|
Abi = BCi ^((~BCo)& BCu );
|
||||||
|
Abo = BCo ^((~BCu)& BCa );
|
||||||
|
Abu = BCu ^((~BCa)& BCe );
|
||||||
|
|
||||||
|
Ebo ^= Do;
|
||||||
|
BCa = ROL(Ebo, 28);
|
||||||
|
Egu ^= Du;
|
||||||
|
BCe = ROL(Egu, 20);
|
||||||
|
Eka ^= Da;
|
||||||
|
BCi = ROL(Eka, 3);
|
||||||
|
Eme ^= De;
|
||||||
|
BCo = ROL(Eme, 45);
|
||||||
|
Esi ^= Di;
|
||||||
|
BCu = ROL(Esi, 61);
|
||||||
|
Aga = BCa ^((~BCe)& BCi );
|
||||||
|
Age = BCe ^((~BCi)& BCo );
|
||||||
|
Agi = BCi ^((~BCo)& BCu );
|
||||||
|
Ago = BCo ^((~BCu)& BCa );
|
||||||
|
Agu = BCu ^((~BCa)& BCe );
|
||||||
|
|
||||||
|
Ebe ^= De;
|
||||||
|
BCa = ROL(Ebe, 1);
|
||||||
|
Egi ^= Di;
|
||||||
|
BCe = ROL(Egi, 6);
|
||||||
|
Eko ^= Do;
|
||||||
|
BCi = ROL(Eko, 25);
|
||||||
|
Emu ^= Du;
|
||||||
|
BCo = ROL(Emu, 8);
|
||||||
|
Esa ^= Da;
|
||||||
|
BCu = ROL(Esa, 18);
|
||||||
|
Aka = BCa ^((~BCe)& BCi );
|
||||||
|
Ake = BCe ^((~BCi)& BCo );
|
||||||
|
Aki = BCi ^((~BCo)& BCu );
|
||||||
|
Ako = BCo ^((~BCu)& BCa );
|
||||||
|
Aku = BCu ^((~BCa)& BCe );
|
||||||
|
|
||||||
|
Ebu ^= Du;
|
||||||
|
BCa = ROL(Ebu, 27);
|
||||||
|
Ega ^= Da;
|
||||||
|
BCe = ROL(Ega, 36);
|
||||||
|
Eke ^= De;
|
||||||
|
BCi = ROL(Eke, 10);
|
||||||
|
Emi ^= Di;
|
||||||
|
BCo = ROL(Emi, 15);
|
||||||
|
Eso ^= Do;
|
||||||
|
BCu = ROL(Eso, 56);
|
||||||
|
Ama = BCa ^((~BCe)& BCi );
|
||||||
|
Ame = BCe ^((~BCi)& BCo );
|
||||||
|
Ami = BCi ^((~BCo)& BCu );
|
||||||
|
Amo = BCo ^((~BCu)& BCa );
|
||||||
|
Amu = BCu ^((~BCa)& BCe );
|
||||||
|
|
||||||
|
Ebi ^= Di;
|
||||||
|
BCa = ROL(Ebi, 62);
|
||||||
|
Ego ^= Do;
|
||||||
|
BCe = ROL(Ego, 55);
|
||||||
|
Eku ^= Du;
|
||||||
|
BCi = ROL(Eku, 39);
|
||||||
|
Ema ^= Da;
|
||||||
|
BCo = ROL(Ema, 41);
|
||||||
|
Ese ^= De;
|
||||||
|
BCu = ROL(Ese, 2);
|
||||||
|
Asa = BCa ^((~BCe)& BCi );
|
||||||
|
Ase = BCe ^((~BCi)& BCo );
|
||||||
|
Asi = BCi ^((~BCo)& BCu );
|
||||||
|
Aso = BCo ^((~BCu)& BCa );
|
||||||
|
Asu = BCu ^((~BCa)& BCe );
|
||||||
|
}
|
||||||
|
|
||||||
|
//copyToState(state, A)
|
||||||
|
state[ 0] = Aba;
|
||||||
|
state[ 1] = Abe;
|
||||||
|
state[ 2] = Abi;
|
||||||
|
state[ 3] = Abo;
|
||||||
|
state[ 4] = Abu;
|
||||||
|
state[ 5] = Aga;
|
||||||
|
state[ 6] = Age;
|
||||||
|
state[ 7] = Agi;
|
||||||
|
state[ 8] = Ago;
|
||||||
|
state[ 9] = Agu;
|
||||||
|
state[10] = Aka;
|
||||||
|
state[11] = Ake;
|
||||||
|
state[12] = Aki;
|
||||||
|
state[13] = Ako;
|
||||||
|
state[14] = Aku;
|
||||||
|
state[15] = Ama;
|
||||||
|
state[16] = Ame;
|
||||||
|
state[17] = Ami;
|
||||||
|
state[18] = Amo;
|
||||||
|
state[19] = Amu;
|
||||||
|
state[20] = Asa;
|
||||||
|
state[21] = Ase;
|
||||||
|
state[22] = Asi;
|
||||||
|
state[23] = Aso;
|
||||||
|
state[24] = Asu;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: keccak_init
|
||||||
|
*
|
||||||
|
* Description: Initializes the Keccak state.
|
||||||
|
*
|
||||||
|
* Arguments: - uint64_t *s: pointer to Keccak state
|
||||||
|
**************************************************/
|
||||||
|
static void keccak_init(uint64_t s[25])
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
for(i=0;i<25;i++)
|
||||||
|
s[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: keccak_absorb
|
||||||
|
*
|
||||||
|
* Description: Absorb step of Keccak; incremental.
|
||||||
|
*
|
||||||
|
* Arguments: - uint64_t *s: pointer to Keccak state
|
||||||
|
* - unsigned int pos: position in current block to be absorbed
|
||||||
|
* - unsigned int r: rate in bytes (e.g., 168 for SHAKE128)
|
||||||
|
* - const uint8_t *in: pointer to input to be absorbed into s
|
||||||
|
* - size_t inlen: length of input in bytes
|
||||||
|
*
|
||||||
|
* Returns new position pos in current block
|
||||||
|
**************************************************/
|
||||||
|
static unsigned int keccak_absorb(uint64_t s[25],
|
||||||
|
unsigned int pos,
|
||||||
|
unsigned int r,
|
||||||
|
const uint8_t *in,
|
||||||
|
size_t inlen)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
while(pos+inlen >= r) {
|
||||||
|
for(i=pos;i<r;i++)
|
||||||
|
s[i/8] ^= (uint64_t)*in++ << 8*(i%8);
|
||||||
|
inlen -= r-pos;
|
||||||
|
KeccakF1600_StatePermute(s);
|
||||||
|
pos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i=pos;i<pos+inlen;i++)
|
||||||
|
s[i/8] ^= (uint64_t)*in++ << 8*(i%8);
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: keccak_finalize
|
||||||
|
*
|
||||||
|
* Description: Finalize absorb step.
|
||||||
|
*
|
||||||
|
* Arguments: - uint64_t *s: pointer to Keccak state
|
||||||
|
* - unsigned int pos: position in current block to be absorbed
|
||||||
|
* - unsigned int r: rate in bytes (e.g., 168 for SHAKE128)
|
||||||
|
* - uint8_t p: domain separation byte
|
||||||
|
**************************************************/
|
||||||
|
static void keccak_finalize(uint64_t s[25], unsigned int pos, unsigned int r, uint8_t p)
|
||||||
|
{
|
||||||
|
s[pos/8] ^= (uint64_t)p << 8*(pos%8);
|
||||||
|
s[r/8-1] ^= 1ULL << 63;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: keccak_squeeze
|
||||||
|
*
|
||||||
|
* Description: Squeeze step of Keccak. Squeezes arbitratrily many bytes.
|
||||||
|
* Modifies the state. Can be called multiple times to keep
|
||||||
|
* squeezing, i.e., is incremental.
|
||||||
|
*
|
||||||
|
* Arguments: - uint8_t *out: pointer to output
|
||||||
|
* - size_t outlen: number of bytes to be squeezed (written to out)
|
||||||
|
* - uint64_t *s: pointer to input/output Keccak state
|
||||||
|
* - unsigned int pos: number of bytes in current block already squeezed
|
||||||
|
* - unsigned int r: rate in bytes (e.g., 168 for SHAKE128)
|
||||||
|
*
|
||||||
|
* Returns new position pos in current block
|
||||||
|
**************************************************/
|
||||||
|
static unsigned int keccak_squeeze(uint8_t *out,
|
||||||
|
size_t outlen,
|
||||||
|
uint64_t s[25],
|
||||||
|
unsigned int pos,
|
||||||
|
unsigned int r)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
while(outlen) {
|
||||||
|
if(pos == r) {
|
||||||
|
KeccakF1600_StatePermute(s);
|
||||||
|
pos = 0;
|
||||||
|
}
|
||||||
|
for(i=pos;i < r && i < pos+outlen; i++)
|
||||||
|
*out++ = s[i/8] >> 8*(i%8);
|
||||||
|
outlen -= i-pos;
|
||||||
|
pos = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: keccak_absorb_once
|
||||||
|
*
|
||||||
|
* Description: Absorb step of Keccak;
|
||||||
|
* non-incremental, starts by zeroeing the state.
|
||||||
|
*
|
||||||
|
* Arguments: - uint64_t *s: pointer to (uninitialized) output Keccak state
|
||||||
|
* - unsigned int r: rate in bytes (e.g., 168 for SHAKE128)
|
||||||
|
* - const uint8_t *in: pointer to input to be absorbed into s
|
||||||
|
* - size_t inlen: length of input in bytes
|
||||||
|
* - uint8_t p: domain-separation byte for different Keccak-derived functions
|
||||||
|
**************************************************/
|
||||||
|
static void keccak_absorb_once(uint64_t s[25],
|
||||||
|
unsigned int r,
|
||||||
|
const uint8_t *in,
|
||||||
|
size_t inlen,
|
||||||
|
uint8_t p)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for(i=0;i<25;i++)
|
||||||
|
s[i] = 0;
|
||||||
|
|
||||||
|
while(inlen >= r) {
|
||||||
|
for(i=0;i<r/8;i++)
|
||||||
|
s[i] ^= load64(in+8*i);
|
||||||
|
in += r;
|
||||||
|
inlen -= r;
|
||||||
|
KeccakF1600_StatePermute(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i=0;i<inlen;i++)
|
||||||
|
s[i/8] ^= (uint64_t)in[i] << 8*(i%8);
|
||||||
|
|
||||||
|
s[i/8] ^= (uint64_t)p << 8*(i%8);
|
||||||
|
s[(r-1)/8] ^= 1ULL << 63;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: keccak_squeezeblocks
|
||||||
|
*
|
||||||
|
* Description: Squeeze step of Keccak. Squeezes full blocks of r bytes each.
|
||||||
|
* Modifies the state. Can be called multiple times to keep
|
||||||
|
* squeezing, i.e., is incremental. Assumes zero bytes of current
|
||||||
|
* block have already been squeezed.
|
||||||
|
*
|
||||||
|
* Arguments: - uint8_t *out: pointer to output blocks
|
||||||
|
* - size_t nblocks: number of blocks to be squeezed (written to out)
|
||||||
|
* - uint64_t *s: pointer to input/output Keccak state
|
||||||
|
* - unsigned int r: rate in bytes (e.g., 168 for SHAKE128)
|
||||||
|
**************************************************/
|
||||||
|
static void keccak_squeezeblocks(uint8_t *out,
|
||||||
|
size_t nblocks,
|
||||||
|
uint64_t s[25],
|
||||||
|
unsigned int r)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
while(nblocks) {
|
||||||
|
KeccakF1600_StatePermute(s);
|
||||||
|
for(i=0;i<r/8;i++)
|
||||||
|
store64(out+8*i, s[i]);
|
||||||
|
out += r;
|
||||||
|
nblocks -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: shake128_init
|
||||||
|
*
|
||||||
|
* Description: Initilizes Keccak state for use as SHAKE128 XOF
|
||||||
|
*
|
||||||
|
* Arguments: - keccak_state *state: pointer to (uninitialized) Keccak state
|
||||||
|
**************************************************/
|
||||||
|
void shake128_init(keccak_state *state)
|
||||||
|
{
|
||||||
|
keccak_init(state->s);
|
||||||
|
state->pos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: shake128_absorb
|
||||||
|
*
|
||||||
|
* Description: Absorb step of the SHAKE128 XOF; incremental.
|
||||||
|
*
|
||||||
|
* Arguments: - keccak_state *state: pointer to (initialized) output Keccak state
|
||||||
|
* - const uint8_t *in: pointer to input to be absorbed into s
|
||||||
|
* - size_t inlen: length of input in bytes
|
||||||
|
**************************************************/
|
||||||
|
void shake128_absorb(keccak_state *state, const uint8_t *in, size_t inlen)
|
||||||
|
{
|
||||||
|
state->pos = keccak_absorb(state->s, state->pos, SHAKE128_RATE, in, inlen);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: shake128_finalize
|
||||||
|
*
|
||||||
|
* Description: Finalize absorb step of the SHAKE128 XOF.
|
||||||
|
*
|
||||||
|
* Arguments: - keccak_state *state: pointer to Keccak state
|
||||||
|
**************************************************/
|
||||||
|
void shake128_finalize(keccak_state *state)
|
||||||
|
{
|
||||||
|
keccak_finalize(state->s, state->pos, SHAKE128_RATE, 0x1F);
|
||||||
|
state->pos = SHAKE128_RATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: shake128_squeeze
|
||||||
|
*
|
||||||
|
* Description: Squeeze step of SHAKE128 XOF. Squeezes arbitraily many
|
||||||
|
* bytes. Can be called multiple times to keep squeezing.
|
||||||
|
*
|
||||||
|
* Arguments: - uint8_t *out: pointer to output blocks
|
||||||
|
* - size_t outlen : number of bytes to be squeezed (written to output)
|
||||||
|
* - keccak_state *s: pointer to input/output Keccak state
|
||||||
|
**************************************************/
|
||||||
|
void shake128_squeeze(uint8_t *out, size_t outlen, keccak_state *state)
|
||||||
|
{
|
||||||
|
state->pos = keccak_squeeze(out, outlen, state->s, state->pos, SHAKE128_RATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: shake128_absorb_once
|
||||||
|
*
|
||||||
|
* Description: Initialize, absorb into and finalize SHAKE128 XOF; non-incremental.
|
||||||
|
*
|
||||||
|
* Arguments: - keccak_state *state: pointer to (uninitialized) output Keccak state
|
||||||
|
* - const uint8_t *in: pointer to input to be absorbed into s
|
||||||
|
* - size_t inlen: length of input in bytes
|
||||||
|
**************************************************/
|
||||||
|
void shake128_absorb_once(keccak_state *state, const uint8_t *in, size_t inlen)
|
||||||
|
{
|
||||||
|
keccak_absorb_once(state->s, SHAKE128_RATE, in, inlen, 0x1F);
|
||||||
|
state->pos = SHAKE128_RATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: shake128_squeezeblocks
|
||||||
|
*
|
||||||
|
* Description: Squeeze step of SHAKE128 XOF. Squeezes full blocks of
|
||||||
|
* SHAKE128_RATE bytes each. Can be called multiple times
|
||||||
|
* to keep squeezing. Assumes new block has not yet been
|
||||||
|
* started (state->pos = SHAKE128_RATE).
|
||||||
|
*
|
||||||
|
* Arguments: - uint8_t *out: pointer to output blocks
|
||||||
|
* - size_t nblocks: number of blocks to be squeezed (written to output)
|
||||||
|
* - keccak_state *s: pointer to input/output Keccak state
|
||||||
|
**************************************************/
|
||||||
|
void shake128_squeezeblocks(uint8_t *out, size_t nblocks, keccak_state *state)
|
||||||
|
{
|
||||||
|
keccak_squeezeblocks(out, nblocks, state->s, SHAKE128_RATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: shake256_init
|
||||||
|
*
|
||||||
|
* Description: Initilizes Keccak state for use as SHAKE256 XOF
|
||||||
|
*
|
||||||
|
* Arguments: - keccak_state *state: pointer to (uninitialized) Keccak state
|
||||||
|
**************************************************/
|
||||||
|
void shake256_init(keccak_state *state)
|
||||||
|
{
|
||||||
|
keccak_init(state->s);
|
||||||
|
state->pos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: shake256_absorb
|
||||||
|
*
|
||||||
|
* Description: Absorb step of the SHAKE256 XOF; incremental.
|
||||||
|
*
|
||||||
|
* Arguments: - keccak_state *state: pointer to (initialized) output Keccak state
|
||||||
|
* - const uint8_t *in: pointer to input to be absorbed into s
|
||||||
|
* - size_t inlen: length of input in bytes
|
||||||
|
**************************************************/
|
||||||
|
void shake256_absorb(keccak_state *state, const uint8_t *in, size_t inlen)
|
||||||
|
{
|
||||||
|
state->pos = keccak_absorb(state->s, state->pos, SHAKE256_RATE, in, inlen);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: shake256_finalize
|
||||||
|
*
|
||||||
|
* Description: Finalize absorb step of the SHAKE256 XOF.
|
||||||
|
*
|
||||||
|
* Arguments: - keccak_state *state: pointer to Keccak state
|
||||||
|
**************************************************/
|
||||||
|
void shake256_finalize(keccak_state *state)
|
||||||
|
{
|
||||||
|
keccak_finalize(state->s, state->pos, SHAKE256_RATE, 0x1F);
|
||||||
|
state->pos = SHAKE256_RATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: shake256_squeeze
|
||||||
|
*
|
||||||
|
* Description: Squeeze step of SHAKE256 XOF. Squeezes arbitraily many
|
||||||
|
* bytes. Can be called multiple times to keep squeezing.
|
||||||
|
*
|
||||||
|
* Arguments: - uint8_t *out: pointer to output blocks
|
||||||
|
* - size_t outlen : number of bytes to be squeezed (written to output)
|
||||||
|
* - keccak_state *s: pointer to input/output Keccak state
|
||||||
|
**************************************************/
|
||||||
|
void shake256_squeeze(uint8_t *out, size_t outlen, keccak_state *state)
|
||||||
|
{
|
||||||
|
state->pos = keccak_squeeze(out, outlen, state->s, state->pos, SHAKE256_RATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: shake256_absorb_once
|
||||||
|
*
|
||||||
|
* Description: Initialize, absorb into and finalize SHAKE256 XOF; non-incremental.
|
||||||
|
*
|
||||||
|
* Arguments: - keccak_state *state: pointer to (uninitialized) output Keccak state
|
||||||
|
* - const uint8_t *in: pointer to input to be absorbed into s
|
||||||
|
* - size_t inlen: length of input in bytes
|
||||||
|
**************************************************/
|
||||||
|
void shake256_absorb_once(keccak_state *state, const uint8_t *in, size_t inlen)
|
||||||
|
{
|
||||||
|
keccak_absorb_once(state->s, SHAKE256_RATE, in, inlen, 0x1F);
|
||||||
|
state->pos = SHAKE256_RATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: shake256_squeezeblocks
|
||||||
|
*
|
||||||
|
* Description: Squeeze step of SHAKE256 XOF. Squeezes full blocks of
|
||||||
|
* SHAKE256_RATE bytes each. Can be called multiple times
|
||||||
|
* to keep squeezing. Assumes next block has not yet been
|
||||||
|
* started (state->pos = SHAKE256_RATE).
|
||||||
|
*
|
||||||
|
* Arguments: - uint8_t *out: pointer to output blocks
|
||||||
|
* - size_t nblocks: number of blocks to be squeezed (written to output)
|
||||||
|
* - keccak_state *s: pointer to input/output Keccak state
|
||||||
|
**************************************************/
|
||||||
|
void shake256_squeezeblocks(uint8_t *out, size_t nblocks, keccak_state *state)
|
||||||
|
{
|
||||||
|
keccak_squeezeblocks(out, nblocks, state->s, SHAKE256_RATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: shake128
|
||||||
|
*
|
||||||
|
* Description: SHAKE128 XOF with non-incremental API
|
||||||
|
*
|
||||||
|
* Arguments: - uint8_t *out: pointer to output
|
||||||
|
* - size_t outlen: requested output length in bytes
|
||||||
|
* - const uint8_t *in: pointer to input
|
||||||
|
* - size_t inlen: length of input in bytes
|
||||||
|
**************************************************/
|
||||||
|
void shake128(uint8_t *out, size_t outlen, const uint8_t *in, size_t inlen)
|
||||||
|
{
|
||||||
|
size_t nblocks;
|
||||||
|
keccak_state state;
|
||||||
|
|
||||||
|
shake128_absorb_once(&state, in, inlen);
|
||||||
|
nblocks = outlen/SHAKE128_RATE;
|
||||||
|
shake128_squeezeblocks(out, nblocks, &state);
|
||||||
|
outlen -= nblocks*SHAKE128_RATE;
|
||||||
|
out += nblocks*SHAKE128_RATE;
|
||||||
|
shake128_squeeze(out, outlen, &state);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: shake256
|
||||||
|
*
|
||||||
|
* Description: SHAKE256 XOF with non-incremental API
|
||||||
|
*
|
||||||
|
* Arguments: - uint8_t *out: pointer to output
|
||||||
|
* - size_t outlen: requested output length in bytes
|
||||||
|
* - const uint8_t *in: pointer to input
|
||||||
|
* - size_t inlen: length of input in bytes
|
||||||
|
**************************************************/
|
||||||
|
void shake256(uint8_t *out, size_t outlen, const uint8_t *in, size_t inlen)
|
||||||
|
{
|
||||||
|
size_t nblocks;
|
||||||
|
keccak_state state;
|
||||||
|
|
||||||
|
shake256_absorb_once(&state, in, inlen);
|
||||||
|
nblocks = outlen/SHAKE256_RATE;
|
||||||
|
shake256_squeezeblocks(out, nblocks, &state);
|
||||||
|
outlen -= nblocks*SHAKE256_RATE;
|
||||||
|
out += nblocks*SHAKE256_RATE;
|
||||||
|
shake256_squeeze(out, outlen, &state);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: sha3_256
|
||||||
|
*
|
||||||
|
* Description: SHA3-256 with non-incremental API
|
||||||
|
*
|
||||||
|
* Arguments: - uint8_t *h: pointer to output (32 bytes)
|
||||||
|
* - const uint8_t *in: pointer to input
|
||||||
|
* - size_t inlen: length of input in bytes
|
||||||
|
**************************************************/
|
||||||
|
void sha3_256(uint8_t h[32], const uint8_t *in, size_t inlen)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
uint64_t s[25];
|
||||||
|
|
||||||
|
keccak_absorb_once(s, SHA3_256_RATE, in, inlen, 0x06);
|
||||||
|
KeccakF1600_StatePermute(s);
|
||||||
|
for(i=0;i<4;i++)
|
||||||
|
store64(h+8*i,s[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: sha3_512
|
||||||
|
*
|
||||||
|
* Description: SHA3-512 with non-incremental API
|
||||||
|
*
|
||||||
|
* Arguments: - uint8_t *h: pointer to output (64 bytes)
|
||||||
|
* - const uint8_t *in: pointer to input
|
||||||
|
* - size_t inlen: length of input in bytes
|
||||||
|
**************************************************/
|
||||||
|
void sha3_512(uint8_t h[64], const uint8_t *in, size_t inlen)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
uint64_t s[25];
|
||||||
|
|
||||||
|
keccak_absorb_once(s, SHA3_512_RATE, in, inlen, 0x06);
|
||||||
|
KeccakF1600_StatePermute(s);
|
||||||
|
for(i=0;i<8;i++)
|
||||||
|
store64(h+8*i,s[i]);
|
||||||
|
}
|
||||||
57
src/crypto/pq/_d/ref/fips202.h
Normal file
57
src/crypto/pq/_d/ref/fips202.h
Normal file
|
|
@ -0,0 +1,57 @@
|
||||||
|
#ifndef FIPS202_H
|
||||||
|
#define FIPS202_H
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define SHAKE128_RATE 168
|
||||||
|
#define SHAKE256_RATE 136
|
||||||
|
#define SHA3_256_RATE 136
|
||||||
|
#define SHA3_512_RATE 72
|
||||||
|
|
||||||
|
#define FIPS202_NAMESPACE(s) pqcrystals_dilithium_fips202_ref_##s
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint64_t s[25];
|
||||||
|
unsigned int pos;
|
||||||
|
} keccak_state;
|
||||||
|
|
||||||
|
#define KeccakF_RoundConstants FIPS202_NAMESPACE(KeccakF_RoundConstants)
|
||||||
|
extern const uint64_t KeccakF_RoundConstants[];
|
||||||
|
|
||||||
|
#define shake128_init FIPS202_NAMESPACE(shake128_init)
|
||||||
|
void shake128_init(keccak_state *state);
|
||||||
|
#define shake128_absorb FIPS202_NAMESPACE(shake128_absorb)
|
||||||
|
void shake128_absorb(keccak_state *state, const uint8_t *in, size_t inlen);
|
||||||
|
#define shake128_finalize FIPS202_NAMESPACE(shake128_finalize)
|
||||||
|
void shake128_finalize(keccak_state *state);
|
||||||
|
#define shake128_squeeze FIPS202_NAMESPACE(shake128_squeeze)
|
||||||
|
void shake128_squeeze(uint8_t *out, size_t outlen, keccak_state *state);
|
||||||
|
#define shake128_absorb_once FIPS202_NAMESPACE(shake128_absorb_once)
|
||||||
|
void shake128_absorb_once(keccak_state *state, const uint8_t *in, size_t inlen);
|
||||||
|
#define shake128_squeezeblocks FIPS202_NAMESPACE(shake128_squeezeblocks)
|
||||||
|
void shake128_squeezeblocks(uint8_t *out, size_t nblocks, keccak_state *state);
|
||||||
|
|
||||||
|
#define shake256_init FIPS202_NAMESPACE(shake256_init)
|
||||||
|
void shake256_init(keccak_state *state);
|
||||||
|
#define shake256_absorb FIPS202_NAMESPACE(shake256_absorb)
|
||||||
|
void shake256_absorb(keccak_state *state, const uint8_t *in, size_t inlen);
|
||||||
|
#define shake256_finalize FIPS202_NAMESPACE(shake256_finalize)
|
||||||
|
void shake256_finalize(keccak_state *state);
|
||||||
|
#define shake256_squeeze FIPS202_NAMESPACE(shake256_squeeze)
|
||||||
|
void shake256_squeeze(uint8_t *out, size_t outlen, keccak_state *state);
|
||||||
|
#define shake256_absorb_once FIPS202_NAMESPACE(shake256_absorb_once)
|
||||||
|
void shake256_absorb_once(keccak_state *state, const uint8_t *in, size_t inlen);
|
||||||
|
#define shake256_squeezeblocks FIPS202_NAMESPACE(shake256_squeezeblocks)
|
||||||
|
void shake256_squeezeblocks(uint8_t *out, size_t nblocks, keccak_state *state);
|
||||||
|
|
||||||
|
#define shake128 FIPS202_NAMESPACE(shake128)
|
||||||
|
void shake128(uint8_t *out, size_t outlen, const uint8_t *in, size_t inlen);
|
||||||
|
#define shake256 FIPS202_NAMESPACE(shake256)
|
||||||
|
void shake256(uint8_t *out, size_t outlen, const uint8_t *in, size_t inlen);
|
||||||
|
#define sha3_256 FIPS202_NAMESPACE(sha3_256)
|
||||||
|
void sha3_256(uint8_t h[32], const uint8_t *in, size_t inlen);
|
||||||
|
#define sha3_512 FIPS202_NAMESPACE(sha3_512)
|
||||||
|
void sha3_512(uint8_t h[64], const uint8_t *in, size_t inlen);
|
||||||
|
|
||||||
|
#endif
|
||||||
3
src/crypto/pq/_d/ref/nistkat/.gitignore
vendored
Normal file
3
src/crypto/pq/_d/ref/nistkat/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
PQCgenKAT_sign2
|
||||||
|
PQCgenKAT_sign3
|
||||||
|
PQCgenKAT_sign5
|
||||||
261
src/crypto/pq/_d/ref/nistkat/PQCgenKAT_sign.c
Normal file
261
src/crypto/pq/_d/ref/nistkat/PQCgenKAT_sign.c
Normal file
|
|
@ -0,0 +1,261 @@
|
||||||
|
//
|
||||||
|
// PQCgenKAT_sign.c
|
||||||
|
//
|
||||||
|
// Created by Bassham, Lawrence E (Fed) on 8/29/17.
|
||||||
|
// Copyright © 2017 Bassham, Lawrence E (Fed). All rights reserved.
|
||||||
|
//
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include "rng.h"
|
||||||
|
#include "../sign.h"
|
||||||
|
|
||||||
|
#define MAX_MARKER_LEN 50
|
||||||
|
|
||||||
|
#define KAT_SUCCESS 0
|
||||||
|
#define KAT_FILE_OPEN_ERROR -1
|
||||||
|
#define KAT_DATA_ERROR -3
|
||||||
|
#define KAT_CRYPTO_FAILURE -4
|
||||||
|
|
||||||
|
int FindMarker(FILE *infile, const char *marker);
|
||||||
|
int ReadHex(FILE *infile, unsigned char *a, int Length, char *str);
|
||||||
|
void fprintBstr(FILE *fp, char *s, unsigned char *a, unsigned long long l);
|
||||||
|
|
||||||
|
int
|
||||||
|
main()
|
||||||
|
{
|
||||||
|
char fn_req[32], fn_rsp[32];
|
||||||
|
FILE *fp_req, *fp_rsp;
|
||||||
|
uint8_t seed[48];
|
||||||
|
uint8_t msg[3300];
|
||||||
|
uint8_t entropy_input[48];
|
||||||
|
uint8_t *m, *sm, *m1;
|
||||||
|
size_t mlen, smlen, mlen1;
|
||||||
|
int count;
|
||||||
|
int done;
|
||||||
|
uint8_t pk[CRYPTO_PUBLICKEYBYTES], sk[CRYPTO_SECRETKEYBYTES];
|
||||||
|
int ret_val;
|
||||||
|
|
||||||
|
// Create the REQUEST file
|
||||||
|
sprintf(fn_req, "PQCsignKAT_%.16s.req", CRYPTO_ALGNAME);
|
||||||
|
if ( (fp_req = fopen(fn_req, "w")) == NULL ) {
|
||||||
|
printf("Couldn't open <%s> for write\n", fn_req);
|
||||||
|
return KAT_FILE_OPEN_ERROR;
|
||||||
|
}
|
||||||
|
sprintf(fn_rsp, "PQCsignKAT_%.16s.rsp", CRYPTO_ALGNAME);
|
||||||
|
if ( (fp_rsp = fopen(fn_rsp, "w")) == NULL ) {
|
||||||
|
printf("Couldn't open <%s> for write\n", fn_rsp);
|
||||||
|
return KAT_FILE_OPEN_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i=0; i<48; i++)
|
||||||
|
entropy_input[i] = i;
|
||||||
|
|
||||||
|
randombytes_init(entropy_input, NULL, 256);
|
||||||
|
for (int i=0; i<100; i++) {
|
||||||
|
fprintf(fp_req, "count = %d\n", i);
|
||||||
|
randombytes(seed, 48);
|
||||||
|
fprintBstr(fp_req, "seed = ", seed, 48);
|
||||||
|
mlen = 33*(i+1);
|
||||||
|
fprintf(fp_req, "mlen = %lu\n", mlen);
|
||||||
|
randombytes(msg, mlen);
|
||||||
|
fprintBstr(fp_req, "msg = ", msg, mlen);
|
||||||
|
fprintf(fp_req, "pk =\n");
|
||||||
|
fprintf(fp_req, "sk =\n");
|
||||||
|
fprintf(fp_req, "smlen =\n");
|
||||||
|
fprintf(fp_req, "sm =\n\n");
|
||||||
|
}
|
||||||
|
fclose(fp_req);
|
||||||
|
|
||||||
|
//Create the RESPONSE file based on what's in the REQUEST file
|
||||||
|
if ( (fp_req = fopen(fn_req, "r")) == NULL ) {
|
||||||
|
printf("Couldn't open <%s> for read\n", fn_req);
|
||||||
|
return KAT_FILE_OPEN_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(fp_rsp, "# %s\n\n", CRYPTO_ALGNAME);
|
||||||
|
done = 0;
|
||||||
|
do {
|
||||||
|
if ( FindMarker(fp_req, "count = ") )
|
||||||
|
fscanf(fp_req, "%d", &count);
|
||||||
|
else {
|
||||||
|
done = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
fprintf(fp_rsp, "count = %d\n", count);
|
||||||
|
|
||||||
|
if ( !ReadHex(fp_req, seed, 48, "seed = ") ) {
|
||||||
|
printf("ERROR: unable to read 'seed' from <%s>\n", fn_req);
|
||||||
|
return KAT_DATA_ERROR;
|
||||||
|
}
|
||||||
|
fprintBstr(fp_rsp, "seed = ", seed, 48);
|
||||||
|
|
||||||
|
randombytes_init(seed, NULL, 256);
|
||||||
|
|
||||||
|
if ( FindMarker(fp_req, "mlen = ") )
|
||||||
|
fscanf(fp_req, "%lu", &mlen);
|
||||||
|
else {
|
||||||
|
printf("ERROR: unable to read 'mlen' from <%s>\n", fn_req);
|
||||||
|
return KAT_DATA_ERROR;
|
||||||
|
}
|
||||||
|
fprintf(fp_rsp, "mlen = %lu\n", mlen);
|
||||||
|
|
||||||
|
m = (uint8_t *)calloc(mlen, sizeof(uint8_t));
|
||||||
|
m1 = (uint8_t *)calloc(mlen+CRYPTO_BYTES, sizeof(uint8_t));
|
||||||
|
sm = (uint8_t *)calloc(mlen+CRYPTO_BYTES, sizeof(uint8_t));
|
||||||
|
|
||||||
|
if ( !ReadHex(fp_req, m, (int)mlen, "msg = ") ) {
|
||||||
|
printf("ERROR: unable to read 'msg' from <%s>\n", fn_req);
|
||||||
|
return KAT_DATA_ERROR;
|
||||||
|
}
|
||||||
|
fprintBstr(fp_rsp, "msg = ", m, mlen);
|
||||||
|
|
||||||
|
// Generate the public/private keypair
|
||||||
|
if ( (ret_val = crypto_sign_keypair(pk, sk)) != 0) {
|
||||||
|
printf("crypto_sign_keypair returned <%d>\n", ret_val);
|
||||||
|
return KAT_CRYPTO_FAILURE;
|
||||||
|
}
|
||||||
|
fprintBstr(fp_rsp, "pk = ", pk, CRYPTO_PUBLICKEYBYTES);
|
||||||
|
fprintBstr(fp_rsp, "sk = ", sk, CRYPTO_SECRETKEYBYTES);
|
||||||
|
|
||||||
|
if ( (ret_val = crypto_sign(sm, &smlen, m, mlen, NULL, 0, sk)) != 0) {
|
||||||
|
printf("crypto_sign returned <%d>\n", ret_val);
|
||||||
|
return KAT_CRYPTO_FAILURE;
|
||||||
|
}
|
||||||
|
fprintf(fp_rsp, "smlen = %lu\n", smlen);
|
||||||
|
fprintBstr(fp_rsp, "sm = ", sm, smlen);
|
||||||
|
fprintf(fp_rsp, "\n");
|
||||||
|
|
||||||
|
if ( (ret_val = crypto_sign_open(m1, &mlen1, sm, smlen, NULL, 0, pk)) != 0) {
|
||||||
|
printf("crypto_sign_open returned <%d>\n", ret_val);
|
||||||
|
return KAT_CRYPTO_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( mlen != mlen1 ) {
|
||||||
|
printf("crypto_sign_open returned bad 'mlen': Got <%lu>, expected <%lu>\n", mlen1, mlen);
|
||||||
|
return KAT_CRYPTO_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( memcmp(m, m1, mlen) ) {
|
||||||
|
printf("crypto_sign_open returned bad 'm' value\n");
|
||||||
|
return KAT_CRYPTO_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(m);
|
||||||
|
free(m1);
|
||||||
|
free(sm);
|
||||||
|
|
||||||
|
} while ( !done );
|
||||||
|
|
||||||
|
fclose(fp_req);
|
||||||
|
fclose(fp_rsp);
|
||||||
|
|
||||||
|
return KAT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// ALLOW TO READ HEXADECIMAL ENTRY (KEYS, DATA, TEXT, etc.)
|
||||||
|
//
|
||||||
|
int
|
||||||
|
FindMarker(FILE *infile, const char *marker)
|
||||||
|
{
|
||||||
|
char line[MAX_MARKER_LEN];
|
||||||
|
int i, len;
|
||||||
|
int curr_line;
|
||||||
|
|
||||||
|
len = (int)strlen(marker);
|
||||||
|
if ( len > MAX_MARKER_LEN-1 )
|
||||||
|
len = MAX_MARKER_LEN-1;
|
||||||
|
|
||||||
|
for ( i=0; i<len; i++ )
|
||||||
|
{
|
||||||
|
curr_line = fgetc(infile);
|
||||||
|
line[i] = curr_line;
|
||||||
|
if (curr_line == EOF )
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
line[len] = '\0';
|
||||||
|
|
||||||
|
while ( 1 ) {
|
||||||
|
if ( !strncmp(line, marker, len) )
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
for ( i=0; i<len-1; i++ )
|
||||||
|
line[i] = line[i+1];
|
||||||
|
curr_line = fgetc(infile);
|
||||||
|
line[len-1] = curr_line;
|
||||||
|
if (curr_line == EOF )
|
||||||
|
return 0;
|
||||||
|
line[len] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
// shouldn't get here
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// ALLOW TO READ HEXADECIMAL ENTRY (KEYS, DATA, TEXT, etc.)
|
||||||
|
//
|
||||||
|
int
|
||||||
|
ReadHex(FILE *infile, unsigned char *a, int Length, char *str)
|
||||||
|
{
|
||||||
|
int i, ch, started;
|
||||||
|
unsigned char ich;
|
||||||
|
|
||||||
|
if ( Length == 0 ) {
|
||||||
|
a[0] = 0x00;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
memset(a, 0x00, Length);
|
||||||
|
started = 0;
|
||||||
|
if ( FindMarker(infile, str) )
|
||||||
|
while ( (ch = fgetc(infile)) != EOF ) {
|
||||||
|
if ( !isxdigit(ch) ) {
|
||||||
|
if ( !started ) {
|
||||||
|
if ( ch == '\n' )
|
||||||
|
break;
|
||||||
|
else
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
started = 1;
|
||||||
|
if ( (ch >= '0') && (ch <= '9') )
|
||||||
|
ich = ch - '0';
|
||||||
|
else if ( (ch >= 'A') && (ch <= 'F') )
|
||||||
|
ich = ch - 'A' + 10;
|
||||||
|
else if ( (ch >= 'a') && (ch <= 'f') )
|
||||||
|
ich = ch - 'a' + 10;
|
||||||
|
else // shouldn't ever get here
|
||||||
|
ich = 0;
|
||||||
|
|
||||||
|
for ( i=0; i<Length-1; i++ )
|
||||||
|
a[i] = (a[i] << 4) | (a[i+1] >> 4);
|
||||||
|
a[Length-1] = (a[Length-1] << 4) | ich;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
fprintBstr(FILE *fp, char *s, unsigned char *a, unsigned long long l)
|
||||||
|
{
|
||||||
|
unsigned long long i;
|
||||||
|
|
||||||
|
fprintf(fp, "%s", s);
|
||||||
|
|
||||||
|
for ( i=0; i<l; i++ )
|
||||||
|
fprintf(fp, "%02X", a[i]);
|
||||||
|
|
||||||
|
if ( l == 0 )
|
||||||
|
fprintf(fp, "00");
|
||||||
|
|
||||||
|
fprintf(fp, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
222
src/crypto/pq/_d/ref/nistkat/rng.c
Normal file
222
src/crypto/pq/_d/ref/nistkat/rng.c
Normal file
|
|
@ -0,0 +1,222 @@
|
||||||
|
//
|
||||||
|
// rng.c
|
||||||
|
//
|
||||||
|
// Created by Bassham, Lawrence E (Fed) on 8/29/17.
|
||||||
|
// Copyright © 2017 Bassham, Lawrence E (Fed). All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include "rng.h"
|
||||||
|
#include <openssl/conf.h>
|
||||||
|
#include <openssl/evp.h>
|
||||||
|
#include <openssl/err.h>
|
||||||
|
|
||||||
|
AES256_CTR_DRBG_struct DRBG_ctx;
|
||||||
|
|
||||||
|
void AES256_ECB(unsigned char *key, unsigned char *ctr, unsigned char *buffer);
|
||||||
|
|
||||||
|
/*
|
||||||
|
seedexpander_init()
|
||||||
|
ctx - stores the current state of an instance of the seed expander
|
||||||
|
seed - a 32 byte random value
|
||||||
|
diversifier - an 8 byte diversifier
|
||||||
|
maxlen - maximum number of bytes (less than 2**32) generated under this seed and diversifier
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
seedexpander_init(AES_XOF_struct *ctx,
|
||||||
|
unsigned char *seed,
|
||||||
|
unsigned char *diversifier,
|
||||||
|
unsigned long maxlen)
|
||||||
|
{
|
||||||
|
if ( maxlen >= 0x100000000 )
|
||||||
|
return RNG_BAD_MAXLEN;
|
||||||
|
|
||||||
|
ctx->length_remaining = maxlen;
|
||||||
|
|
||||||
|
memcpy(ctx->key, seed, 32);
|
||||||
|
|
||||||
|
memcpy(ctx->ctr, diversifier, 8);
|
||||||
|
ctx->ctr[11] = maxlen % 256;
|
||||||
|
maxlen >>= 8;
|
||||||
|
ctx->ctr[10] = maxlen % 256;
|
||||||
|
maxlen >>= 8;
|
||||||
|
ctx->ctr[9] = maxlen % 256;
|
||||||
|
maxlen >>= 8;
|
||||||
|
ctx->ctr[8] = maxlen % 256;
|
||||||
|
memset(ctx->ctr+12, 0x00, 4);
|
||||||
|
|
||||||
|
ctx->buffer_pos = 16;
|
||||||
|
memset(ctx->buffer, 0x00, 16);
|
||||||
|
|
||||||
|
return RNG_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
seedexpander()
|
||||||
|
ctx - stores the current state of an instance of the seed expander
|
||||||
|
x - returns the XOF data
|
||||||
|
xlen - number of bytes to return
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
seedexpander(AES_XOF_struct *ctx, unsigned char *x, unsigned long xlen)
|
||||||
|
{
|
||||||
|
unsigned long offset;
|
||||||
|
|
||||||
|
if ( x == NULL )
|
||||||
|
return RNG_BAD_OUTBUF;
|
||||||
|
if ( xlen >= ctx->length_remaining )
|
||||||
|
return RNG_BAD_REQ_LEN;
|
||||||
|
|
||||||
|
ctx->length_remaining -= xlen;
|
||||||
|
|
||||||
|
offset = 0;
|
||||||
|
while ( xlen > 0 ) {
|
||||||
|
if ( xlen <= (16-ctx->buffer_pos) ) { // buffer has what we need
|
||||||
|
memcpy(x+offset, ctx->buffer+ctx->buffer_pos, xlen);
|
||||||
|
ctx->buffer_pos += xlen;
|
||||||
|
|
||||||
|
return RNG_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
// take what's in the buffer
|
||||||
|
memcpy(x+offset, ctx->buffer+ctx->buffer_pos, 16-ctx->buffer_pos);
|
||||||
|
xlen -= 16-ctx->buffer_pos;
|
||||||
|
offset += 16-ctx->buffer_pos;
|
||||||
|
|
||||||
|
AES256_ECB(ctx->key, ctx->ctr, ctx->buffer);
|
||||||
|
ctx->buffer_pos = 0;
|
||||||
|
|
||||||
|
//increment the counter
|
||||||
|
for (int i=15; i>=12; i--) {
|
||||||
|
if ( ctx->ctr[i] == 0xff )
|
||||||
|
ctx->ctr[i] = 0x00;
|
||||||
|
else {
|
||||||
|
ctx->ctr[i]++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return RNG_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void handleErrors(void)
|
||||||
|
{
|
||||||
|
ERR_print_errors_fp(stderr);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use whatever AES implementation you have. This uses AES from openSSL library
|
||||||
|
// key - 256-bit AES key
|
||||||
|
// ctr - a 128-bit plaintext value
|
||||||
|
// buffer - a 128-bit ciphertext value
|
||||||
|
void
|
||||||
|
AES256_ECB(unsigned char *key, unsigned char *ctr, unsigned char *buffer)
|
||||||
|
{
|
||||||
|
EVP_CIPHER_CTX *ctx;
|
||||||
|
|
||||||
|
int len;
|
||||||
|
|
||||||
|
int ciphertext_len;
|
||||||
|
|
||||||
|
/* Create and initialise the context */
|
||||||
|
if(!(ctx = EVP_CIPHER_CTX_new())) handleErrors();
|
||||||
|
|
||||||
|
if(1 != EVP_EncryptInit_ex(ctx, EVP_aes_256_ecb(), NULL, key, NULL))
|
||||||
|
handleErrors();
|
||||||
|
|
||||||
|
if(1 != EVP_EncryptUpdate(ctx, buffer, &len, ctr, 16))
|
||||||
|
handleErrors();
|
||||||
|
ciphertext_len = len;
|
||||||
|
|
||||||
|
/* Clean up */
|
||||||
|
EVP_CIPHER_CTX_free(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
randombytes_init(unsigned char *entropy_input,
|
||||||
|
unsigned char *personalization_string,
|
||||||
|
int security_strength)
|
||||||
|
{
|
||||||
|
unsigned char seed_material[48];
|
||||||
|
|
||||||
|
memcpy(seed_material, entropy_input, 48);
|
||||||
|
if (personalization_string)
|
||||||
|
for (int i=0; i<48; i++)
|
||||||
|
seed_material[i] ^= personalization_string[i];
|
||||||
|
memset(DRBG_ctx.Key, 0x00, 32);
|
||||||
|
memset(DRBG_ctx.V, 0x00, 16);
|
||||||
|
AES256_CTR_DRBG_Update(seed_material, DRBG_ctx.Key, DRBG_ctx.V);
|
||||||
|
DRBG_ctx.reseed_counter = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
randombytes(unsigned char *x, unsigned long long xlen)
|
||||||
|
{
|
||||||
|
unsigned char block[16];
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
while ( xlen > 0 ) {
|
||||||
|
//increment V
|
||||||
|
for (int j=15; j>=0; j--) {
|
||||||
|
if ( DRBG_ctx.V[j] == 0xff )
|
||||||
|
DRBG_ctx.V[j] = 0x00;
|
||||||
|
else {
|
||||||
|
DRBG_ctx.V[j]++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AES256_ECB(DRBG_ctx.Key, DRBG_ctx.V, block);
|
||||||
|
if ( xlen > 15 ) {
|
||||||
|
memcpy(x+i, block, 16);
|
||||||
|
i += 16;
|
||||||
|
xlen -= 16;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
memcpy(x+i, block, xlen);
|
||||||
|
xlen = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AES256_CTR_DRBG_Update(NULL, DRBG_ctx.Key, DRBG_ctx.V);
|
||||||
|
DRBG_ctx.reseed_counter++;
|
||||||
|
|
||||||
|
return RNG_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
AES256_CTR_DRBG_Update(unsigned char *provided_data,
|
||||||
|
unsigned char *Key,
|
||||||
|
unsigned char *V)
|
||||||
|
{
|
||||||
|
unsigned char temp[48];
|
||||||
|
|
||||||
|
for (int i=0; i<3; i++) {
|
||||||
|
//increment V
|
||||||
|
for (int j=15; j>=0; j--) {
|
||||||
|
if ( V[j] == 0xff )
|
||||||
|
V[j] = 0x00;
|
||||||
|
else {
|
||||||
|
V[j]++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AES256_ECB(Key, V, temp+16*i);
|
||||||
|
}
|
||||||
|
if ( provided_data != NULL )
|
||||||
|
for (int i=0; i<48; i++)
|
||||||
|
temp[i] ^= provided_data[i];
|
||||||
|
memcpy(Key, temp, 32);
|
||||||
|
memcpy(V, temp+32, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
55
src/crypto/pq/_d/ref/nistkat/rng.h
Normal file
55
src/crypto/pq/_d/ref/nistkat/rng.h
Normal file
|
|
@ -0,0 +1,55 @@
|
||||||
|
//
|
||||||
|
// rng.h
|
||||||
|
//
|
||||||
|
// Created by Bassham, Lawrence E (Fed) on 8/29/17.
|
||||||
|
// Copyright © 2017 Bassham, Lawrence E (Fed). All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef rng_h
|
||||||
|
#define rng_h
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#define RNG_SUCCESS 0
|
||||||
|
#define RNG_BAD_MAXLEN -1
|
||||||
|
#define RNG_BAD_OUTBUF -2
|
||||||
|
#define RNG_BAD_REQ_LEN -3
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned char buffer[16];
|
||||||
|
int buffer_pos;
|
||||||
|
unsigned long length_remaining;
|
||||||
|
unsigned char key[32];
|
||||||
|
unsigned char ctr[16];
|
||||||
|
} AES_XOF_struct;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned char Key[32];
|
||||||
|
unsigned char V[16];
|
||||||
|
int reseed_counter;
|
||||||
|
} AES256_CTR_DRBG_struct;
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
AES256_CTR_DRBG_Update(unsigned char *provided_data,
|
||||||
|
unsigned char *Key,
|
||||||
|
unsigned char *V);
|
||||||
|
|
||||||
|
int
|
||||||
|
seedexpander_init(AES_XOF_struct *ctx,
|
||||||
|
unsigned char *seed,
|
||||||
|
unsigned char *diversifier,
|
||||||
|
unsigned long maxlen);
|
||||||
|
|
||||||
|
int
|
||||||
|
seedexpander(AES_XOF_struct *ctx, unsigned char *x, unsigned long xlen);
|
||||||
|
|
||||||
|
void
|
||||||
|
randombytes_init(unsigned char *entropy_input,
|
||||||
|
unsigned char *personalization_string,
|
||||||
|
int security_strength);
|
||||||
|
|
||||||
|
int
|
||||||
|
randombytes(unsigned char *x, unsigned long long xlen);
|
||||||
|
|
||||||
|
#endif /* rng_h */
|
||||||
98
src/crypto/pq/_d/ref/ntt.c
Normal file
98
src/crypto/pq/_d/ref/ntt.c
Normal file
|
|
@ -0,0 +1,98 @@
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "params.h"
|
||||||
|
#include "ntt.h"
|
||||||
|
#include "reduce.h"
|
||||||
|
|
||||||
|
static const int32_t zetas[N] = {
|
||||||
|
0, 25847, -2608894, -518909, 237124, -777960, -876248, 466468,
|
||||||
|
1826347, 2353451, -359251, -2091905, 3119733, -2884855, 3111497, 2680103,
|
||||||
|
2725464, 1024112, -1079900, 3585928, -549488, -1119584, 2619752, -2108549,
|
||||||
|
-2118186, -3859737, -1399561, -3277672, 1757237, -19422, 4010497, 280005,
|
||||||
|
2706023, 95776, 3077325, 3530437, -1661693, -3592148, -2537516, 3915439,
|
||||||
|
-3861115, -3043716, 3574422, -2867647, 3539968, -300467, 2348700, -539299,
|
||||||
|
-1699267, -1643818, 3505694, -3821735, 3507263, -2140649, -1600420, 3699596,
|
||||||
|
811944, 531354, 954230, 3881043, 3900724, -2556880, 2071892, -2797779,
|
||||||
|
-3930395, -1528703, -3677745, -3041255, -1452451, 3475950, 2176455, -1585221,
|
||||||
|
-1257611, 1939314, -4083598, -1000202, -3190144, -3157330, -3632928, 126922,
|
||||||
|
3412210, -983419, 2147896, 2715295, -2967645, -3693493, -411027, -2477047,
|
||||||
|
-671102, -1228525, -22981, -1308169, -381987, 1349076, 1852771, -1430430,
|
||||||
|
-3343383, 264944, 508951, 3097992, 44288, -1100098, 904516, 3958618,
|
||||||
|
-3724342, -8578, 1653064, -3249728, 2389356, -210977, 759969, -1316856,
|
||||||
|
189548, -3553272, 3159746, -1851402, -2409325, -177440, 1315589, 1341330,
|
||||||
|
1285669, -1584928, -812732, -1439742, -3019102, -3881060, -3628969, 3839961,
|
||||||
|
2091667, 3407706, 2316500, 3817976, -3342478, 2244091, -2446433, -3562462,
|
||||||
|
266997, 2434439, -1235728, 3513181, -3520352, -3759364, -1197226, -3193378,
|
||||||
|
900702, 1859098, 909542, 819034, 495491, -1613174, -43260, -522500,
|
||||||
|
-655327, -3122442, 2031748, 3207046, -3556995, -525098, -768622, -3595838,
|
||||||
|
342297, 286988, -2437823, 4108315, 3437287, -3342277, 1735879, 203044,
|
||||||
|
2842341, 2691481, -2590150, 1265009, 4055324, 1247620, 2486353, 1595974,
|
||||||
|
-3767016, 1250494, 2635921, -3548272, -2994039, 1869119, 1903435, -1050970,
|
||||||
|
-1333058, 1237275, -3318210, -1430225, -451100, 1312455, 3306115, -1962642,
|
||||||
|
-1279661, 1917081, -2546312, -1374803, 1500165, 777191, 2235880, 3406031,
|
||||||
|
-542412, -2831860, -1671176, -1846953, -2584293, -3724270, 594136, -3776993,
|
||||||
|
-2013608, 2432395, 2454455, -164721, 1957272, 3369112, 185531, -1207385,
|
||||||
|
-3183426, 162844, 1616392, 3014001, 810149, 1652634, -3694233, -1799107,
|
||||||
|
-3038916, 3523897, 3866901, 269760, 2213111, -975884, 1717735, 472078,
|
||||||
|
-426683, 1723600, -1803090, 1910376, -1667432, -1104333, -260646, -3833893,
|
||||||
|
-2939036, -2235985, -420899, -2286327, 183443, -976891, 1612842, -3545687,
|
||||||
|
-554416, 3919660, -48306, -1362209, 3937738, 1400424, -846154, 1976782
|
||||||
|
};
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: ntt
|
||||||
|
*
|
||||||
|
* Description: Forward NTT, in-place. No modular reduction is performed after
|
||||||
|
* additions or subtractions. Output vector is in bitreversed order.
|
||||||
|
*
|
||||||
|
* Arguments: - uint32_t p[N]: input/output coefficient array
|
||||||
|
**************************************************/
|
||||||
|
void ntt(int32_t a[N]) {
|
||||||
|
unsigned int len, start, j, k;
|
||||||
|
int32_t zeta, t;
|
||||||
|
|
||||||
|
k = 0;
|
||||||
|
for(len = 128; len > 0; len >>= 1) {
|
||||||
|
for(start = 0; start < N; start = j + len) {
|
||||||
|
zeta = zetas[++k];
|
||||||
|
for(j = start; j < start + len; ++j) {
|
||||||
|
t = montgomery_reduce((int64_t)zeta * a[j + len]);
|
||||||
|
a[j + len] = a[j] - t;
|
||||||
|
a[j] = a[j] + t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: invntt_tomont
|
||||||
|
*
|
||||||
|
* Description: Inverse NTT and multiplication by Montgomery factor 2^32.
|
||||||
|
* In-place. No modular reductions after additions or
|
||||||
|
* subtractions; input coefficients need to be smaller than
|
||||||
|
* Q in absolute value. Output coefficient are smaller than Q in
|
||||||
|
* absolute value.
|
||||||
|
*
|
||||||
|
* Arguments: - uint32_t p[N]: input/output coefficient array
|
||||||
|
**************************************************/
|
||||||
|
void invntt_tomont(int32_t a[N]) {
|
||||||
|
unsigned int start, len, j, k;
|
||||||
|
int32_t t, zeta;
|
||||||
|
const int32_t f = 41978; // mont^2/256
|
||||||
|
|
||||||
|
k = 256;
|
||||||
|
for(len = 1; len < N; len <<= 1) {
|
||||||
|
for(start = 0; start < N; start = j + len) {
|
||||||
|
zeta = -zetas[--k];
|
||||||
|
for(j = start; j < start + len; ++j) {
|
||||||
|
t = a[j];
|
||||||
|
a[j] = t + a[j + len];
|
||||||
|
a[j + len] = t - a[j + len];
|
||||||
|
a[j + len] = montgomery_reduce((int64_t)zeta * a[j + len]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(j = 0; j < N; ++j) {
|
||||||
|
a[j] = montgomery_reduce((int64_t)f * a[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
13
src/crypto/pq/_d/ref/ntt.h
Normal file
13
src/crypto/pq/_d/ref/ntt.h
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
#ifndef NTT_H
|
||||||
|
#define NTT_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "params.h"
|
||||||
|
|
||||||
|
#define ntt DILITHIUM_NAMESPACE(ntt)
|
||||||
|
void ntt(int32_t a[N]);
|
||||||
|
|
||||||
|
#define invntt_tomont DILITHIUM_NAMESPACE(invntt_tomont)
|
||||||
|
void invntt_tomont(int32_t a[N]);
|
||||||
|
|
||||||
|
#endif
|
||||||
237
src/crypto/pq/_d/ref/packing.c
Normal file
237
src/crypto/pq/_d/ref/packing.c
Normal file
|
|
@ -0,0 +1,237 @@
|
||||||
|
#include "params.h"
|
||||||
|
#include "packing.h"
|
||||||
|
#include "polyvec.h"
|
||||||
|
#include "poly.h"
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: pack_pk
|
||||||
|
*
|
||||||
|
* Description: Bit-pack public key pk = (rho, t1).
|
||||||
|
*
|
||||||
|
* Arguments: - uint8_t pk[]: output byte array
|
||||||
|
* - const uint8_t rho[]: byte array containing rho
|
||||||
|
* - const polyveck *t1: pointer to vector t1
|
||||||
|
**************************************************/
|
||||||
|
void pack_pk(uint8_t pk[CRYPTO_PUBLICKEYBYTES],
|
||||||
|
const uint8_t rho[SEEDBYTES],
|
||||||
|
const polyveck *t1)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for(i = 0; i < SEEDBYTES; ++i)
|
||||||
|
pk[i] = rho[i];
|
||||||
|
pk += SEEDBYTES;
|
||||||
|
|
||||||
|
for(i = 0; i < K; ++i)
|
||||||
|
polyt1_pack(pk + i*POLYT1_PACKEDBYTES, &t1->vec[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: unpack_pk
|
||||||
|
*
|
||||||
|
* Description: Unpack public key pk = (rho, t1).
|
||||||
|
*
|
||||||
|
* Arguments: - const uint8_t rho[]: output byte array for rho
|
||||||
|
* - const polyveck *t1: pointer to output vector t1
|
||||||
|
* - uint8_t pk[]: byte array containing bit-packed pk
|
||||||
|
**************************************************/
|
||||||
|
void unpack_pk(uint8_t rho[SEEDBYTES],
|
||||||
|
polyveck *t1,
|
||||||
|
const uint8_t pk[CRYPTO_PUBLICKEYBYTES])
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for(i = 0; i < SEEDBYTES; ++i)
|
||||||
|
rho[i] = pk[i];
|
||||||
|
pk += SEEDBYTES;
|
||||||
|
|
||||||
|
for(i = 0; i < K; ++i)
|
||||||
|
polyt1_unpack(&t1->vec[i], pk + i*POLYT1_PACKEDBYTES);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: pack_sk
|
||||||
|
*
|
||||||
|
* Description: Bit-pack secret key sk = (rho, tr, key, t0, s1, s2).
|
||||||
|
*
|
||||||
|
* Arguments: - uint8_t sk[]: output byte array
|
||||||
|
* - const uint8_t rho[]: byte array containing rho
|
||||||
|
* - const uint8_t tr[]: byte array containing tr
|
||||||
|
* - const uint8_t key[]: byte array containing key
|
||||||
|
* - const polyveck *t0: pointer to vector t0
|
||||||
|
* - const polyvecl *s1: pointer to vector s1
|
||||||
|
* - const polyveck *s2: pointer to vector s2
|
||||||
|
**************************************************/
|
||||||
|
void pack_sk(uint8_t sk[CRYPTO_SECRETKEYBYTES],
|
||||||
|
const uint8_t rho[SEEDBYTES],
|
||||||
|
const uint8_t tr[TRBYTES],
|
||||||
|
const uint8_t key[SEEDBYTES],
|
||||||
|
const polyveck *t0,
|
||||||
|
const polyvecl *s1,
|
||||||
|
const polyveck *s2)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for(i = 0; i < SEEDBYTES; ++i)
|
||||||
|
sk[i] = rho[i];
|
||||||
|
sk += SEEDBYTES;
|
||||||
|
|
||||||
|
for(i = 0; i < SEEDBYTES; ++i)
|
||||||
|
sk[i] = key[i];
|
||||||
|
sk += SEEDBYTES;
|
||||||
|
|
||||||
|
for(i = 0; i < TRBYTES; ++i)
|
||||||
|
sk[i] = tr[i];
|
||||||
|
sk += TRBYTES;
|
||||||
|
|
||||||
|
for(i = 0; i < L; ++i)
|
||||||
|
polyeta_pack(sk + i*POLYETA_PACKEDBYTES, &s1->vec[i]);
|
||||||
|
sk += L*POLYETA_PACKEDBYTES;
|
||||||
|
|
||||||
|
for(i = 0; i < K; ++i)
|
||||||
|
polyeta_pack(sk + i*POLYETA_PACKEDBYTES, &s2->vec[i]);
|
||||||
|
sk += K*POLYETA_PACKEDBYTES;
|
||||||
|
|
||||||
|
for(i = 0; i < K; ++i)
|
||||||
|
polyt0_pack(sk + i*POLYT0_PACKEDBYTES, &t0->vec[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: unpack_sk
|
||||||
|
*
|
||||||
|
* Description: Unpack secret key sk = (rho, tr, key, t0, s1, s2).
|
||||||
|
*
|
||||||
|
* Arguments: - const uint8_t rho[]: output byte array for rho
|
||||||
|
* - const uint8_t tr[]: output byte array for tr
|
||||||
|
* - const uint8_t key[]: output byte array for key
|
||||||
|
* - const polyveck *t0: pointer to output vector t0
|
||||||
|
* - const polyvecl *s1: pointer to output vector s1
|
||||||
|
* - const polyveck *s2: pointer to output vector s2
|
||||||
|
* - uint8_t sk[]: byte array containing bit-packed sk
|
||||||
|
**************************************************/
|
||||||
|
void unpack_sk(uint8_t rho[SEEDBYTES],
|
||||||
|
uint8_t tr[TRBYTES],
|
||||||
|
uint8_t key[SEEDBYTES],
|
||||||
|
polyveck *t0,
|
||||||
|
polyvecl *s1,
|
||||||
|
polyveck *s2,
|
||||||
|
const uint8_t sk[CRYPTO_SECRETKEYBYTES])
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for(i = 0; i < SEEDBYTES; ++i)
|
||||||
|
rho[i] = sk[i];
|
||||||
|
sk += SEEDBYTES;
|
||||||
|
|
||||||
|
for(i = 0; i < SEEDBYTES; ++i)
|
||||||
|
key[i] = sk[i];
|
||||||
|
sk += SEEDBYTES;
|
||||||
|
|
||||||
|
for(i = 0; i < TRBYTES; ++i)
|
||||||
|
tr[i] = sk[i];
|
||||||
|
sk += TRBYTES;
|
||||||
|
|
||||||
|
for(i=0; i < L; ++i)
|
||||||
|
polyeta_unpack(&s1->vec[i], sk + i*POLYETA_PACKEDBYTES);
|
||||||
|
sk += L*POLYETA_PACKEDBYTES;
|
||||||
|
|
||||||
|
for(i=0; i < K; ++i)
|
||||||
|
polyeta_unpack(&s2->vec[i], sk + i*POLYETA_PACKEDBYTES);
|
||||||
|
sk += K*POLYETA_PACKEDBYTES;
|
||||||
|
|
||||||
|
for(i=0; i < K; ++i)
|
||||||
|
polyt0_unpack(&t0->vec[i], sk + i*POLYT0_PACKEDBYTES);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: pack_sig
|
||||||
|
*
|
||||||
|
* Description: Bit-pack signature sig = (c, z, h).
|
||||||
|
*
|
||||||
|
* Arguments: - uint8_t sig[]: output byte array
|
||||||
|
* - const uint8_t *c: pointer to challenge hash length SEEDBYTES
|
||||||
|
* - const polyvecl *z: pointer to vector z
|
||||||
|
* - const polyveck *h: pointer to hint vector h
|
||||||
|
**************************************************/
|
||||||
|
void pack_sig(uint8_t sig[CRYPTO_BYTES],
|
||||||
|
const uint8_t c[CTILDEBYTES],
|
||||||
|
const polyvecl *z,
|
||||||
|
const polyveck *h)
|
||||||
|
{
|
||||||
|
unsigned int i, j, k;
|
||||||
|
|
||||||
|
for(i=0; i < CTILDEBYTES; ++i)
|
||||||
|
sig[i] = c[i];
|
||||||
|
sig += CTILDEBYTES;
|
||||||
|
|
||||||
|
for(i = 0; i < L; ++i)
|
||||||
|
polyz_pack(sig + i*POLYZ_PACKEDBYTES, &z->vec[i]);
|
||||||
|
sig += L*POLYZ_PACKEDBYTES;
|
||||||
|
|
||||||
|
/* Encode h */
|
||||||
|
for(i = 0; i < OMEGA + K; ++i)
|
||||||
|
sig[i] = 0;
|
||||||
|
|
||||||
|
k = 0;
|
||||||
|
for(i = 0; i < K; ++i) {
|
||||||
|
for(j = 0; j < N; ++j)
|
||||||
|
if(h->vec[i].coeffs[j] != 0)
|
||||||
|
sig[k++] = j;
|
||||||
|
|
||||||
|
sig[OMEGA + i] = k;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: unpack_sig
|
||||||
|
*
|
||||||
|
* Description: Unpack signature sig = (c, z, h).
|
||||||
|
*
|
||||||
|
* Arguments: - uint8_t *c: pointer to output challenge hash
|
||||||
|
* - polyvecl *z: pointer to output vector z
|
||||||
|
* - polyveck *h: pointer to output hint vector h
|
||||||
|
* - const uint8_t sig[]: byte array containing
|
||||||
|
* bit-packed signature
|
||||||
|
*
|
||||||
|
* Returns 1 in case of malformed signature; otherwise 0.
|
||||||
|
**************************************************/
|
||||||
|
int unpack_sig(uint8_t c[CTILDEBYTES],
|
||||||
|
polyvecl *z,
|
||||||
|
polyveck *h,
|
||||||
|
const uint8_t sig[CRYPTO_BYTES])
|
||||||
|
{
|
||||||
|
unsigned int i, j, k;
|
||||||
|
|
||||||
|
for(i = 0; i < CTILDEBYTES; ++i)
|
||||||
|
c[i] = sig[i];
|
||||||
|
sig += CTILDEBYTES;
|
||||||
|
|
||||||
|
for(i = 0; i < L; ++i)
|
||||||
|
polyz_unpack(&z->vec[i], sig + i*POLYZ_PACKEDBYTES);
|
||||||
|
sig += L*POLYZ_PACKEDBYTES;
|
||||||
|
|
||||||
|
/* Decode h */
|
||||||
|
k = 0;
|
||||||
|
for(i = 0; i < K; ++i) {
|
||||||
|
for(j = 0; j < N; ++j)
|
||||||
|
h->vec[i].coeffs[j] = 0;
|
||||||
|
|
||||||
|
if(sig[OMEGA + i] < k || sig[OMEGA + i] > OMEGA)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
for(j = k; j < sig[OMEGA + i]; ++j) {
|
||||||
|
/* Coefficients are ordered for strong unforgeability */
|
||||||
|
if(j > k && sig[j] <= sig[j-1]) return 1;
|
||||||
|
h->vec[i].coeffs[sig[j]] = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
k = sig[OMEGA + i];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Extra indices are zero for strong unforgeability */
|
||||||
|
for(j = k; j < OMEGA; ++j)
|
||||||
|
if(sig[j])
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
38
src/crypto/pq/_d/ref/packing.h
Normal file
38
src/crypto/pq/_d/ref/packing.h
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
#ifndef PACKING_H
|
||||||
|
#define PACKING_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "params.h"
|
||||||
|
#include "polyvec.h"
|
||||||
|
|
||||||
|
#define pack_pk DILITHIUM_NAMESPACE(pack_pk)
|
||||||
|
void pack_pk(uint8_t pk[CRYPTO_PUBLICKEYBYTES], const uint8_t rho[SEEDBYTES], const polyveck *t1);
|
||||||
|
|
||||||
|
#define pack_sk DILITHIUM_NAMESPACE(pack_sk)
|
||||||
|
void pack_sk(uint8_t sk[CRYPTO_SECRETKEYBYTES],
|
||||||
|
const uint8_t rho[SEEDBYTES],
|
||||||
|
const uint8_t tr[TRBYTES],
|
||||||
|
const uint8_t key[SEEDBYTES],
|
||||||
|
const polyveck *t0,
|
||||||
|
const polyvecl *s1,
|
||||||
|
const polyveck *s2);
|
||||||
|
|
||||||
|
#define pack_sig DILITHIUM_NAMESPACE(pack_sig)
|
||||||
|
void pack_sig(uint8_t sig[CRYPTO_BYTES], const uint8_t c[CTILDEBYTES], const polyvecl *z, const polyveck *h);
|
||||||
|
|
||||||
|
#define unpack_pk DILITHIUM_NAMESPACE(unpack_pk)
|
||||||
|
void unpack_pk(uint8_t rho[SEEDBYTES], polyveck *t1, const uint8_t pk[CRYPTO_PUBLICKEYBYTES]);
|
||||||
|
|
||||||
|
#define unpack_sk DILITHIUM_NAMESPACE(unpack_sk)
|
||||||
|
void unpack_sk(uint8_t rho[SEEDBYTES],
|
||||||
|
uint8_t tr[TRBYTES],
|
||||||
|
uint8_t key[SEEDBYTES],
|
||||||
|
polyveck *t0,
|
||||||
|
polyvecl *s1,
|
||||||
|
polyveck *s2,
|
||||||
|
const uint8_t sk[CRYPTO_SECRETKEYBYTES]);
|
||||||
|
|
||||||
|
#define unpack_sig DILITHIUM_NAMESPACE(unpack_sig)
|
||||||
|
int unpack_sig(uint8_t c[CTILDEBYTES], polyvecl *z, polyveck *h, const uint8_t sig[CRYPTO_BYTES]);
|
||||||
|
|
||||||
|
#endif
|
||||||
80
src/crypto/pq/_d/ref/params.h
Normal file
80
src/crypto/pq/_d/ref/params.h
Normal file
|
|
@ -0,0 +1,80 @@
|
||||||
|
#ifndef PARAMS_H
|
||||||
|
#define PARAMS_H
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#define SEEDBYTES 32
|
||||||
|
#define CRHBYTES 64
|
||||||
|
#define TRBYTES 64
|
||||||
|
#define RNDBYTES 32
|
||||||
|
#define N 256
|
||||||
|
#define Q 8380417
|
||||||
|
#define D 13
|
||||||
|
#define ROOT_OF_UNITY 1753
|
||||||
|
|
||||||
|
#if DILITHIUM_MODE == 2
|
||||||
|
#define K 4
|
||||||
|
#define L 4
|
||||||
|
#define ETA 2
|
||||||
|
#define TAU 39
|
||||||
|
#define BETA 78
|
||||||
|
#define GAMMA1 (1 << 17)
|
||||||
|
#define GAMMA2 ((Q-1)/88)
|
||||||
|
#define OMEGA 80
|
||||||
|
#define CTILDEBYTES 32
|
||||||
|
|
||||||
|
#elif DILITHIUM_MODE == 3
|
||||||
|
#define K 6
|
||||||
|
#define L 5
|
||||||
|
#define ETA 4
|
||||||
|
#define TAU 49
|
||||||
|
#define BETA 196
|
||||||
|
#define GAMMA1 (1 << 19)
|
||||||
|
#define GAMMA2 ((Q-1)/32)
|
||||||
|
#define OMEGA 55
|
||||||
|
#define CTILDEBYTES 48
|
||||||
|
|
||||||
|
#elif DILITHIUM_MODE == 5
|
||||||
|
#define K 8
|
||||||
|
#define L 7
|
||||||
|
#define ETA 2
|
||||||
|
#define TAU 60
|
||||||
|
#define BETA 120
|
||||||
|
#define GAMMA1 (1 << 19)
|
||||||
|
#define GAMMA2 ((Q-1)/32)
|
||||||
|
#define OMEGA 75
|
||||||
|
#define CTILDEBYTES 64
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define POLYT1_PACKEDBYTES 320
|
||||||
|
#define POLYT0_PACKEDBYTES 416
|
||||||
|
#define POLYVECH_PACKEDBYTES (OMEGA + K)
|
||||||
|
|
||||||
|
#if GAMMA1 == (1 << 17)
|
||||||
|
#define POLYZ_PACKEDBYTES 576
|
||||||
|
#elif GAMMA1 == (1 << 19)
|
||||||
|
#define POLYZ_PACKEDBYTES 640
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if GAMMA2 == (Q-1)/88
|
||||||
|
#define POLYW1_PACKEDBYTES 192
|
||||||
|
#elif GAMMA2 == (Q-1)/32
|
||||||
|
#define POLYW1_PACKEDBYTES 128
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ETA == 2
|
||||||
|
#define POLYETA_PACKEDBYTES 96
|
||||||
|
#elif ETA == 4
|
||||||
|
#define POLYETA_PACKEDBYTES 128
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define CRYPTO_PUBLICKEYBYTES (SEEDBYTES + K*POLYT1_PACKEDBYTES)
|
||||||
|
#define CRYPTO_SECRETKEYBYTES (2*SEEDBYTES \
|
||||||
|
+ TRBYTES \
|
||||||
|
+ L*POLYETA_PACKEDBYTES \
|
||||||
|
+ K*POLYETA_PACKEDBYTES \
|
||||||
|
+ K*POLYT0_PACKEDBYTES)
|
||||||
|
#define CRYPTO_BYTES (CTILDEBYTES + L*POLYZ_PACKEDBYTES + POLYVECH_PACKEDBYTES)
|
||||||
|
|
||||||
|
#endif
|
||||||
907
src/crypto/pq/_d/ref/poly.c
Normal file
907
src/crypto/pq/_d/ref/poly.c
Normal file
|
|
@ -0,0 +1,907 @@
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "params.h"
|
||||||
|
#include "poly.h"
|
||||||
|
#include "ntt.h"
|
||||||
|
#include "reduce.h"
|
||||||
|
#include "rounding.h"
|
||||||
|
#include "symmetric.h"
|
||||||
|
|
||||||
|
#ifdef DBENCH
|
||||||
|
#include "test/cpucycles.h"
|
||||||
|
extern const uint64_t timing_overhead;
|
||||||
|
extern uint64_t *tred, *tadd, *tmul, *tround, *tsample, *tpack;
|
||||||
|
#define DBENCH_START() uint64_t time = cpucycles()
|
||||||
|
#define DBENCH_STOP(t) t += cpucycles() - time - timing_overhead
|
||||||
|
#else
|
||||||
|
#define DBENCH_START()
|
||||||
|
#define DBENCH_STOP(t)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: poly_reduce
|
||||||
|
*
|
||||||
|
* Description: Inplace reduction of all coefficients of polynomial to
|
||||||
|
* representative in [-6283008,6283008].
|
||||||
|
*
|
||||||
|
* Arguments: - poly *a: pointer to input/output polynomial
|
||||||
|
**************************************************/
|
||||||
|
void poly_reduce(poly *a) {
|
||||||
|
unsigned int i;
|
||||||
|
DBENCH_START();
|
||||||
|
|
||||||
|
for(i = 0; i < N; ++i)
|
||||||
|
a->coeffs[i] = reduce32(a->coeffs[i]);
|
||||||
|
|
||||||
|
DBENCH_STOP(*tred);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: poly_caddq
|
||||||
|
*
|
||||||
|
* Description: For all coefficients of in/out polynomial add Q if
|
||||||
|
* coefficient is negative.
|
||||||
|
*
|
||||||
|
* Arguments: - poly *a: pointer to input/output polynomial
|
||||||
|
**************************************************/
|
||||||
|
void poly_caddq(poly *a) {
|
||||||
|
unsigned int i;
|
||||||
|
DBENCH_START();
|
||||||
|
|
||||||
|
for(i = 0; i < N; ++i)
|
||||||
|
a->coeffs[i] = caddq(a->coeffs[i]);
|
||||||
|
|
||||||
|
DBENCH_STOP(*tred);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: poly_add
|
||||||
|
*
|
||||||
|
* Description: Add polynomials. No modular reduction is performed.
|
||||||
|
*
|
||||||
|
* Arguments: - poly *c: pointer to output polynomial
|
||||||
|
* - const poly *a: pointer to first summand
|
||||||
|
* - const poly *b: pointer to second summand
|
||||||
|
**************************************************/
|
||||||
|
void poly_add(poly *c, const poly *a, const poly *b) {
|
||||||
|
unsigned int i;
|
||||||
|
DBENCH_START();
|
||||||
|
|
||||||
|
for(i = 0; i < N; ++i)
|
||||||
|
c->coeffs[i] = a->coeffs[i] + b->coeffs[i];
|
||||||
|
|
||||||
|
DBENCH_STOP(*tadd);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: poly_sub
|
||||||
|
*
|
||||||
|
* Description: Subtract polynomials. No modular reduction is
|
||||||
|
* performed.
|
||||||
|
*
|
||||||
|
* Arguments: - poly *c: pointer to output polynomial
|
||||||
|
* - const poly *a: pointer to first input polynomial
|
||||||
|
* - const poly *b: pointer to second input polynomial to be
|
||||||
|
* subtraced from first input polynomial
|
||||||
|
**************************************************/
|
||||||
|
void poly_sub(poly *c, const poly *a, const poly *b) {
|
||||||
|
unsigned int i;
|
||||||
|
DBENCH_START();
|
||||||
|
|
||||||
|
for(i = 0; i < N; ++i)
|
||||||
|
c->coeffs[i] = a->coeffs[i] - b->coeffs[i];
|
||||||
|
|
||||||
|
DBENCH_STOP(*tadd);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: poly_shiftl
|
||||||
|
*
|
||||||
|
* Description: Multiply polynomial by 2^D without modular reduction. Assumes
|
||||||
|
* input coefficients to be less than 2^{31-D} in absolute value.
|
||||||
|
*
|
||||||
|
* Arguments: - poly *a: pointer to input/output polynomial
|
||||||
|
**************************************************/
|
||||||
|
void poly_shiftl(poly *a) {
|
||||||
|
unsigned int i;
|
||||||
|
DBENCH_START();
|
||||||
|
|
||||||
|
for(i = 0; i < N; ++i)
|
||||||
|
a->coeffs[i] <<= D;
|
||||||
|
|
||||||
|
DBENCH_STOP(*tmul);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: poly_ntt
|
||||||
|
*
|
||||||
|
* Description: Inplace forward NTT. Coefficients can grow by
|
||||||
|
* 8*Q in absolute value.
|
||||||
|
*
|
||||||
|
* Arguments: - poly *a: pointer to input/output polynomial
|
||||||
|
**************************************************/
|
||||||
|
void poly_ntt(poly *a) {
|
||||||
|
DBENCH_START();
|
||||||
|
|
||||||
|
ntt(a->coeffs);
|
||||||
|
|
||||||
|
DBENCH_STOP(*tmul);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: poly_invntt_tomont
|
||||||
|
*
|
||||||
|
* Description: Inplace inverse NTT and multiplication by 2^{32}.
|
||||||
|
* Input coefficients need to be less than Q in absolute
|
||||||
|
* value and output coefficients are again bounded by Q.
|
||||||
|
*
|
||||||
|
* Arguments: - poly *a: pointer to input/output polynomial
|
||||||
|
**************************************************/
|
||||||
|
void poly_invntt_tomont(poly *a) {
|
||||||
|
DBENCH_START();
|
||||||
|
|
||||||
|
invntt_tomont(a->coeffs);
|
||||||
|
|
||||||
|
DBENCH_STOP(*tmul);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: poly_pointwise_montgomery
|
||||||
|
*
|
||||||
|
* Description: Pointwise multiplication of polynomials in NTT domain
|
||||||
|
* representation and multiplication of resulting polynomial
|
||||||
|
* by 2^{-32}.
|
||||||
|
*
|
||||||
|
* Arguments: - poly *c: pointer to output polynomial
|
||||||
|
* - const poly *a: pointer to first input polynomial
|
||||||
|
* - const poly *b: pointer to second input polynomial
|
||||||
|
**************************************************/
|
||||||
|
void poly_pointwise_montgomery(poly *c, const poly *a, const poly *b) {
|
||||||
|
unsigned int i;
|
||||||
|
DBENCH_START();
|
||||||
|
|
||||||
|
for(i = 0; i < N; ++i)
|
||||||
|
c->coeffs[i] = montgomery_reduce((int64_t)a->coeffs[i] * b->coeffs[i]);
|
||||||
|
|
||||||
|
DBENCH_STOP(*tmul);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: poly_power2round
|
||||||
|
*
|
||||||
|
* Description: For all coefficients c of the input polynomial,
|
||||||
|
* compute c0, c1 such that c mod Q = c1*2^D + c0
|
||||||
|
* with -2^{D-1} < c0 <= 2^{D-1}. Assumes coefficients to be
|
||||||
|
* standard representatives.
|
||||||
|
*
|
||||||
|
* Arguments: - poly *a1: pointer to output polynomial with coefficients c1
|
||||||
|
* - poly *a0: pointer to output polynomial with coefficients c0
|
||||||
|
* - const poly *a: pointer to input polynomial
|
||||||
|
**************************************************/
|
||||||
|
void poly_power2round(poly *a1, poly *a0, const poly *a) {
|
||||||
|
unsigned int i;
|
||||||
|
DBENCH_START();
|
||||||
|
|
||||||
|
for(i = 0; i < N; ++i)
|
||||||
|
a1->coeffs[i] = power2round(&a0->coeffs[i], a->coeffs[i]);
|
||||||
|
|
||||||
|
DBENCH_STOP(*tround);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: poly_decompose
|
||||||
|
*
|
||||||
|
* Description: For all coefficients c of the input polynomial,
|
||||||
|
* compute high and low bits c0, c1 such c mod Q = c1*ALPHA + c0
|
||||||
|
* with -ALPHA/2 < c0 <= ALPHA/2 except c1 = (Q-1)/ALPHA where we
|
||||||
|
* set c1 = 0 and -ALPHA/2 <= c0 = c mod Q - Q < 0.
|
||||||
|
* Assumes coefficients to be standard representatives.
|
||||||
|
*
|
||||||
|
* Arguments: - poly *a1: pointer to output polynomial with coefficients c1
|
||||||
|
* - poly *a0: pointer to output polynomial with coefficients c0
|
||||||
|
* - const poly *a: pointer to input polynomial
|
||||||
|
**************************************************/
|
||||||
|
void poly_decompose(poly *a1, poly *a0, const poly *a) {
|
||||||
|
unsigned int i;
|
||||||
|
DBENCH_START();
|
||||||
|
|
||||||
|
for(i = 0; i < N; ++i)
|
||||||
|
a1->coeffs[i] = decompose(&a0->coeffs[i], a->coeffs[i]);
|
||||||
|
|
||||||
|
DBENCH_STOP(*tround);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: poly_make_hint
|
||||||
|
*
|
||||||
|
* Description: Compute hint polynomial. The coefficients of which indicate
|
||||||
|
* whether the low bits of the corresponding coefficient of
|
||||||
|
* the input polynomial overflow into the high bits.
|
||||||
|
*
|
||||||
|
* Arguments: - poly *h: pointer to output hint polynomial
|
||||||
|
* - const poly *a0: pointer to low part of input polynomial
|
||||||
|
* - const poly *a1: pointer to high part of input polynomial
|
||||||
|
*
|
||||||
|
* Returns number of 1 bits.
|
||||||
|
**************************************************/
|
||||||
|
unsigned int poly_make_hint(poly *h, const poly *a0, const poly *a1) {
|
||||||
|
unsigned int i, s = 0;
|
||||||
|
DBENCH_START();
|
||||||
|
|
||||||
|
for(i = 0; i < N; ++i) {
|
||||||
|
h->coeffs[i] = make_hint(a0->coeffs[i], a1->coeffs[i]);
|
||||||
|
s += h->coeffs[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
DBENCH_STOP(*tround);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: poly_use_hint
|
||||||
|
*
|
||||||
|
* Description: Use hint polynomial to correct the high bits of a polynomial.
|
||||||
|
*
|
||||||
|
* Arguments: - poly *b: pointer to output polynomial with corrected high bits
|
||||||
|
* - const poly *a: pointer to input polynomial
|
||||||
|
* - const poly *h: pointer to input hint polynomial
|
||||||
|
**************************************************/
|
||||||
|
void poly_use_hint(poly *b, const poly *a, const poly *h) {
|
||||||
|
unsigned int i;
|
||||||
|
DBENCH_START();
|
||||||
|
|
||||||
|
for(i = 0; i < N; ++i)
|
||||||
|
b->coeffs[i] = use_hint(a->coeffs[i], h->coeffs[i]);
|
||||||
|
|
||||||
|
DBENCH_STOP(*tround);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: poly_chknorm
|
||||||
|
*
|
||||||
|
* Description: Check infinity norm of polynomial against given bound.
|
||||||
|
* Assumes input coefficients were reduced by reduce32().
|
||||||
|
*
|
||||||
|
* Arguments: - const poly *a: pointer to polynomial
|
||||||
|
* - int32_t B: norm bound
|
||||||
|
*
|
||||||
|
* Returns 0 if norm is strictly smaller than B <= (Q-1)/8 and 1 otherwise.
|
||||||
|
**************************************************/
|
||||||
|
int poly_chknorm(const poly *a, int32_t B) {
|
||||||
|
unsigned int i;
|
||||||
|
int32_t t;
|
||||||
|
DBENCH_START();
|
||||||
|
|
||||||
|
if(B > (Q-1)/8)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
/* It is ok to leak which coefficient violates the bound since
|
||||||
|
the probability for each coefficient is independent of secret
|
||||||
|
data but we must not leak the sign of the centralized representative. */
|
||||||
|
for(i = 0; i < N; ++i) {
|
||||||
|
/* Absolute value */
|
||||||
|
t = a->coeffs[i] >> 31;
|
||||||
|
t = a->coeffs[i] - (t & 2*a->coeffs[i]);
|
||||||
|
|
||||||
|
if(t >= B) {
|
||||||
|
DBENCH_STOP(*tsample);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DBENCH_STOP(*tsample);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: rej_uniform
|
||||||
|
*
|
||||||
|
* Description: Sample uniformly random coefficients in [0, Q-1] by
|
||||||
|
* performing rejection sampling on array of random bytes.
|
||||||
|
*
|
||||||
|
* Arguments: - int32_t *a: pointer to output array (allocated)
|
||||||
|
* - unsigned int len: number of coefficients to be sampled
|
||||||
|
* - const uint8_t *buf: array of random bytes
|
||||||
|
* - unsigned int buflen: length of array of random bytes
|
||||||
|
*
|
||||||
|
* Returns number of sampled coefficients. Can be smaller than len if not enough
|
||||||
|
* random bytes were given.
|
||||||
|
**************************************************/
|
||||||
|
static unsigned int rej_uniform(int32_t *a,
|
||||||
|
unsigned int len,
|
||||||
|
const uint8_t *buf,
|
||||||
|
unsigned int buflen)
|
||||||
|
{
|
||||||
|
unsigned int ctr, pos;
|
||||||
|
uint32_t t;
|
||||||
|
DBENCH_START();
|
||||||
|
|
||||||
|
ctr = pos = 0;
|
||||||
|
while(ctr < len && pos + 3 <= buflen) {
|
||||||
|
t = buf[pos++];
|
||||||
|
t |= (uint32_t)buf[pos++] << 8;
|
||||||
|
t |= (uint32_t)buf[pos++] << 16;
|
||||||
|
t &= 0x7FFFFF;
|
||||||
|
|
||||||
|
if(t < Q)
|
||||||
|
a[ctr++] = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
DBENCH_STOP(*tsample);
|
||||||
|
return ctr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: poly_uniform
|
||||||
|
*
|
||||||
|
* Description: Sample polynomial with uniformly random coefficients
|
||||||
|
* in [0,Q-1] by performing rejection sampling on the
|
||||||
|
* output stream of SHAKE128(seed|nonce)
|
||||||
|
*
|
||||||
|
* Arguments: - poly *a: pointer to output polynomial
|
||||||
|
* - const uint8_t seed[]: byte array with seed of length SEEDBYTES
|
||||||
|
* - uint16_t nonce: 2-byte nonce
|
||||||
|
**************************************************/
|
||||||
|
#define POLY_UNIFORM_NBLOCKS ((768 + STREAM128_BLOCKBYTES - 1)/STREAM128_BLOCKBYTES)
|
||||||
|
void poly_uniform(poly *a,
|
||||||
|
const uint8_t seed[SEEDBYTES],
|
||||||
|
uint16_t nonce)
|
||||||
|
{
|
||||||
|
unsigned int i, ctr, off;
|
||||||
|
unsigned int buflen = POLY_UNIFORM_NBLOCKS*STREAM128_BLOCKBYTES;
|
||||||
|
uint8_t buf[POLY_UNIFORM_NBLOCKS*STREAM128_BLOCKBYTES + 2];
|
||||||
|
stream128_state state;
|
||||||
|
|
||||||
|
stream128_init(&state, seed, nonce);
|
||||||
|
stream128_squeezeblocks(buf, POLY_UNIFORM_NBLOCKS, &state);
|
||||||
|
|
||||||
|
ctr = rej_uniform(a->coeffs, N, buf, buflen);
|
||||||
|
|
||||||
|
while(ctr < N) {
|
||||||
|
off = buflen % 3;
|
||||||
|
for(i = 0; i < off; ++i)
|
||||||
|
buf[i] = buf[buflen - off + i];
|
||||||
|
|
||||||
|
stream128_squeezeblocks(buf + off, 1, &state);
|
||||||
|
buflen = STREAM128_BLOCKBYTES + off;
|
||||||
|
ctr += rej_uniform(a->coeffs + ctr, N - ctr, buf, buflen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: rej_eta
|
||||||
|
*
|
||||||
|
* Description: Sample uniformly random coefficients in [-ETA, ETA] by
|
||||||
|
* performing rejection sampling on array of random bytes.
|
||||||
|
*
|
||||||
|
* Arguments: - int32_t *a: pointer to output array (allocated)
|
||||||
|
* - unsigned int len: number of coefficients to be sampled
|
||||||
|
* - const uint8_t *buf: array of random bytes
|
||||||
|
* - unsigned int buflen: length of array of random bytes
|
||||||
|
*
|
||||||
|
* Returns number of sampled coefficients. Can be smaller than len if not enough
|
||||||
|
* random bytes were given.
|
||||||
|
**************************************************/
|
||||||
|
static unsigned int rej_eta(int32_t *a,
|
||||||
|
unsigned int len,
|
||||||
|
const uint8_t *buf,
|
||||||
|
unsigned int buflen)
|
||||||
|
{
|
||||||
|
unsigned int ctr, pos;
|
||||||
|
uint32_t t0, t1;
|
||||||
|
DBENCH_START();
|
||||||
|
|
||||||
|
ctr = pos = 0;
|
||||||
|
while(ctr < len && pos < buflen) {
|
||||||
|
t0 = buf[pos] & 0x0F;
|
||||||
|
t1 = buf[pos++] >> 4;
|
||||||
|
|
||||||
|
#if ETA == 2
|
||||||
|
if(t0 < 15) {
|
||||||
|
t0 = t0 - (205*t0 >> 10)*5;
|
||||||
|
a[ctr++] = 2 - t0;
|
||||||
|
}
|
||||||
|
if(t1 < 15 && ctr < len) {
|
||||||
|
t1 = t1 - (205*t1 >> 10)*5;
|
||||||
|
a[ctr++] = 2 - t1;
|
||||||
|
}
|
||||||
|
#elif ETA == 4
|
||||||
|
if(t0 < 9)
|
||||||
|
a[ctr++] = 4 - t0;
|
||||||
|
if(t1 < 9 && ctr < len)
|
||||||
|
a[ctr++] = 4 - t1;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
DBENCH_STOP(*tsample);
|
||||||
|
return ctr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: poly_uniform_eta
|
||||||
|
*
|
||||||
|
* Description: Sample polynomial with uniformly random coefficients
|
||||||
|
* in [-ETA,ETA] by performing rejection sampling on the
|
||||||
|
* output stream from SHAKE256(seed|nonce)
|
||||||
|
*
|
||||||
|
* Arguments: - poly *a: pointer to output polynomial
|
||||||
|
* - const uint8_t seed[]: byte array with seed of length CRHBYTES
|
||||||
|
* - uint16_t nonce: 2-byte nonce
|
||||||
|
**************************************************/
|
||||||
|
#if ETA == 2
|
||||||
|
#define POLY_UNIFORM_ETA_NBLOCKS ((136 + STREAM256_BLOCKBYTES - 1)/STREAM256_BLOCKBYTES)
|
||||||
|
#elif ETA == 4
|
||||||
|
#define POLY_UNIFORM_ETA_NBLOCKS ((227 + STREAM256_BLOCKBYTES - 1)/STREAM256_BLOCKBYTES)
|
||||||
|
#endif
|
||||||
|
void poly_uniform_eta(poly *a,
|
||||||
|
const uint8_t seed[CRHBYTES],
|
||||||
|
uint16_t nonce)
|
||||||
|
{
|
||||||
|
unsigned int ctr;
|
||||||
|
unsigned int buflen = POLY_UNIFORM_ETA_NBLOCKS*STREAM256_BLOCKBYTES;
|
||||||
|
uint8_t buf[POLY_UNIFORM_ETA_NBLOCKS*STREAM256_BLOCKBYTES];
|
||||||
|
stream256_state state;
|
||||||
|
|
||||||
|
stream256_init(&state, seed, nonce);
|
||||||
|
stream256_squeezeblocks(buf, POLY_UNIFORM_ETA_NBLOCKS, &state);
|
||||||
|
|
||||||
|
ctr = rej_eta(a->coeffs, N, buf, buflen);
|
||||||
|
|
||||||
|
while(ctr < N) {
|
||||||
|
stream256_squeezeblocks(buf, 1, &state);
|
||||||
|
ctr += rej_eta(a->coeffs + ctr, N - ctr, buf, STREAM256_BLOCKBYTES);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: poly_uniform_gamma1m1
|
||||||
|
*
|
||||||
|
* Description: Sample polynomial with uniformly random coefficients
|
||||||
|
* in [-(GAMMA1 - 1), GAMMA1] by unpacking output stream
|
||||||
|
* of SHAKE256(seed|nonce)
|
||||||
|
*
|
||||||
|
* Arguments: - poly *a: pointer to output polynomial
|
||||||
|
* - const uint8_t seed[]: byte array with seed of length CRHBYTES
|
||||||
|
* - uint16_t nonce: 16-bit nonce
|
||||||
|
**************************************************/
|
||||||
|
#define POLY_UNIFORM_GAMMA1_NBLOCKS ((POLYZ_PACKEDBYTES + STREAM256_BLOCKBYTES - 1)/STREAM256_BLOCKBYTES)
|
||||||
|
void poly_uniform_gamma1(poly *a,
|
||||||
|
const uint8_t seed[CRHBYTES],
|
||||||
|
uint16_t nonce)
|
||||||
|
{
|
||||||
|
uint8_t buf[POLY_UNIFORM_GAMMA1_NBLOCKS*STREAM256_BLOCKBYTES];
|
||||||
|
stream256_state state;
|
||||||
|
|
||||||
|
stream256_init(&state, seed, nonce);
|
||||||
|
stream256_squeezeblocks(buf, POLY_UNIFORM_GAMMA1_NBLOCKS, &state);
|
||||||
|
polyz_unpack(a, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: challenge
|
||||||
|
*
|
||||||
|
* Description: Implementation of H. Samples polynomial with TAU nonzero
|
||||||
|
* coefficients in {-1,1} using the output stream of
|
||||||
|
* SHAKE256(seed).
|
||||||
|
*
|
||||||
|
* Arguments: - poly *c: pointer to output polynomial
|
||||||
|
* - const uint8_t mu[]: byte array containing seed of length CTILDEBYTES
|
||||||
|
**************************************************/
|
||||||
|
void poly_challenge(poly *c, const uint8_t seed[CTILDEBYTES]) {
|
||||||
|
unsigned int i, b, pos;
|
||||||
|
uint64_t signs;
|
||||||
|
uint8_t buf[SHAKE256_RATE];
|
||||||
|
keccak_state state;
|
||||||
|
|
||||||
|
shake256_init(&state);
|
||||||
|
shake256_absorb(&state, seed, CTILDEBYTES);
|
||||||
|
shake256_finalize(&state);
|
||||||
|
shake256_squeezeblocks(buf, 1, &state);
|
||||||
|
|
||||||
|
signs = 0;
|
||||||
|
for(i = 0; i < 8; ++i)
|
||||||
|
signs |= (uint64_t)buf[i] << 8*i;
|
||||||
|
pos = 8;
|
||||||
|
|
||||||
|
for(i = 0; i < N; ++i)
|
||||||
|
c->coeffs[i] = 0;
|
||||||
|
for(i = N-TAU; i < N; ++i) {
|
||||||
|
do {
|
||||||
|
if(pos >= SHAKE256_RATE) {
|
||||||
|
shake256_squeezeblocks(buf, 1, &state);
|
||||||
|
pos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
b = buf[pos++];
|
||||||
|
} while(b > i);
|
||||||
|
|
||||||
|
c->coeffs[i] = c->coeffs[b];
|
||||||
|
c->coeffs[b] = 1 - 2*(signs & 1);
|
||||||
|
signs >>= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: polyeta_pack
|
||||||
|
*
|
||||||
|
* Description: Bit-pack polynomial with coefficients in [-ETA,ETA].
|
||||||
|
*
|
||||||
|
* Arguments: - uint8_t *r: pointer to output byte array with at least
|
||||||
|
* POLYETA_PACKEDBYTES bytes
|
||||||
|
* - const poly *a: pointer to input polynomial
|
||||||
|
**************************************************/
|
||||||
|
void polyeta_pack(uint8_t *r, const poly *a) {
|
||||||
|
unsigned int i;
|
||||||
|
uint8_t t[8];
|
||||||
|
DBENCH_START();
|
||||||
|
|
||||||
|
#if ETA == 2
|
||||||
|
for(i = 0; i < N/8; ++i) {
|
||||||
|
t[0] = ETA - a->coeffs[8*i+0];
|
||||||
|
t[1] = ETA - a->coeffs[8*i+1];
|
||||||
|
t[2] = ETA - a->coeffs[8*i+2];
|
||||||
|
t[3] = ETA - a->coeffs[8*i+3];
|
||||||
|
t[4] = ETA - a->coeffs[8*i+4];
|
||||||
|
t[5] = ETA - a->coeffs[8*i+5];
|
||||||
|
t[6] = ETA - a->coeffs[8*i+6];
|
||||||
|
t[7] = ETA - a->coeffs[8*i+7];
|
||||||
|
|
||||||
|
r[3*i+0] = (t[0] >> 0) | (t[1] << 3) | (t[2] << 6);
|
||||||
|
r[3*i+1] = (t[2] >> 2) | (t[3] << 1) | (t[4] << 4) | (t[5] << 7);
|
||||||
|
r[3*i+2] = (t[5] >> 1) | (t[6] << 2) | (t[7] << 5);
|
||||||
|
}
|
||||||
|
#elif ETA == 4
|
||||||
|
for(i = 0; i < N/2; ++i) {
|
||||||
|
t[0] = ETA - a->coeffs[2*i+0];
|
||||||
|
t[1] = ETA - a->coeffs[2*i+1];
|
||||||
|
r[i] = t[0] | (t[1] << 4);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
DBENCH_STOP(*tpack);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: polyeta_unpack
|
||||||
|
*
|
||||||
|
* Description: Unpack polynomial with coefficients in [-ETA,ETA].
|
||||||
|
*
|
||||||
|
* Arguments: - poly *r: pointer to output polynomial
|
||||||
|
* - const uint8_t *a: byte array with bit-packed polynomial
|
||||||
|
**************************************************/
|
||||||
|
void polyeta_unpack(poly *r, const uint8_t *a) {
|
||||||
|
unsigned int i;
|
||||||
|
DBENCH_START();
|
||||||
|
|
||||||
|
#if ETA == 2
|
||||||
|
for(i = 0; i < N/8; ++i) {
|
||||||
|
r->coeffs[8*i+0] = (a[3*i+0] >> 0) & 7;
|
||||||
|
r->coeffs[8*i+1] = (a[3*i+0] >> 3) & 7;
|
||||||
|
r->coeffs[8*i+2] = ((a[3*i+0] >> 6) | (a[3*i+1] << 2)) & 7;
|
||||||
|
r->coeffs[8*i+3] = (a[3*i+1] >> 1) & 7;
|
||||||
|
r->coeffs[8*i+4] = (a[3*i+1] >> 4) & 7;
|
||||||
|
r->coeffs[8*i+5] = ((a[3*i+1] >> 7) | (a[3*i+2] << 1)) & 7;
|
||||||
|
r->coeffs[8*i+6] = (a[3*i+2] >> 2) & 7;
|
||||||
|
r->coeffs[8*i+7] = (a[3*i+2] >> 5) & 7;
|
||||||
|
|
||||||
|
r->coeffs[8*i+0] = ETA - r->coeffs[8*i+0];
|
||||||
|
r->coeffs[8*i+1] = ETA - r->coeffs[8*i+1];
|
||||||
|
r->coeffs[8*i+2] = ETA - r->coeffs[8*i+2];
|
||||||
|
r->coeffs[8*i+3] = ETA - r->coeffs[8*i+3];
|
||||||
|
r->coeffs[8*i+4] = ETA - r->coeffs[8*i+4];
|
||||||
|
r->coeffs[8*i+5] = ETA - r->coeffs[8*i+5];
|
||||||
|
r->coeffs[8*i+6] = ETA - r->coeffs[8*i+6];
|
||||||
|
r->coeffs[8*i+7] = ETA - r->coeffs[8*i+7];
|
||||||
|
}
|
||||||
|
#elif ETA == 4
|
||||||
|
for(i = 0; i < N/2; ++i) {
|
||||||
|
r->coeffs[2*i+0] = a[i] & 0x0F;
|
||||||
|
r->coeffs[2*i+1] = a[i] >> 4;
|
||||||
|
r->coeffs[2*i+0] = ETA - r->coeffs[2*i+0];
|
||||||
|
r->coeffs[2*i+1] = ETA - r->coeffs[2*i+1];
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
DBENCH_STOP(*tpack);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: polyt1_pack
|
||||||
|
*
|
||||||
|
* Description: Bit-pack polynomial t1 with coefficients fitting in 10 bits.
|
||||||
|
* Input coefficients are assumed to be standard representatives.
|
||||||
|
*
|
||||||
|
* Arguments: - uint8_t *r: pointer to output byte array with at least
|
||||||
|
* POLYT1_PACKEDBYTES bytes
|
||||||
|
* - const poly *a: pointer to input polynomial
|
||||||
|
**************************************************/
|
||||||
|
void polyt1_pack(uint8_t *r, const poly *a) {
|
||||||
|
unsigned int i;
|
||||||
|
DBENCH_START();
|
||||||
|
|
||||||
|
for(i = 0; i < N/4; ++i) {
|
||||||
|
r[5*i+0] = (a->coeffs[4*i+0] >> 0);
|
||||||
|
r[5*i+1] = (a->coeffs[4*i+0] >> 8) | (a->coeffs[4*i+1] << 2);
|
||||||
|
r[5*i+2] = (a->coeffs[4*i+1] >> 6) | (a->coeffs[4*i+2] << 4);
|
||||||
|
r[5*i+3] = (a->coeffs[4*i+2] >> 4) | (a->coeffs[4*i+3] << 6);
|
||||||
|
r[5*i+4] = (a->coeffs[4*i+3] >> 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
DBENCH_STOP(*tpack);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: polyt1_unpack
|
||||||
|
*
|
||||||
|
* Description: Unpack polynomial t1 with 10-bit coefficients.
|
||||||
|
* Output coefficients are standard representatives.
|
||||||
|
*
|
||||||
|
* Arguments: - poly *r: pointer to output polynomial
|
||||||
|
* - const uint8_t *a: byte array with bit-packed polynomial
|
||||||
|
**************************************************/
|
||||||
|
void polyt1_unpack(poly *r, const uint8_t *a) {
|
||||||
|
unsigned int i;
|
||||||
|
DBENCH_START();
|
||||||
|
|
||||||
|
for(i = 0; i < N/4; ++i) {
|
||||||
|
r->coeffs[4*i+0] = ((a[5*i+0] >> 0) | ((uint32_t)a[5*i+1] << 8)) & 0x3FF;
|
||||||
|
r->coeffs[4*i+1] = ((a[5*i+1] >> 2) | ((uint32_t)a[5*i+2] << 6)) & 0x3FF;
|
||||||
|
r->coeffs[4*i+2] = ((a[5*i+2] >> 4) | ((uint32_t)a[5*i+3] << 4)) & 0x3FF;
|
||||||
|
r->coeffs[4*i+3] = ((a[5*i+3] >> 6) | ((uint32_t)a[5*i+4] << 2)) & 0x3FF;
|
||||||
|
}
|
||||||
|
|
||||||
|
DBENCH_STOP(*tpack);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: polyt0_pack
|
||||||
|
*
|
||||||
|
* Description: Bit-pack polynomial t0 with coefficients in ]-2^{D-1}, 2^{D-1}].
|
||||||
|
*
|
||||||
|
* Arguments: - uint8_t *r: pointer to output byte array with at least
|
||||||
|
* POLYT0_PACKEDBYTES bytes
|
||||||
|
* - const poly *a: pointer to input polynomial
|
||||||
|
**************************************************/
|
||||||
|
void polyt0_pack(uint8_t *r, const poly *a) {
|
||||||
|
unsigned int i;
|
||||||
|
uint32_t t[8];
|
||||||
|
DBENCH_START();
|
||||||
|
|
||||||
|
for(i = 0; i < N/8; ++i) {
|
||||||
|
t[0] = (1 << (D-1)) - a->coeffs[8*i+0];
|
||||||
|
t[1] = (1 << (D-1)) - a->coeffs[8*i+1];
|
||||||
|
t[2] = (1 << (D-1)) - a->coeffs[8*i+2];
|
||||||
|
t[3] = (1 << (D-1)) - a->coeffs[8*i+3];
|
||||||
|
t[4] = (1 << (D-1)) - a->coeffs[8*i+4];
|
||||||
|
t[5] = (1 << (D-1)) - a->coeffs[8*i+5];
|
||||||
|
t[6] = (1 << (D-1)) - a->coeffs[8*i+6];
|
||||||
|
t[7] = (1 << (D-1)) - a->coeffs[8*i+7];
|
||||||
|
|
||||||
|
r[13*i+ 0] = t[0];
|
||||||
|
r[13*i+ 1] = t[0] >> 8;
|
||||||
|
r[13*i+ 1] |= t[1] << 5;
|
||||||
|
r[13*i+ 2] = t[1] >> 3;
|
||||||
|
r[13*i+ 3] = t[1] >> 11;
|
||||||
|
r[13*i+ 3] |= t[2] << 2;
|
||||||
|
r[13*i+ 4] = t[2] >> 6;
|
||||||
|
r[13*i+ 4] |= t[3] << 7;
|
||||||
|
r[13*i+ 5] = t[3] >> 1;
|
||||||
|
r[13*i+ 6] = t[3] >> 9;
|
||||||
|
r[13*i+ 6] |= t[4] << 4;
|
||||||
|
r[13*i+ 7] = t[4] >> 4;
|
||||||
|
r[13*i+ 8] = t[4] >> 12;
|
||||||
|
r[13*i+ 8] |= t[5] << 1;
|
||||||
|
r[13*i+ 9] = t[5] >> 7;
|
||||||
|
r[13*i+ 9] |= t[6] << 6;
|
||||||
|
r[13*i+10] = t[6] >> 2;
|
||||||
|
r[13*i+11] = t[6] >> 10;
|
||||||
|
r[13*i+11] |= t[7] << 3;
|
||||||
|
r[13*i+12] = t[7] >> 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
DBENCH_STOP(*tpack);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: polyt0_unpack
|
||||||
|
*
|
||||||
|
* Description: Unpack polynomial t0 with coefficients in ]-2^{D-1}, 2^{D-1}].
|
||||||
|
*
|
||||||
|
* Arguments: - poly *r: pointer to output polynomial
|
||||||
|
* - const uint8_t *a: byte array with bit-packed polynomial
|
||||||
|
**************************************************/
|
||||||
|
void polyt0_unpack(poly *r, const uint8_t *a) {
|
||||||
|
unsigned int i;
|
||||||
|
DBENCH_START();
|
||||||
|
|
||||||
|
for(i = 0; i < N/8; ++i) {
|
||||||
|
r->coeffs[8*i+0] = a[13*i+0];
|
||||||
|
r->coeffs[8*i+0] |= (uint32_t)a[13*i+1] << 8;
|
||||||
|
r->coeffs[8*i+0] &= 0x1FFF;
|
||||||
|
|
||||||
|
r->coeffs[8*i+1] = a[13*i+1] >> 5;
|
||||||
|
r->coeffs[8*i+1] |= (uint32_t)a[13*i+2] << 3;
|
||||||
|
r->coeffs[8*i+1] |= (uint32_t)a[13*i+3] << 11;
|
||||||
|
r->coeffs[8*i+1] &= 0x1FFF;
|
||||||
|
|
||||||
|
r->coeffs[8*i+2] = a[13*i+3] >> 2;
|
||||||
|
r->coeffs[8*i+2] |= (uint32_t)a[13*i+4] << 6;
|
||||||
|
r->coeffs[8*i+2] &= 0x1FFF;
|
||||||
|
|
||||||
|
r->coeffs[8*i+3] = a[13*i+4] >> 7;
|
||||||
|
r->coeffs[8*i+3] |= (uint32_t)a[13*i+5] << 1;
|
||||||
|
r->coeffs[8*i+3] |= (uint32_t)a[13*i+6] << 9;
|
||||||
|
r->coeffs[8*i+3] &= 0x1FFF;
|
||||||
|
|
||||||
|
r->coeffs[8*i+4] = a[13*i+6] >> 4;
|
||||||
|
r->coeffs[8*i+4] |= (uint32_t)a[13*i+7] << 4;
|
||||||
|
r->coeffs[8*i+4] |= (uint32_t)a[13*i+8] << 12;
|
||||||
|
r->coeffs[8*i+4] &= 0x1FFF;
|
||||||
|
|
||||||
|
r->coeffs[8*i+5] = a[13*i+8] >> 1;
|
||||||
|
r->coeffs[8*i+5] |= (uint32_t)a[13*i+9] << 7;
|
||||||
|
r->coeffs[8*i+5] &= 0x1FFF;
|
||||||
|
|
||||||
|
r->coeffs[8*i+6] = a[13*i+9] >> 6;
|
||||||
|
r->coeffs[8*i+6] |= (uint32_t)a[13*i+10] << 2;
|
||||||
|
r->coeffs[8*i+6] |= (uint32_t)a[13*i+11] << 10;
|
||||||
|
r->coeffs[8*i+6] &= 0x1FFF;
|
||||||
|
|
||||||
|
r->coeffs[8*i+7] = a[13*i+11] >> 3;
|
||||||
|
r->coeffs[8*i+7] |= (uint32_t)a[13*i+12] << 5;
|
||||||
|
r->coeffs[8*i+7] &= 0x1FFF;
|
||||||
|
|
||||||
|
r->coeffs[8*i+0] = (1 << (D-1)) - r->coeffs[8*i+0];
|
||||||
|
r->coeffs[8*i+1] = (1 << (D-1)) - r->coeffs[8*i+1];
|
||||||
|
r->coeffs[8*i+2] = (1 << (D-1)) - r->coeffs[8*i+2];
|
||||||
|
r->coeffs[8*i+3] = (1 << (D-1)) - r->coeffs[8*i+3];
|
||||||
|
r->coeffs[8*i+4] = (1 << (D-1)) - r->coeffs[8*i+4];
|
||||||
|
r->coeffs[8*i+5] = (1 << (D-1)) - r->coeffs[8*i+5];
|
||||||
|
r->coeffs[8*i+6] = (1 << (D-1)) - r->coeffs[8*i+6];
|
||||||
|
r->coeffs[8*i+7] = (1 << (D-1)) - r->coeffs[8*i+7];
|
||||||
|
}
|
||||||
|
|
||||||
|
DBENCH_STOP(*tpack);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: polyz_pack
|
||||||
|
*
|
||||||
|
* Description: Bit-pack polynomial with coefficients
|
||||||
|
* in [-(GAMMA1 - 1), GAMMA1].
|
||||||
|
*
|
||||||
|
* Arguments: - uint8_t *r: pointer to output byte array with at least
|
||||||
|
* POLYZ_PACKEDBYTES bytes
|
||||||
|
* - const poly *a: pointer to input polynomial
|
||||||
|
**************************************************/
|
||||||
|
void polyz_pack(uint8_t *r, const poly *a) {
|
||||||
|
unsigned int i;
|
||||||
|
uint32_t t[4];
|
||||||
|
DBENCH_START();
|
||||||
|
|
||||||
|
#if GAMMA1 == (1 << 17)
|
||||||
|
for(i = 0; i < N/4; ++i) {
|
||||||
|
t[0] = GAMMA1 - a->coeffs[4*i+0];
|
||||||
|
t[1] = GAMMA1 - a->coeffs[4*i+1];
|
||||||
|
t[2] = GAMMA1 - a->coeffs[4*i+2];
|
||||||
|
t[3] = GAMMA1 - a->coeffs[4*i+3];
|
||||||
|
|
||||||
|
r[9*i+0] = t[0];
|
||||||
|
r[9*i+1] = t[0] >> 8;
|
||||||
|
r[9*i+2] = t[0] >> 16;
|
||||||
|
r[9*i+2] |= t[1] << 2;
|
||||||
|
r[9*i+3] = t[1] >> 6;
|
||||||
|
r[9*i+4] = t[1] >> 14;
|
||||||
|
r[9*i+4] |= t[2] << 4;
|
||||||
|
r[9*i+5] = t[2] >> 4;
|
||||||
|
r[9*i+6] = t[2] >> 12;
|
||||||
|
r[9*i+6] |= t[3] << 6;
|
||||||
|
r[9*i+7] = t[3] >> 2;
|
||||||
|
r[9*i+8] = t[3] >> 10;
|
||||||
|
}
|
||||||
|
#elif GAMMA1 == (1 << 19)
|
||||||
|
for(i = 0; i < N/2; ++i) {
|
||||||
|
t[0] = GAMMA1 - a->coeffs[2*i+0];
|
||||||
|
t[1] = GAMMA1 - a->coeffs[2*i+1];
|
||||||
|
|
||||||
|
r[5*i+0] = t[0];
|
||||||
|
r[5*i+1] = t[0] >> 8;
|
||||||
|
r[5*i+2] = t[0] >> 16;
|
||||||
|
r[5*i+2] |= t[1] << 4;
|
||||||
|
r[5*i+3] = t[1] >> 4;
|
||||||
|
r[5*i+4] = t[1] >> 12;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
DBENCH_STOP(*tpack);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: polyz_unpack
|
||||||
|
*
|
||||||
|
* Description: Unpack polynomial z with coefficients
|
||||||
|
* in [-(GAMMA1 - 1), GAMMA1].
|
||||||
|
*
|
||||||
|
* Arguments: - poly *r: pointer to output polynomial
|
||||||
|
* - const uint8_t *a: byte array with bit-packed polynomial
|
||||||
|
**************************************************/
|
||||||
|
void polyz_unpack(poly *r, const uint8_t *a) {
|
||||||
|
unsigned int i;
|
||||||
|
DBENCH_START();
|
||||||
|
|
||||||
|
#if GAMMA1 == (1 << 17)
|
||||||
|
for(i = 0; i < N/4; ++i) {
|
||||||
|
r->coeffs[4*i+0] = a[9*i+0];
|
||||||
|
r->coeffs[4*i+0] |= (uint32_t)a[9*i+1] << 8;
|
||||||
|
r->coeffs[4*i+0] |= (uint32_t)a[9*i+2] << 16;
|
||||||
|
r->coeffs[4*i+0] &= 0x3FFFF;
|
||||||
|
|
||||||
|
r->coeffs[4*i+1] = a[9*i+2] >> 2;
|
||||||
|
r->coeffs[4*i+1] |= (uint32_t)a[9*i+3] << 6;
|
||||||
|
r->coeffs[4*i+1] |= (uint32_t)a[9*i+4] << 14;
|
||||||
|
r->coeffs[4*i+1] &= 0x3FFFF;
|
||||||
|
|
||||||
|
r->coeffs[4*i+2] = a[9*i+4] >> 4;
|
||||||
|
r->coeffs[4*i+2] |= (uint32_t)a[9*i+5] << 4;
|
||||||
|
r->coeffs[4*i+2] |= (uint32_t)a[9*i+6] << 12;
|
||||||
|
r->coeffs[4*i+2] &= 0x3FFFF;
|
||||||
|
|
||||||
|
r->coeffs[4*i+3] = a[9*i+6] >> 6;
|
||||||
|
r->coeffs[4*i+3] |= (uint32_t)a[9*i+7] << 2;
|
||||||
|
r->coeffs[4*i+3] |= (uint32_t)a[9*i+8] << 10;
|
||||||
|
r->coeffs[4*i+3] &= 0x3FFFF;
|
||||||
|
|
||||||
|
r->coeffs[4*i+0] = GAMMA1 - r->coeffs[4*i+0];
|
||||||
|
r->coeffs[4*i+1] = GAMMA1 - r->coeffs[4*i+1];
|
||||||
|
r->coeffs[4*i+2] = GAMMA1 - r->coeffs[4*i+2];
|
||||||
|
r->coeffs[4*i+3] = GAMMA1 - r->coeffs[4*i+3];
|
||||||
|
}
|
||||||
|
#elif GAMMA1 == (1 << 19)
|
||||||
|
for(i = 0; i < N/2; ++i) {
|
||||||
|
r->coeffs[2*i+0] = a[5*i+0];
|
||||||
|
r->coeffs[2*i+0] |= (uint32_t)a[5*i+1] << 8;
|
||||||
|
r->coeffs[2*i+0] |= (uint32_t)a[5*i+2] << 16;
|
||||||
|
r->coeffs[2*i+0] &= 0xFFFFF;
|
||||||
|
|
||||||
|
r->coeffs[2*i+1] = a[5*i+2] >> 4;
|
||||||
|
r->coeffs[2*i+1] |= (uint32_t)a[5*i+3] << 4;
|
||||||
|
r->coeffs[2*i+1] |= (uint32_t)a[5*i+4] << 12;
|
||||||
|
/* r->coeffs[2*i+1] &= 0xFFFFF; */ /* No effect, since we're anyway at 20 bits */
|
||||||
|
|
||||||
|
r->coeffs[2*i+0] = GAMMA1 - r->coeffs[2*i+0];
|
||||||
|
r->coeffs[2*i+1] = GAMMA1 - r->coeffs[2*i+1];
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
DBENCH_STOP(*tpack);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: polyw1_pack
|
||||||
|
*
|
||||||
|
* Description: Bit-pack polynomial w1 with coefficients in [0,15] or [0,43].
|
||||||
|
* Input coefficients are assumed to be standard representatives.
|
||||||
|
*
|
||||||
|
* Arguments: - uint8_t *r: pointer to output byte array with at least
|
||||||
|
* POLYW1_PACKEDBYTES bytes
|
||||||
|
* - const poly *a: pointer to input polynomial
|
||||||
|
**************************************************/
|
||||||
|
void polyw1_pack(uint8_t *r, const poly *a) {
|
||||||
|
unsigned int i;
|
||||||
|
DBENCH_START();
|
||||||
|
|
||||||
|
#if GAMMA2 == (Q-1)/88
|
||||||
|
for(i = 0; i < N/4; ++i) {
|
||||||
|
r[3*i+0] = a->coeffs[4*i+0];
|
||||||
|
r[3*i+0] |= a->coeffs[4*i+1] << 6;
|
||||||
|
r[3*i+1] = a->coeffs[4*i+1] >> 2;
|
||||||
|
r[3*i+1] |= a->coeffs[4*i+2] << 4;
|
||||||
|
r[3*i+2] = a->coeffs[4*i+2] >> 4;
|
||||||
|
r[3*i+2] |= a->coeffs[4*i+3] << 2;
|
||||||
|
}
|
||||||
|
#elif GAMMA2 == (Q-1)/32
|
||||||
|
for(i = 0; i < N/2; ++i)
|
||||||
|
r[i] = a->coeffs[2*i+0] | (a->coeffs[2*i+1] << 4);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
DBENCH_STOP(*tpack);
|
||||||
|
}
|
||||||
79
src/crypto/pq/_d/ref/poly.h
Normal file
79
src/crypto/pq/_d/ref/poly.h
Normal file
|
|
@ -0,0 +1,79 @@
|
||||||
|
#ifndef POLY_H
|
||||||
|
#define POLY_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "params.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int32_t coeffs[N];
|
||||||
|
} poly;
|
||||||
|
|
||||||
|
#define poly_reduce DILITHIUM_NAMESPACE(poly_reduce)
|
||||||
|
void poly_reduce(poly *a);
|
||||||
|
#define poly_caddq DILITHIUM_NAMESPACE(poly_caddq)
|
||||||
|
void poly_caddq(poly *a);
|
||||||
|
|
||||||
|
#define poly_add DILITHIUM_NAMESPACE(poly_add)
|
||||||
|
void poly_add(poly *c, const poly *a, const poly *b);
|
||||||
|
#define poly_sub DILITHIUM_NAMESPACE(poly_sub)
|
||||||
|
void poly_sub(poly *c, const poly *a, const poly *b);
|
||||||
|
#define poly_shiftl DILITHIUM_NAMESPACE(poly_shiftl)
|
||||||
|
void poly_shiftl(poly *a);
|
||||||
|
|
||||||
|
#define poly_ntt DILITHIUM_NAMESPACE(poly_ntt)
|
||||||
|
void poly_ntt(poly *a);
|
||||||
|
#define poly_invntt_tomont DILITHIUM_NAMESPACE(poly_invntt_tomont)
|
||||||
|
void poly_invntt_tomont(poly *a);
|
||||||
|
#define poly_pointwise_montgomery DILITHIUM_NAMESPACE(poly_pointwise_montgomery)
|
||||||
|
void poly_pointwise_montgomery(poly *c, const poly *a, const poly *b);
|
||||||
|
|
||||||
|
#define poly_power2round DILITHIUM_NAMESPACE(poly_power2round)
|
||||||
|
void poly_power2round(poly *a1, poly *a0, const poly *a);
|
||||||
|
#define poly_decompose DILITHIUM_NAMESPACE(poly_decompose)
|
||||||
|
void poly_decompose(poly *a1, poly *a0, const poly *a);
|
||||||
|
#define poly_make_hint DILITHIUM_NAMESPACE(poly_make_hint)
|
||||||
|
unsigned int poly_make_hint(poly *h, const poly *a0, const poly *a1);
|
||||||
|
#define poly_use_hint DILITHIUM_NAMESPACE(poly_use_hint)
|
||||||
|
void poly_use_hint(poly *b, const poly *a, const poly *h);
|
||||||
|
|
||||||
|
#define poly_chknorm DILITHIUM_NAMESPACE(poly_chknorm)
|
||||||
|
int poly_chknorm(const poly *a, int32_t B);
|
||||||
|
#define poly_uniform DILITHIUM_NAMESPACE(poly_uniform)
|
||||||
|
void poly_uniform(poly *a,
|
||||||
|
const uint8_t seed[SEEDBYTES],
|
||||||
|
uint16_t nonce);
|
||||||
|
#define poly_uniform_eta DILITHIUM_NAMESPACE(poly_uniform_eta)
|
||||||
|
void poly_uniform_eta(poly *a,
|
||||||
|
const uint8_t seed[CRHBYTES],
|
||||||
|
uint16_t nonce);
|
||||||
|
#define poly_uniform_gamma1 DILITHIUM_NAMESPACE(poly_uniform_gamma1)
|
||||||
|
void poly_uniform_gamma1(poly *a,
|
||||||
|
const uint8_t seed[CRHBYTES],
|
||||||
|
uint16_t nonce);
|
||||||
|
#define poly_challenge DILITHIUM_NAMESPACE(poly_challenge)
|
||||||
|
void poly_challenge(poly *c, const uint8_t seed[CTILDEBYTES]);
|
||||||
|
|
||||||
|
#define polyeta_pack DILITHIUM_NAMESPACE(polyeta_pack)
|
||||||
|
void polyeta_pack(uint8_t *r, const poly *a);
|
||||||
|
#define polyeta_unpack DILITHIUM_NAMESPACE(polyeta_unpack)
|
||||||
|
void polyeta_unpack(poly *r, const uint8_t *a);
|
||||||
|
|
||||||
|
#define polyt1_pack DILITHIUM_NAMESPACE(polyt1_pack)
|
||||||
|
void polyt1_pack(uint8_t *r, const poly *a);
|
||||||
|
#define polyt1_unpack DILITHIUM_NAMESPACE(polyt1_unpack)
|
||||||
|
void polyt1_unpack(poly *r, const uint8_t *a);
|
||||||
|
|
||||||
|
#define polyt0_pack DILITHIUM_NAMESPACE(polyt0_pack)
|
||||||
|
void polyt0_pack(uint8_t *r, const poly *a);
|
||||||
|
#define polyt0_unpack DILITHIUM_NAMESPACE(polyt0_unpack)
|
||||||
|
void polyt0_unpack(poly *r, const uint8_t *a);
|
||||||
|
|
||||||
|
#define polyz_pack DILITHIUM_NAMESPACE(polyz_pack)
|
||||||
|
void polyz_pack(uint8_t *r, const poly *a);
|
||||||
|
#define polyz_unpack DILITHIUM_NAMESPACE(polyz_unpack)
|
||||||
|
void polyz_unpack(poly *r, const uint8_t *a);
|
||||||
|
|
||||||
|
#define polyw1_pack DILITHIUM_NAMESPACE(polyw1_pack)
|
||||||
|
void polyw1_pack(uint8_t *r, const poly *a);
|
||||||
|
|
||||||
|
#endif
|
||||||
389
src/crypto/pq/_d/ref/polyvec.c
Normal file
389
src/crypto/pq/_d/ref/polyvec.c
Normal file
|
|
@ -0,0 +1,389 @@
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "params.h"
|
||||||
|
#include "polyvec.h"
|
||||||
|
#include "poly.h"
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: expand_mat
|
||||||
|
*
|
||||||
|
* Description: Implementation of ExpandA. Generates matrix A with uniformly
|
||||||
|
* random coefficients a_{i,j} by performing rejection
|
||||||
|
* sampling on the output stream of SHAKE128(rho|j|i)
|
||||||
|
*
|
||||||
|
* Arguments: - polyvecl mat[K]: output matrix
|
||||||
|
* - const uint8_t rho[]: byte array containing seed rho
|
||||||
|
**************************************************/
|
||||||
|
void polyvec_matrix_expand(polyvecl mat[K], const uint8_t rho[SEEDBYTES]) {
|
||||||
|
unsigned int i, j;
|
||||||
|
|
||||||
|
for(i = 0; i < K; ++i)
|
||||||
|
for(j = 0; j < L; ++j)
|
||||||
|
poly_uniform(&mat[i].vec[j], rho, (i << 8) + j);
|
||||||
|
}
|
||||||
|
|
||||||
|
void polyvec_matrix_pointwise_montgomery(polyveck *t, const polyvecl mat[K], const polyvecl *v) {
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for(i = 0; i < K; ++i)
|
||||||
|
polyvecl_pointwise_acc_montgomery(&t->vec[i], &mat[i], v);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************************************************/
|
||||||
|
/************ Vectors of polynomials of length L **************/
|
||||||
|
/**************************************************************/
|
||||||
|
|
||||||
|
void polyvecl_uniform_eta(polyvecl *v, const uint8_t seed[CRHBYTES], uint16_t nonce) {
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for(i = 0; i < L; ++i)
|
||||||
|
poly_uniform_eta(&v->vec[i], seed, nonce++);
|
||||||
|
}
|
||||||
|
|
||||||
|
void polyvecl_uniform_gamma1(polyvecl *v, const uint8_t seed[CRHBYTES], uint16_t nonce) {
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for(i = 0; i < L; ++i)
|
||||||
|
poly_uniform_gamma1(&v->vec[i], seed, L*nonce + i);
|
||||||
|
}
|
||||||
|
|
||||||
|
void polyvecl_reduce(polyvecl *v) {
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for(i = 0; i < L; ++i)
|
||||||
|
poly_reduce(&v->vec[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: polyvecl_add
|
||||||
|
*
|
||||||
|
* Description: Add vectors of polynomials of length L.
|
||||||
|
* No modular reduction is performed.
|
||||||
|
*
|
||||||
|
* Arguments: - polyvecl *w: pointer to output vector
|
||||||
|
* - const polyvecl *u: pointer to first summand
|
||||||
|
* - const polyvecl *v: pointer to second summand
|
||||||
|
**************************************************/
|
||||||
|
void polyvecl_add(polyvecl *w, const polyvecl *u, const polyvecl *v) {
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for(i = 0; i < L; ++i)
|
||||||
|
poly_add(&w->vec[i], &u->vec[i], &v->vec[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: polyvecl_ntt
|
||||||
|
*
|
||||||
|
* Description: Forward NTT of all polynomials in vector of length L. Output
|
||||||
|
* coefficients can be up to 16*Q larger than input coefficients.
|
||||||
|
*
|
||||||
|
* Arguments: - polyvecl *v: pointer to input/output vector
|
||||||
|
**************************************************/
|
||||||
|
void polyvecl_ntt(polyvecl *v) {
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for(i = 0; i < L; ++i)
|
||||||
|
poly_ntt(&v->vec[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void polyvecl_invntt_tomont(polyvecl *v) {
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for(i = 0; i < L; ++i)
|
||||||
|
poly_invntt_tomont(&v->vec[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void polyvecl_pointwise_poly_montgomery(polyvecl *r, const poly *a, const polyvecl *v) {
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for(i = 0; i < L; ++i)
|
||||||
|
poly_pointwise_montgomery(&r->vec[i], a, &v->vec[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: polyvecl_pointwise_acc_montgomery
|
||||||
|
*
|
||||||
|
* Description: Pointwise multiply vectors of polynomials of length L, multiply
|
||||||
|
* resulting vector by 2^{-32} and add (accumulate) polynomials
|
||||||
|
* in it. Input/output vectors are in NTT domain representation.
|
||||||
|
*
|
||||||
|
* Arguments: - poly *w: output polynomial
|
||||||
|
* - const polyvecl *u: pointer to first input vector
|
||||||
|
* - const polyvecl *v: pointer to second input vector
|
||||||
|
**************************************************/
|
||||||
|
void polyvecl_pointwise_acc_montgomery(poly *w,
|
||||||
|
const polyvecl *u,
|
||||||
|
const polyvecl *v)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
poly t;
|
||||||
|
|
||||||
|
poly_pointwise_montgomery(w, &u->vec[0], &v->vec[0]);
|
||||||
|
for(i = 1; i < L; ++i) {
|
||||||
|
poly_pointwise_montgomery(&t, &u->vec[i], &v->vec[i]);
|
||||||
|
poly_add(w, w, &t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: polyvecl_chknorm
|
||||||
|
*
|
||||||
|
* Description: Check infinity norm of polynomials in vector of length L.
|
||||||
|
* Assumes input polyvecl to be reduced by polyvecl_reduce().
|
||||||
|
*
|
||||||
|
* Arguments: - const polyvecl *v: pointer to vector
|
||||||
|
* - int32_t B: norm bound
|
||||||
|
*
|
||||||
|
* Returns 0 if norm of all polynomials is strictly smaller than B <= (Q-1)/8
|
||||||
|
* and 1 otherwise.
|
||||||
|
**************************************************/
|
||||||
|
int polyvecl_chknorm(const polyvecl *v, int32_t bound) {
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for(i = 0; i < L; ++i)
|
||||||
|
if(poly_chknorm(&v->vec[i], bound))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************************************************/
|
||||||
|
/************ Vectors of polynomials of length K **************/
|
||||||
|
/**************************************************************/
|
||||||
|
|
||||||
|
void polyveck_uniform_eta(polyveck *v, const uint8_t seed[CRHBYTES], uint16_t nonce) {
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for(i = 0; i < K; ++i)
|
||||||
|
poly_uniform_eta(&v->vec[i], seed, nonce++);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: polyveck_reduce
|
||||||
|
*
|
||||||
|
* Description: Reduce coefficients of polynomials in vector of length K
|
||||||
|
* to representatives in [-6283008,6283008].
|
||||||
|
*
|
||||||
|
* Arguments: - polyveck *v: pointer to input/output vector
|
||||||
|
**************************************************/
|
||||||
|
void polyveck_reduce(polyveck *v) {
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for(i = 0; i < K; ++i)
|
||||||
|
poly_reduce(&v->vec[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: polyveck_caddq
|
||||||
|
*
|
||||||
|
* Description: For all coefficients of polynomials in vector of length K
|
||||||
|
* add Q if coefficient is negative.
|
||||||
|
*
|
||||||
|
* Arguments: - polyveck *v: pointer to input/output vector
|
||||||
|
**************************************************/
|
||||||
|
void polyveck_caddq(polyveck *v) {
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for(i = 0; i < K; ++i)
|
||||||
|
poly_caddq(&v->vec[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: polyveck_add
|
||||||
|
*
|
||||||
|
* Description: Add vectors of polynomials of length K.
|
||||||
|
* No modular reduction is performed.
|
||||||
|
*
|
||||||
|
* Arguments: - polyveck *w: pointer to output vector
|
||||||
|
* - const polyveck *u: pointer to first summand
|
||||||
|
* - const polyveck *v: pointer to second summand
|
||||||
|
**************************************************/
|
||||||
|
void polyveck_add(polyveck *w, const polyveck *u, const polyveck *v) {
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for(i = 0; i < K; ++i)
|
||||||
|
poly_add(&w->vec[i], &u->vec[i], &v->vec[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: polyveck_sub
|
||||||
|
*
|
||||||
|
* Description: Subtract vectors of polynomials of length K.
|
||||||
|
* No modular reduction is performed.
|
||||||
|
*
|
||||||
|
* Arguments: - polyveck *w: pointer to output vector
|
||||||
|
* - const polyveck *u: pointer to first input vector
|
||||||
|
* - const polyveck *v: pointer to second input vector to be
|
||||||
|
* subtracted from first input vector
|
||||||
|
**************************************************/
|
||||||
|
void polyveck_sub(polyveck *w, const polyveck *u, const polyveck *v) {
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for(i = 0; i < K; ++i)
|
||||||
|
poly_sub(&w->vec[i], &u->vec[i], &v->vec[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: polyveck_shiftl
|
||||||
|
*
|
||||||
|
* Description: Multiply vector of polynomials of Length K by 2^D without modular
|
||||||
|
* reduction. Assumes input coefficients to be less than 2^{31-D}.
|
||||||
|
*
|
||||||
|
* Arguments: - polyveck *v: pointer to input/output vector
|
||||||
|
**************************************************/
|
||||||
|
void polyveck_shiftl(polyveck *v) {
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for(i = 0; i < K; ++i)
|
||||||
|
poly_shiftl(&v->vec[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: polyveck_ntt
|
||||||
|
*
|
||||||
|
* Description: Forward NTT of all polynomials in vector of length K. Output
|
||||||
|
* coefficients can be up to 16*Q larger than input coefficients.
|
||||||
|
*
|
||||||
|
* Arguments: - polyveck *v: pointer to input/output vector
|
||||||
|
**************************************************/
|
||||||
|
void polyveck_ntt(polyveck *v) {
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for(i = 0; i < K; ++i)
|
||||||
|
poly_ntt(&v->vec[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: polyveck_invntt_tomont
|
||||||
|
*
|
||||||
|
* Description: Inverse NTT and multiplication by 2^{32} of polynomials
|
||||||
|
* in vector of length K. Input coefficients need to be less
|
||||||
|
* than 2*Q.
|
||||||
|
*
|
||||||
|
* Arguments: - polyveck *v: pointer to input/output vector
|
||||||
|
**************************************************/
|
||||||
|
void polyveck_invntt_tomont(polyveck *v) {
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for(i = 0; i < K; ++i)
|
||||||
|
poly_invntt_tomont(&v->vec[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void polyveck_pointwise_poly_montgomery(polyveck *r, const poly *a, const polyveck *v) {
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for(i = 0; i < K; ++i)
|
||||||
|
poly_pointwise_montgomery(&r->vec[i], a, &v->vec[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: polyveck_chknorm
|
||||||
|
*
|
||||||
|
* Description: Check infinity norm of polynomials in vector of length K.
|
||||||
|
* Assumes input polyveck to be reduced by polyveck_reduce().
|
||||||
|
*
|
||||||
|
* Arguments: - const polyveck *v: pointer to vector
|
||||||
|
* - int32_t B: norm bound
|
||||||
|
*
|
||||||
|
* Returns 0 if norm of all polynomials are strictly smaller than B <= (Q-1)/8
|
||||||
|
* and 1 otherwise.
|
||||||
|
**************************************************/
|
||||||
|
int polyveck_chknorm(const polyveck *v, int32_t bound) {
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for(i = 0; i < K; ++i)
|
||||||
|
if(poly_chknorm(&v->vec[i], bound))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: polyveck_power2round
|
||||||
|
*
|
||||||
|
* Description: For all coefficients a of polynomials in vector of length K,
|
||||||
|
* compute a0, a1 such that a mod^+ Q = a1*2^D + a0
|
||||||
|
* with -2^{D-1} < a0 <= 2^{D-1}. Assumes coefficients to be
|
||||||
|
* standard representatives.
|
||||||
|
*
|
||||||
|
* Arguments: - polyveck *v1: pointer to output vector of polynomials with
|
||||||
|
* coefficients a1
|
||||||
|
* - polyveck *v0: pointer to output vector of polynomials with
|
||||||
|
* coefficients a0
|
||||||
|
* - const polyveck *v: pointer to input vector
|
||||||
|
**************************************************/
|
||||||
|
void polyveck_power2round(polyveck *v1, polyveck *v0, const polyveck *v) {
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for(i = 0; i < K; ++i)
|
||||||
|
poly_power2round(&v1->vec[i], &v0->vec[i], &v->vec[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: polyveck_decompose
|
||||||
|
*
|
||||||
|
* Description: For all coefficients a of polynomials in vector of length K,
|
||||||
|
* compute high and low bits a0, a1 such a mod^+ Q = a1*ALPHA + a0
|
||||||
|
* with -ALPHA/2 < a0 <= ALPHA/2 except a1 = (Q-1)/ALPHA where we
|
||||||
|
* set a1 = 0 and -ALPHA/2 <= a0 = a mod Q - Q < 0.
|
||||||
|
* Assumes coefficients to be standard representatives.
|
||||||
|
*
|
||||||
|
* Arguments: - polyveck *v1: pointer to output vector of polynomials with
|
||||||
|
* coefficients a1
|
||||||
|
* - polyveck *v0: pointer to output vector of polynomials with
|
||||||
|
* coefficients a0
|
||||||
|
* - const polyveck *v: pointer to input vector
|
||||||
|
**************************************************/
|
||||||
|
void polyveck_decompose(polyveck *v1, polyveck *v0, const polyveck *v) {
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for(i = 0; i < K; ++i)
|
||||||
|
poly_decompose(&v1->vec[i], &v0->vec[i], &v->vec[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: polyveck_make_hint
|
||||||
|
*
|
||||||
|
* Description: Compute hint vector.
|
||||||
|
*
|
||||||
|
* Arguments: - polyveck *h: pointer to output vector
|
||||||
|
* - const polyveck *v0: pointer to low part of input vector
|
||||||
|
* - const polyveck *v1: pointer to high part of input vector
|
||||||
|
*
|
||||||
|
* Returns number of 1 bits.
|
||||||
|
**************************************************/
|
||||||
|
unsigned int polyveck_make_hint(polyveck *h,
|
||||||
|
const polyveck *v0,
|
||||||
|
const polyveck *v1)
|
||||||
|
{
|
||||||
|
unsigned int i, s = 0;
|
||||||
|
|
||||||
|
for(i = 0; i < K; ++i)
|
||||||
|
s += poly_make_hint(&h->vec[i], &v0->vec[i], &v1->vec[i]);
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: polyveck_use_hint
|
||||||
|
*
|
||||||
|
* Description: Use hint vector to correct the high bits of input vector.
|
||||||
|
*
|
||||||
|
* Arguments: - polyveck *w: pointer to output vector of polynomials with
|
||||||
|
* corrected high bits
|
||||||
|
* - const polyveck *u: pointer to input vector
|
||||||
|
* - const polyveck *h: pointer to input hint vector
|
||||||
|
**************************************************/
|
||||||
|
void polyveck_use_hint(polyveck *w, const polyveck *u, const polyveck *h) {
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for(i = 0; i < K; ++i)
|
||||||
|
poly_use_hint(&w->vec[i], &u->vec[i], &h->vec[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void polyveck_pack_w1(uint8_t r[K*POLYW1_PACKEDBYTES], const polyveck *w1) {
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for(i = 0; i < K; ++i)
|
||||||
|
polyw1_pack(&r[i*POLYW1_PACKEDBYTES], &w1->vec[i]);
|
||||||
|
}
|
||||||
93
src/crypto/pq/_d/ref/polyvec.h
Normal file
93
src/crypto/pq/_d/ref/polyvec.h
Normal file
|
|
@ -0,0 +1,93 @@
|
||||||
|
#ifndef POLYVEC_H
|
||||||
|
#define POLYVEC_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "params.h"
|
||||||
|
#include "poly.h"
|
||||||
|
|
||||||
|
/* Vectors of polynomials of length L */
|
||||||
|
typedef struct {
|
||||||
|
poly vec[L];
|
||||||
|
} polyvecl;
|
||||||
|
|
||||||
|
#define polyvecl_uniform_eta DILITHIUM_NAMESPACE(polyvecl_uniform_eta)
|
||||||
|
void polyvecl_uniform_eta(polyvecl *v, const uint8_t seed[CRHBYTES], uint16_t nonce);
|
||||||
|
|
||||||
|
#define polyvecl_uniform_gamma1 DILITHIUM_NAMESPACE(polyvecl_uniform_gamma1)
|
||||||
|
void polyvecl_uniform_gamma1(polyvecl *v, const uint8_t seed[CRHBYTES], uint16_t nonce);
|
||||||
|
|
||||||
|
#define polyvecl_reduce DILITHIUM_NAMESPACE(polyvecl_reduce)
|
||||||
|
void polyvecl_reduce(polyvecl *v);
|
||||||
|
|
||||||
|
#define polyvecl_add DILITHIUM_NAMESPACE(polyvecl_add)
|
||||||
|
void polyvecl_add(polyvecl *w, const polyvecl *u, const polyvecl *v);
|
||||||
|
|
||||||
|
#define polyvecl_ntt DILITHIUM_NAMESPACE(polyvecl_ntt)
|
||||||
|
void polyvecl_ntt(polyvecl *v);
|
||||||
|
#define polyvecl_invntt_tomont DILITHIUM_NAMESPACE(polyvecl_invntt_tomont)
|
||||||
|
void polyvecl_invntt_tomont(polyvecl *v);
|
||||||
|
#define polyvecl_pointwise_poly_montgomery DILITHIUM_NAMESPACE(polyvecl_pointwise_poly_montgomery)
|
||||||
|
void polyvecl_pointwise_poly_montgomery(polyvecl *r, const poly *a, const polyvecl *v);
|
||||||
|
#define polyvecl_pointwise_acc_montgomery \
|
||||||
|
DILITHIUM_NAMESPACE(polyvecl_pointwise_acc_montgomery)
|
||||||
|
void polyvecl_pointwise_acc_montgomery(poly *w,
|
||||||
|
const polyvecl *u,
|
||||||
|
const polyvecl *v);
|
||||||
|
|
||||||
|
|
||||||
|
#define polyvecl_chknorm DILITHIUM_NAMESPACE(polyvecl_chknorm)
|
||||||
|
int polyvecl_chknorm(const polyvecl *v, int32_t B);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Vectors of polynomials of length K */
|
||||||
|
typedef struct {
|
||||||
|
poly vec[K];
|
||||||
|
} polyveck;
|
||||||
|
|
||||||
|
#define polyveck_uniform_eta DILITHIUM_NAMESPACE(polyveck_uniform_eta)
|
||||||
|
void polyveck_uniform_eta(polyveck *v, const uint8_t seed[CRHBYTES], uint16_t nonce);
|
||||||
|
|
||||||
|
#define polyveck_reduce DILITHIUM_NAMESPACE(polyveck_reduce)
|
||||||
|
void polyveck_reduce(polyveck *v);
|
||||||
|
#define polyveck_caddq DILITHIUM_NAMESPACE(polyveck_caddq)
|
||||||
|
void polyveck_caddq(polyveck *v);
|
||||||
|
|
||||||
|
#define polyveck_add DILITHIUM_NAMESPACE(polyveck_add)
|
||||||
|
void polyveck_add(polyveck *w, const polyveck *u, const polyveck *v);
|
||||||
|
#define polyveck_sub DILITHIUM_NAMESPACE(polyveck_sub)
|
||||||
|
void polyveck_sub(polyveck *w, const polyveck *u, const polyveck *v);
|
||||||
|
#define polyveck_shiftl DILITHIUM_NAMESPACE(polyveck_shiftl)
|
||||||
|
void polyveck_shiftl(polyveck *v);
|
||||||
|
|
||||||
|
#define polyveck_ntt DILITHIUM_NAMESPACE(polyveck_ntt)
|
||||||
|
void polyveck_ntt(polyveck *v);
|
||||||
|
#define polyveck_invntt_tomont DILITHIUM_NAMESPACE(polyveck_invntt_tomont)
|
||||||
|
void polyveck_invntt_tomont(polyveck *v);
|
||||||
|
#define polyveck_pointwise_poly_montgomery DILITHIUM_NAMESPACE(polyveck_pointwise_poly_montgomery)
|
||||||
|
void polyveck_pointwise_poly_montgomery(polyveck *r, const poly *a, const polyveck *v);
|
||||||
|
|
||||||
|
#define polyveck_chknorm DILITHIUM_NAMESPACE(polyveck_chknorm)
|
||||||
|
int polyveck_chknorm(const polyveck *v, int32_t B);
|
||||||
|
|
||||||
|
#define polyveck_power2round DILITHIUM_NAMESPACE(polyveck_power2round)
|
||||||
|
void polyveck_power2round(polyveck *v1, polyveck *v0, const polyveck *v);
|
||||||
|
#define polyveck_decompose DILITHIUM_NAMESPACE(polyveck_decompose)
|
||||||
|
void polyveck_decompose(polyveck *v1, polyveck *v0, const polyveck *v);
|
||||||
|
#define polyveck_make_hint DILITHIUM_NAMESPACE(polyveck_make_hint)
|
||||||
|
unsigned int polyveck_make_hint(polyveck *h,
|
||||||
|
const polyveck *v0,
|
||||||
|
const polyveck *v1);
|
||||||
|
#define polyveck_use_hint DILITHIUM_NAMESPACE(polyveck_use_hint)
|
||||||
|
void polyveck_use_hint(polyveck *w, const polyveck *v, const polyveck *h);
|
||||||
|
|
||||||
|
#define polyveck_pack_w1 DILITHIUM_NAMESPACE(polyveck_pack_w1)
|
||||||
|
void polyveck_pack_w1(uint8_t r[K*POLYW1_PACKEDBYTES], const polyveck *w1);
|
||||||
|
|
||||||
|
#define polyvec_matrix_expand DILITHIUM_NAMESPACE(polyvec_matrix_expand)
|
||||||
|
void polyvec_matrix_expand(polyvecl mat[K], const uint8_t rho[SEEDBYTES]);
|
||||||
|
|
||||||
|
#define polyvec_matrix_pointwise_montgomery DILITHIUM_NAMESPACE(polyvec_matrix_pointwise_montgomery)
|
||||||
|
void polyvec_matrix_pointwise_montgomery(polyveck *t, const polyvecl mat[K], const polyvecl *v);
|
||||||
|
|
||||||
|
#endif
|
||||||
12
src/crypto/pq/_d/ref/precomp.gp
Normal file
12
src/crypto/pq/_d/ref/precomp.gp
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
precomp() = {
|
||||||
|
brv = [128, 64, 192, 32, 160, 96, 224, 16, 144, 80, 208, 48, 176, 112, 240, 8, 136, 72, 200, 40, 168, 104, 232, 24, 152, 88, 216, 56, 184, 120, 248, 4, 132, 68, 196, 36, 164, 100, 228, 20, 148, 84, 212, 52, 180, 116, 244, 12, 140, 76, 204, 44, 172, 108, 236, 28, 156, 92, 220, 60, 188, 124, 252, 2, 130, 66, 194, 34, 162, 98, 226, 18, 146, 82, 210, 50, 178, 114, 242, 10, 138, 74, 202, 42, 170, 106, 234, 26, 154, 90, 218, 58, 186, 122, 250, 6, 134, 70, 198, 38, 166, 102, 230, 22, 150, 86, 214, 54, 182, 118, 246, 14, 142, 78, 206, 46, 174, 110, 238, 30, 158, 94, 222, 62, 190, 126, 254, 1, 129, 65, 193, 33, 161, 97, 225, 17, 145, 81, 209, 49, 177, 113, 241, 9, 137, 73, 201, 41, 169, 105, 233, 25, 153, 89, 217, 57, 185, 121, 249, 5, 133, 69, 197, 37, 165, 101, 229, 21, 149, 85, 213, 53, 181, 117, 245, 13, 141, 77, 205, 45, 173, 109, 237, 29, 157, 93, 221, 61, 189, 125, 253, 3, 131, 67, 195, 35, 163, 99, 227, 19, 147, 83, 211, 51, 179, 115, 243, 11, 139, 75, 203, 43, 171, 107, 235, 27, 155, 91, 219, 59, 187, 123, 251, 7, 135, 71, 199, 39, 167, 103, 231, 23, 151, 87, 215, 55, 183, 119, 247, 15, 143, 79, 207, 47, 175, 111, 239, 31, 159, 95, 223, 63, 191, 127, 255];
|
||||||
|
|
||||||
|
q = 2^23 - 2^13 + 1;
|
||||||
|
qinv = Mod(1/q,2^32);
|
||||||
|
mont = Mod(2^32,q);
|
||||||
|
|
||||||
|
z = 0;
|
||||||
|
for(i = 1, q-1, z = Mod(i,q); if(znorder(z) == 512, break));
|
||||||
|
zetas = vector(255, i, centerlift(mont * z^(brv[i])));
|
||||||
|
return(zetas);
|
||||||
|
}
|
||||||
80
src/crypto/pq/_d/ref/randombytes.c
Normal file
80
src/crypto/pq/_d/ref/randombytes.c
Normal file
|
|
@ -0,0 +1,80 @@
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "randombytes.h"
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <windows.h>
|
||||||
|
#include <wincrypt.h>
|
||||||
|
#else
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#ifdef __linux__
|
||||||
|
#define _GNU_SOURCE
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/syscall.h>
|
||||||
|
#else
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
void randombytes(uint8_t *out, size_t outlen) {
|
||||||
|
HCRYPTPROV ctx;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
if(!CryptAcquireContext(&ctx, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
|
||||||
|
abort();
|
||||||
|
|
||||||
|
while(outlen > 0) {
|
||||||
|
len = (outlen > 1048576) ? 1048576 : outlen;
|
||||||
|
if(!CryptGenRandom(ctx, len, (BYTE *)out))
|
||||||
|
abort();
|
||||||
|
|
||||||
|
out += len;
|
||||||
|
outlen -= len;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!CryptReleaseContext(ctx, 0))
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
#elif defined(__linux__) && defined(SYS_getrandom)
|
||||||
|
void randombytes(uint8_t *out, size_t outlen) {
|
||||||
|
ssize_t ret;
|
||||||
|
|
||||||
|
while(outlen > 0) {
|
||||||
|
ret = syscall(SYS_getrandom, out, outlen, 0);
|
||||||
|
if(ret == -1 && errno == EINTR)
|
||||||
|
continue;
|
||||||
|
else if(ret == -1)
|
||||||
|
abort();
|
||||||
|
|
||||||
|
out += ret;
|
||||||
|
outlen -= ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
void randombytes(uint8_t *out, size_t outlen) {
|
||||||
|
static int fd = -1;
|
||||||
|
ssize_t ret;
|
||||||
|
|
||||||
|
while(fd == -1) {
|
||||||
|
fd = open("/dev/urandom", O_RDONLY);
|
||||||
|
if(fd == -1 && errno == EINTR)
|
||||||
|
continue;
|
||||||
|
else if(fd == -1)
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
while(outlen > 0) {
|
||||||
|
ret = read(fd, out, outlen);
|
||||||
|
if(ret == -1 && errno == EINTR)
|
||||||
|
continue;
|
||||||
|
else if(ret == -1)
|
||||||
|
abort();
|
||||||
|
|
||||||
|
out += ret;
|
||||||
|
outlen -= ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
9
src/crypto/pq/_d/ref/randombytes.h
Normal file
9
src/crypto/pq/_d/ref/randombytes.h
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
#ifndef RANDOMBYTES_H
|
||||||
|
#define RANDOMBYTES_H
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
void randombytes(uint8_t *out, size_t outlen);
|
||||||
|
|
||||||
|
#endif
|
||||||
69
src/crypto/pq/_d/ref/reduce.c
Normal file
69
src/crypto/pq/_d/ref/reduce.c
Normal file
|
|
@ -0,0 +1,69 @@
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "params.h"
|
||||||
|
#include "reduce.h"
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: montgomery_reduce
|
||||||
|
*
|
||||||
|
* Description: For finite field element a with -2^{31}Q <= a <= Q*2^31,
|
||||||
|
* compute r \equiv a*2^{-32} (mod Q) such that -Q < r < Q.
|
||||||
|
*
|
||||||
|
* Arguments: - int64_t: finite field element a
|
||||||
|
*
|
||||||
|
* Returns r.
|
||||||
|
**************************************************/
|
||||||
|
int32_t montgomery_reduce(int64_t a) {
|
||||||
|
int32_t t;
|
||||||
|
|
||||||
|
t = (int64_t)(int32_t)a*QINV;
|
||||||
|
t = (a - (int64_t)t*Q) >> 32;
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: reduce32
|
||||||
|
*
|
||||||
|
* Description: For finite field element a with a <= 2^{31} - 2^{22} - 1,
|
||||||
|
* compute r \equiv a (mod Q) such that -6283008 <= r <= 6283008.
|
||||||
|
*
|
||||||
|
* Arguments: - int32_t: finite field element a
|
||||||
|
*
|
||||||
|
* Returns r.
|
||||||
|
**************************************************/
|
||||||
|
int32_t reduce32(int32_t a) {
|
||||||
|
int32_t t;
|
||||||
|
|
||||||
|
t = (a + (1 << 22)) >> 23;
|
||||||
|
t = a - t*Q;
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: caddq
|
||||||
|
*
|
||||||
|
* Description: Add Q if input coefficient is negative.
|
||||||
|
*
|
||||||
|
* Arguments: - int32_t: finite field element a
|
||||||
|
*
|
||||||
|
* Returns r.
|
||||||
|
**************************************************/
|
||||||
|
int32_t caddq(int32_t a) {
|
||||||
|
a += (a >> 31) & Q;
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: freeze
|
||||||
|
*
|
||||||
|
* Description: For finite field element a, compute standard
|
||||||
|
* representative r = a mod^+ Q.
|
||||||
|
*
|
||||||
|
* Arguments: - int32_t: finite field element a
|
||||||
|
*
|
||||||
|
* Returns r.
|
||||||
|
**************************************************/
|
||||||
|
int32_t freeze(int32_t a) {
|
||||||
|
a = reduce32(a);
|
||||||
|
a = caddq(a);
|
||||||
|
return a;
|
||||||
|
}
|
||||||
22
src/crypto/pq/_d/ref/reduce.h
Normal file
22
src/crypto/pq/_d/ref/reduce.h
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
#ifndef REDUCE_H
|
||||||
|
#define REDUCE_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "params.h"
|
||||||
|
|
||||||
|
#define MONT -4186625 // 2^32 % Q
|
||||||
|
#define QINV 58728449 // q^(-1) mod 2^32
|
||||||
|
|
||||||
|
#define montgomery_reduce DILITHIUM_NAMESPACE(montgomery_reduce)
|
||||||
|
int32_t montgomery_reduce(int64_t a);
|
||||||
|
|
||||||
|
#define reduce32 DILITHIUM_NAMESPACE(reduce32)
|
||||||
|
int32_t reduce32(int32_t a);
|
||||||
|
|
||||||
|
#define caddq DILITHIUM_NAMESPACE(caddq)
|
||||||
|
int32_t caddq(int32_t a);
|
||||||
|
|
||||||
|
#define freeze DILITHIUM_NAMESPACE(freeze)
|
||||||
|
int32_t freeze(int32_t a);
|
||||||
|
|
||||||
|
#endif
|
||||||
102
src/crypto/pq/_d/ref/rounding.c
Normal file
102
src/crypto/pq/_d/ref/rounding.c
Normal file
|
|
@ -0,0 +1,102 @@
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "params.h"
|
||||||
|
#include "rounding.h"
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: power2round
|
||||||
|
*
|
||||||
|
* Description: For finite field element a, compute a0, a1 such that
|
||||||
|
* a mod^+ Q = a1*2^D + a0 with -2^{D-1} < a0 <= 2^{D-1}.
|
||||||
|
* Assumes a to be standard representative.
|
||||||
|
*
|
||||||
|
* Arguments: - int32_t a: input element
|
||||||
|
* - int32_t *a0: pointer to output element a0
|
||||||
|
*
|
||||||
|
* Returns a1.
|
||||||
|
**************************************************/
|
||||||
|
int32_t power2round(int32_t *a0, int32_t a) {
|
||||||
|
int32_t a1;
|
||||||
|
|
||||||
|
a1 = (a + (1 << (D-1)) - 1) >> D;
|
||||||
|
*a0 = a - (a1 << D);
|
||||||
|
return a1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: decompose
|
||||||
|
*
|
||||||
|
* Description: For finite field element a, compute high and low bits a0, a1 such
|
||||||
|
* that a mod^+ Q = a1*ALPHA + a0 with -ALPHA/2 < a0 <= ALPHA/2 except
|
||||||
|
* if a1 = (Q-1)/ALPHA where we set a1 = 0 and
|
||||||
|
* -ALPHA/2 <= a0 = a mod^+ Q - Q < 0. Assumes a to be standard
|
||||||
|
* representative.
|
||||||
|
*
|
||||||
|
* Arguments: - int32_t a: input element
|
||||||
|
* - int32_t *a0: pointer to output element a0
|
||||||
|
*
|
||||||
|
* Returns a1.
|
||||||
|
**************************************************/
|
||||||
|
int32_t decompose(int32_t *a0, int32_t a) {
|
||||||
|
int32_t a1;
|
||||||
|
|
||||||
|
a1 = (a + 127) >> 7;
|
||||||
|
#if GAMMA2 == (Q-1)/32
|
||||||
|
a1 = (a1*1025 + (1 << 21)) >> 22;
|
||||||
|
a1 &= 15;
|
||||||
|
#elif GAMMA2 == (Q-1)/88
|
||||||
|
a1 = (a1*11275 + (1 << 23)) >> 24;
|
||||||
|
a1 ^= ((43 - a1) >> 31) & a1;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
*a0 = a - a1*2*GAMMA2;
|
||||||
|
*a0 -= (((Q-1)/2 - *a0) >> 31) & Q;
|
||||||
|
return a1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: make_hint
|
||||||
|
*
|
||||||
|
* Description: Compute hint bit indicating whether the low bits of the
|
||||||
|
* input element overflow into the high bits.
|
||||||
|
*
|
||||||
|
* Arguments: - int32_t a0: low bits of input element
|
||||||
|
* - int32_t a1: high bits of input element
|
||||||
|
*
|
||||||
|
* Returns 1 if overflow.
|
||||||
|
**************************************************/
|
||||||
|
unsigned int make_hint(int32_t a0, int32_t a1) {
|
||||||
|
if(a0 > GAMMA2 || a0 < -GAMMA2 || (a0 == -GAMMA2 && a1 != 0))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: use_hint
|
||||||
|
*
|
||||||
|
* Description: Correct high bits according to hint.
|
||||||
|
*
|
||||||
|
* Arguments: - int32_t a: input element
|
||||||
|
* - unsigned int hint: hint bit
|
||||||
|
*
|
||||||
|
* Returns corrected high bits.
|
||||||
|
**************************************************/
|
||||||
|
int32_t use_hint(int32_t a, unsigned int hint) {
|
||||||
|
int32_t a0, a1;
|
||||||
|
|
||||||
|
a1 = decompose(&a0, a);
|
||||||
|
if(hint == 0)
|
||||||
|
return a1;
|
||||||
|
|
||||||
|
#if GAMMA2 == (Q-1)/32
|
||||||
|
if(a0 > 0)
|
||||||
|
return (a1 + 1) & 15;
|
||||||
|
else
|
||||||
|
return (a1 - 1) & 15;
|
||||||
|
#elif GAMMA2 == (Q-1)/88
|
||||||
|
if(a0 > 0)
|
||||||
|
return (a1 == 43) ? 0 : a1 + 1;
|
||||||
|
else
|
||||||
|
return (a1 == 0) ? 43 : a1 - 1;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
19
src/crypto/pq/_d/ref/rounding.h
Normal file
19
src/crypto/pq/_d/ref/rounding.h
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
#ifndef ROUNDING_H
|
||||||
|
#define ROUNDING_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "params.h"
|
||||||
|
|
||||||
|
#define power2round DILITHIUM_NAMESPACE(power2round)
|
||||||
|
int32_t power2round(int32_t *a0, int32_t a);
|
||||||
|
|
||||||
|
#define decompose DILITHIUM_NAMESPACE(decompose)
|
||||||
|
int32_t decompose(int32_t *a0, int32_t a);
|
||||||
|
|
||||||
|
#define make_hint DILITHIUM_NAMESPACE(make_hint)
|
||||||
|
unsigned int make_hint(int32_t a0, int32_t a1);
|
||||||
|
|
||||||
|
#define use_hint DILITHIUM_NAMESPACE(use_hint)
|
||||||
|
int32_t use_hint(int32_t a, unsigned int hint);
|
||||||
|
|
||||||
|
#endif
|
||||||
443
src/crypto/pq/_d/ref/sign.c
Normal file
443
src/crypto/pq/_d/ref/sign.c
Normal file
|
|
@ -0,0 +1,443 @@
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "params.h"
|
||||||
|
#include "sign.h"
|
||||||
|
#include "packing.h"
|
||||||
|
#include "polyvec.h"
|
||||||
|
#include "poly.h"
|
||||||
|
#include "randombytes.h"
|
||||||
|
#include "symmetric.h"
|
||||||
|
#include "fips202.h"
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: crypto_sign_keypair
|
||||||
|
*
|
||||||
|
* Description: Generates public and private key.
|
||||||
|
*
|
||||||
|
* Arguments: - uint8_t *pk: pointer to output public key (allocated
|
||||||
|
* array of CRYPTO_PUBLICKEYBYTES bytes)
|
||||||
|
* - uint8_t *sk: pointer to output private key (allocated
|
||||||
|
* array of CRYPTO_SECRETKEYBYTES bytes)
|
||||||
|
*
|
||||||
|
* Returns 0 (success)
|
||||||
|
**************************************************/
|
||||||
|
int crypto_sign_keypair(uint8_t *pk, uint8_t *sk) {
|
||||||
|
uint8_t seedbuf[2*SEEDBYTES + CRHBYTES];
|
||||||
|
uint8_t tr[TRBYTES];
|
||||||
|
const uint8_t *rho, *rhoprime, *key;
|
||||||
|
polyvecl mat[K];
|
||||||
|
polyvecl s1, s1hat;
|
||||||
|
polyveck s2, t1, t0;
|
||||||
|
|
||||||
|
/* Get randomness for rho, rhoprime and key */
|
||||||
|
randombytes(seedbuf, SEEDBYTES);
|
||||||
|
seedbuf[SEEDBYTES+0] = K;
|
||||||
|
seedbuf[SEEDBYTES+1] = L;
|
||||||
|
shake256(seedbuf, 2*SEEDBYTES + CRHBYTES, seedbuf, SEEDBYTES+2);
|
||||||
|
rho = seedbuf;
|
||||||
|
rhoprime = rho + SEEDBYTES;
|
||||||
|
key = rhoprime + CRHBYTES;
|
||||||
|
|
||||||
|
/* Expand matrix */
|
||||||
|
polyvec_matrix_expand(mat, rho);
|
||||||
|
|
||||||
|
/* Sample short vectors s1 and s2 */
|
||||||
|
polyvecl_uniform_eta(&s1, rhoprime, 0);
|
||||||
|
polyveck_uniform_eta(&s2, rhoprime, L);
|
||||||
|
|
||||||
|
/* Matrix-vector multiplication */
|
||||||
|
s1hat = s1;
|
||||||
|
polyvecl_ntt(&s1hat);
|
||||||
|
polyvec_matrix_pointwise_montgomery(&t1, mat, &s1hat);
|
||||||
|
polyveck_reduce(&t1);
|
||||||
|
polyveck_invntt_tomont(&t1);
|
||||||
|
|
||||||
|
/* Add error vector s2 */
|
||||||
|
polyveck_add(&t1, &t1, &s2);
|
||||||
|
|
||||||
|
/* Extract t1 and write public key */
|
||||||
|
polyveck_caddq(&t1);
|
||||||
|
polyveck_power2round(&t1, &t0, &t1);
|
||||||
|
pack_pk(pk, rho, &t1);
|
||||||
|
|
||||||
|
/* Compute H(rho, t1) and write secret key */
|
||||||
|
shake256(tr, TRBYTES, pk, CRYPTO_PUBLICKEYBYTES);
|
||||||
|
pack_sk(sk, rho, tr, key, &t0, &s1, &s2);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: crypto_sign_signature_internal
|
||||||
|
*
|
||||||
|
* Description: Computes signature. Internal API.
|
||||||
|
*
|
||||||
|
* Arguments: - uint8_t *sig: pointer to output signature (of length CRYPTO_BYTES)
|
||||||
|
* - size_t *siglen: pointer to output length of signature
|
||||||
|
* - uint8_t *m: pointer to message to be signed
|
||||||
|
* - size_t mlen: length of message
|
||||||
|
* - uint8_t *pre: pointer to prefix string
|
||||||
|
* - size_t prelen: length of prefix string
|
||||||
|
* - uint8_t *rnd: pointer to random seed
|
||||||
|
* - uint8_t *sk: pointer to bit-packed secret key
|
||||||
|
*
|
||||||
|
* Returns 0 (success)
|
||||||
|
**************************************************/
|
||||||
|
int crypto_sign_signature_internal(uint8_t *sig,
|
||||||
|
size_t *siglen,
|
||||||
|
const uint8_t *m,
|
||||||
|
size_t mlen,
|
||||||
|
const uint8_t *pre,
|
||||||
|
size_t prelen,
|
||||||
|
const uint8_t rnd[RNDBYTES],
|
||||||
|
const uint8_t *sk)
|
||||||
|
{
|
||||||
|
unsigned int n;
|
||||||
|
uint8_t seedbuf[2*SEEDBYTES + TRBYTES + 2*CRHBYTES];
|
||||||
|
uint8_t *rho, *tr, *key, *mu, *rhoprime;
|
||||||
|
uint16_t nonce = 0;
|
||||||
|
polyvecl mat[K], s1, y, z;
|
||||||
|
polyveck t0, s2, w1, w0, h;
|
||||||
|
poly cp;
|
||||||
|
keccak_state state;
|
||||||
|
|
||||||
|
rho = seedbuf;
|
||||||
|
tr = rho + SEEDBYTES;
|
||||||
|
key = tr + TRBYTES;
|
||||||
|
mu = key + SEEDBYTES;
|
||||||
|
rhoprime = mu + CRHBYTES;
|
||||||
|
unpack_sk(rho, tr, key, &t0, &s1, &s2, sk);
|
||||||
|
|
||||||
|
/* Compute mu = CRH(tr, pre, msg) */
|
||||||
|
shake256_init(&state);
|
||||||
|
shake256_absorb(&state, tr, TRBYTES);
|
||||||
|
shake256_absorb(&state, pre, prelen);
|
||||||
|
shake256_absorb(&state, m, mlen);
|
||||||
|
shake256_finalize(&state);
|
||||||
|
shake256_squeeze(mu, CRHBYTES, &state);
|
||||||
|
|
||||||
|
/* Compute rhoprime = CRH(key, rnd, mu) */
|
||||||
|
shake256_init(&state);
|
||||||
|
shake256_absorb(&state, key, SEEDBYTES);
|
||||||
|
shake256_absorb(&state, rnd, RNDBYTES);
|
||||||
|
shake256_absorb(&state, mu, CRHBYTES);
|
||||||
|
shake256_finalize(&state);
|
||||||
|
shake256_squeeze(rhoprime, CRHBYTES, &state);
|
||||||
|
|
||||||
|
/* Expand matrix and transform vectors */
|
||||||
|
polyvec_matrix_expand(mat, rho);
|
||||||
|
polyvecl_ntt(&s1);
|
||||||
|
polyveck_ntt(&s2);
|
||||||
|
polyveck_ntt(&t0);
|
||||||
|
|
||||||
|
rej:
|
||||||
|
/* Sample intermediate vector y */
|
||||||
|
polyvecl_uniform_gamma1(&y, rhoprime, nonce++);
|
||||||
|
|
||||||
|
/* Matrix-vector multiplication */
|
||||||
|
z = y;
|
||||||
|
polyvecl_ntt(&z);
|
||||||
|
polyvec_matrix_pointwise_montgomery(&w1, mat, &z);
|
||||||
|
polyveck_reduce(&w1);
|
||||||
|
polyveck_invntt_tomont(&w1);
|
||||||
|
|
||||||
|
/* Decompose w and call the random oracle */
|
||||||
|
polyveck_caddq(&w1);
|
||||||
|
polyveck_decompose(&w1, &w0, &w1);
|
||||||
|
polyveck_pack_w1(sig, &w1);
|
||||||
|
|
||||||
|
shake256_init(&state);
|
||||||
|
shake256_absorb(&state, mu, CRHBYTES);
|
||||||
|
shake256_absorb(&state, sig, K*POLYW1_PACKEDBYTES);
|
||||||
|
shake256_finalize(&state);
|
||||||
|
shake256_squeeze(sig, CTILDEBYTES, &state);
|
||||||
|
poly_challenge(&cp, sig);
|
||||||
|
poly_ntt(&cp);
|
||||||
|
|
||||||
|
/* Compute z, reject if it reveals secret */
|
||||||
|
polyvecl_pointwise_poly_montgomery(&z, &cp, &s1);
|
||||||
|
polyvecl_invntt_tomont(&z);
|
||||||
|
polyvecl_add(&z, &z, &y);
|
||||||
|
polyvecl_reduce(&z);
|
||||||
|
if(polyvecl_chknorm(&z, GAMMA1 - BETA))
|
||||||
|
goto rej;
|
||||||
|
|
||||||
|
/* Check that subtracting cs2 does not change high bits of w and low bits
|
||||||
|
* do not reveal secret information */
|
||||||
|
polyveck_pointwise_poly_montgomery(&h, &cp, &s2);
|
||||||
|
polyveck_invntt_tomont(&h);
|
||||||
|
polyveck_sub(&w0, &w0, &h);
|
||||||
|
polyveck_reduce(&w0);
|
||||||
|
if(polyveck_chknorm(&w0, GAMMA2 - BETA))
|
||||||
|
goto rej;
|
||||||
|
|
||||||
|
/* Compute hints for w1 */
|
||||||
|
polyveck_pointwise_poly_montgomery(&h, &cp, &t0);
|
||||||
|
polyveck_invntt_tomont(&h);
|
||||||
|
polyveck_reduce(&h);
|
||||||
|
if(polyveck_chknorm(&h, GAMMA2))
|
||||||
|
goto rej;
|
||||||
|
|
||||||
|
polyveck_add(&w0, &w0, &h);
|
||||||
|
n = polyveck_make_hint(&h, &w0, &w1);
|
||||||
|
if(n > OMEGA)
|
||||||
|
goto rej;
|
||||||
|
|
||||||
|
/* Write signature */
|
||||||
|
pack_sig(sig, sig, &z, &h);
|
||||||
|
*siglen = CRYPTO_BYTES;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: crypto_sign_signature
|
||||||
|
*
|
||||||
|
* Description: Computes signature.
|
||||||
|
*
|
||||||
|
* Arguments: - uint8_t *sig: pointer to output signature (of length CRYPTO_BYTES)
|
||||||
|
* - size_t *siglen: pointer to output length of signature
|
||||||
|
* - uint8_t *m: pointer to message to be signed
|
||||||
|
* - size_t mlen: length of message
|
||||||
|
* - uint8_t *ctx: pointer to contex string
|
||||||
|
* - size_t ctxlen: length of contex string
|
||||||
|
* - uint8_t *sk: pointer to bit-packed secret key
|
||||||
|
*
|
||||||
|
* Returns 0 (success) or -1 (context string too long)
|
||||||
|
**************************************************/
|
||||||
|
int crypto_sign_signature(uint8_t *sig,
|
||||||
|
size_t *siglen,
|
||||||
|
const uint8_t *m,
|
||||||
|
size_t mlen,
|
||||||
|
const uint8_t *ctx,
|
||||||
|
size_t ctxlen,
|
||||||
|
const uint8_t *sk)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
uint8_t pre[257];
|
||||||
|
uint8_t rnd[RNDBYTES];
|
||||||
|
|
||||||
|
if(ctxlen > 255)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* Prepare pre = (0, ctxlen, ctx) */
|
||||||
|
pre[0] = 0;
|
||||||
|
pre[1] = ctxlen;
|
||||||
|
for(i = 0; i < ctxlen; i++)
|
||||||
|
pre[2 + i] = ctx[i];
|
||||||
|
|
||||||
|
#ifdef DILITHIUM_RANDOMIZED_SIGNING
|
||||||
|
randombytes(rnd, RNDBYTES);
|
||||||
|
#else
|
||||||
|
for(i=0;i<RNDBYTES;i++)
|
||||||
|
rnd[i] = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
crypto_sign_signature_internal(sig,siglen,m,mlen,pre,2+ctxlen,rnd,sk);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: crypto_sign
|
||||||
|
*
|
||||||
|
* Description: Compute signed message.
|
||||||
|
*
|
||||||
|
* Arguments: - uint8_t *sm: pointer to output signed message (allocated
|
||||||
|
* array with CRYPTO_BYTES + mlen bytes),
|
||||||
|
* can be equal to m
|
||||||
|
* - size_t *smlen: pointer to output length of signed
|
||||||
|
* message
|
||||||
|
* - const uint8_t *m: pointer to message to be signed
|
||||||
|
* - size_t mlen: length of message
|
||||||
|
* - const uint8_t *ctx: pointer to context string
|
||||||
|
* - size_t ctxlen: length of context string
|
||||||
|
* - const uint8_t *sk: pointer to bit-packed secret key
|
||||||
|
*
|
||||||
|
* Returns 0 (success) or -1 (context string too long)
|
||||||
|
**************************************************/
|
||||||
|
int crypto_sign(uint8_t *sm,
|
||||||
|
size_t *smlen,
|
||||||
|
const uint8_t *m,
|
||||||
|
size_t mlen,
|
||||||
|
const uint8_t *ctx,
|
||||||
|
size_t ctxlen,
|
||||||
|
const uint8_t *sk)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for(i = 0; i < mlen; ++i)
|
||||||
|
sm[CRYPTO_BYTES + mlen - 1 - i] = m[mlen - 1 - i];
|
||||||
|
ret = crypto_sign_signature(sm, smlen, sm + CRYPTO_BYTES, mlen, ctx, ctxlen, sk);
|
||||||
|
*smlen += mlen;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: crypto_sign_verify_internal
|
||||||
|
*
|
||||||
|
* Description: Verifies signature. Internal API.
|
||||||
|
*
|
||||||
|
* Arguments: - uint8_t *m: pointer to input signature
|
||||||
|
* - size_t siglen: length of signature
|
||||||
|
* - const uint8_t *m: pointer to message
|
||||||
|
* - size_t mlen: length of message
|
||||||
|
* - const uint8_t *pre: pointer to prefix string
|
||||||
|
* - size_t prelen: length of prefix string
|
||||||
|
* - const uint8_t *pk: pointer to bit-packed public key
|
||||||
|
*
|
||||||
|
* Returns 0 if signature could be verified correctly and -1 otherwise
|
||||||
|
**************************************************/
|
||||||
|
int crypto_sign_verify_internal(const uint8_t *sig,
|
||||||
|
size_t siglen,
|
||||||
|
const uint8_t *m,
|
||||||
|
size_t mlen,
|
||||||
|
const uint8_t *pre,
|
||||||
|
size_t prelen,
|
||||||
|
const uint8_t *pk)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
uint8_t buf[K*POLYW1_PACKEDBYTES];
|
||||||
|
uint8_t rho[SEEDBYTES];
|
||||||
|
uint8_t mu[CRHBYTES];
|
||||||
|
uint8_t c[CTILDEBYTES];
|
||||||
|
uint8_t c2[CTILDEBYTES];
|
||||||
|
poly cp;
|
||||||
|
polyvecl mat[K], z;
|
||||||
|
polyveck t1, w1, h;
|
||||||
|
keccak_state state;
|
||||||
|
|
||||||
|
if(siglen != CRYPTO_BYTES)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
unpack_pk(rho, &t1, pk);
|
||||||
|
if(unpack_sig(c, &z, &h, sig))
|
||||||
|
return -1;
|
||||||
|
if(polyvecl_chknorm(&z, GAMMA1 - BETA))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* Compute CRH(H(rho, t1), pre, msg) */
|
||||||
|
shake256(mu, TRBYTES, pk, CRYPTO_PUBLICKEYBYTES);
|
||||||
|
shake256_init(&state);
|
||||||
|
shake256_absorb(&state, mu, TRBYTES);
|
||||||
|
shake256_absorb(&state, pre, prelen);
|
||||||
|
shake256_absorb(&state, m, mlen);
|
||||||
|
shake256_finalize(&state);
|
||||||
|
shake256_squeeze(mu, CRHBYTES, &state);
|
||||||
|
|
||||||
|
/* Matrix-vector multiplication; compute Az - c2^dt1 */
|
||||||
|
poly_challenge(&cp, c);
|
||||||
|
polyvec_matrix_expand(mat, rho);
|
||||||
|
|
||||||
|
polyvecl_ntt(&z);
|
||||||
|
polyvec_matrix_pointwise_montgomery(&w1, mat, &z);
|
||||||
|
|
||||||
|
poly_ntt(&cp);
|
||||||
|
polyveck_shiftl(&t1);
|
||||||
|
polyveck_ntt(&t1);
|
||||||
|
polyveck_pointwise_poly_montgomery(&t1, &cp, &t1);
|
||||||
|
|
||||||
|
polyveck_sub(&w1, &w1, &t1);
|
||||||
|
polyveck_reduce(&w1);
|
||||||
|
polyveck_invntt_tomont(&w1);
|
||||||
|
|
||||||
|
/* Reconstruct w1 */
|
||||||
|
polyveck_caddq(&w1);
|
||||||
|
polyveck_use_hint(&w1, &w1, &h);
|
||||||
|
polyveck_pack_w1(buf, &w1);
|
||||||
|
|
||||||
|
/* Call random oracle and verify challenge */
|
||||||
|
shake256_init(&state);
|
||||||
|
shake256_absorb(&state, mu, CRHBYTES);
|
||||||
|
shake256_absorb(&state, buf, K*POLYW1_PACKEDBYTES);
|
||||||
|
shake256_finalize(&state);
|
||||||
|
shake256_squeeze(c2, CTILDEBYTES, &state);
|
||||||
|
for(i = 0; i < CTILDEBYTES; ++i)
|
||||||
|
if(c[i] != c2[i])
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: crypto_sign_verify
|
||||||
|
*
|
||||||
|
* Description: Verifies signature.
|
||||||
|
*
|
||||||
|
* Arguments: - uint8_t *m: pointer to input signature
|
||||||
|
* - size_t siglen: length of signature
|
||||||
|
* - const uint8_t *m: pointer to message
|
||||||
|
* - size_t mlen: length of message
|
||||||
|
* - const uint8_t *ctx: pointer to context string
|
||||||
|
* - size_t ctxlen: length of context string
|
||||||
|
* - const uint8_t *pk: pointer to bit-packed public key
|
||||||
|
*
|
||||||
|
* Returns 0 if signature could be verified correctly and -1 otherwise
|
||||||
|
**************************************************/
|
||||||
|
int crypto_sign_verify(const uint8_t *sig,
|
||||||
|
size_t siglen,
|
||||||
|
const uint8_t *m,
|
||||||
|
size_t mlen,
|
||||||
|
const uint8_t *ctx,
|
||||||
|
size_t ctxlen,
|
||||||
|
const uint8_t *pk)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
uint8_t pre[257];
|
||||||
|
|
||||||
|
if(ctxlen > 255)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
pre[0] = 0;
|
||||||
|
pre[1] = ctxlen;
|
||||||
|
for(i = 0; i < ctxlen; i++)
|
||||||
|
pre[2 + i] = ctx[i];
|
||||||
|
|
||||||
|
return crypto_sign_verify_internal(sig,siglen,m,mlen,pre,2+ctxlen,pk);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Name: crypto_sign_open
|
||||||
|
*
|
||||||
|
* Description: Verify signed message.
|
||||||
|
*
|
||||||
|
* Arguments: - uint8_t *m: pointer to output message (allocated
|
||||||
|
* array with smlen bytes), can be equal to sm
|
||||||
|
* - size_t *mlen: pointer to output length of message
|
||||||
|
* - const uint8_t *sm: pointer to signed message
|
||||||
|
* - size_t smlen: length of signed message
|
||||||
|
* - const uint8_t *ctx: pointer to context tring
|
||||||
|
* - size_t ctxlen: length of context string
|
||||||
|
* - const uint8_t *pk: pointer to bit-packed public key
|
||||||
|
*
|
||||||
|
* Returns 0 if signed message could be verified correctly and -1 otherwise
|
||||||
|
**************************************************/
|
||||||
|
int crypto_sign_open(uint8_t *m,
|
||||||
|
size_t *mlen,
|
||||||
|
const uint8_t *sm,
|
||||||
|
size_t smlen,
|
||||||
|
const uint8_t *ctx,
|
||||||
|
size_t ctxlen,
|
||||||
|
const uint8_t *pk)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
if(smlen < CRYPTO_BYTES)
|
||||||
|
goto badsig;
|
||||||
|
|
||||||
|
*mlen = smlen - CRYPTO_BYTES;
|
||||||
|
if(crypto_sign_verify(sm, CRYPTO_BYTES, sm + CRYPTO_BYTES, *mlen, ctx, ctxlen, pk))
|
||||||
|
goto badsig;
|
||||||
|
else {
|
||||||
|
/* All good, copy msg, return 0 */
|
||||||
|
for(i = 0; i < *mlen; ++i)
|
||||||
|
m[i] = sm[CRYPTO_BYTES + i];
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
badsig:
|
||||||
|
/* Signature verification failed */
|
||||||
|
*mlen = 0;
|
||||||
|
for(i = 0; i < smlen; ++i)
|
||||||
|
m[i] = 0;
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
56
src/crypto/pq/_d/ref/sign.h
Normal file
56
src/crypto/pq/_d/ref/sign.h
Normal file
|
|
@ -0,0 +1,56 @@
|
||||||
|
#ifndef SIGN_H
|
||||||
|
#define SIGN_H
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "params.h"
|
||||||
|
#include "polyvec.h"
|
||||||
|
#include "poly.h"
|
||||||
|
|
||||||
|
#define crypto_sign_keypair DILITHIUM_NAMESPACE(keypair)
|
||||||
|
int crypto_sign_keypair(uint8_t *pk, uint8_t *sk);
|
||||||
|
|
||||||
|
#define crypto_sign_signature_internal DILITHIUM_NAMESPACE(signature_internal)
|
||||||
|
int crypto_sign_signature_internal(uint8_t *sig,
|
||||||
|
size_t *siglen,
|
||||||
|
const uint8_t *m,
|
||||||
|
size_t mlen,
|
||||||
|
const uint8_t *pre,
|
||||||
|
size_t prelen,
|
||||||
|
const uint8_t rnd[RNDBYTES],
|
||||||
|
const uint8_t *sk);
|
||||||
|
|
||||||
|
#define crypto_sign_signature DILITHIUM_NAMESPACE(signature)
|
||||||
|
int crypto_sign_signature(uint8_t *sig, size_t *siglen,
|
||||||
|
const uint8_t *m, size_t mlen,
|
||||||
|
const uint8_t *ctx, size_t ctxlen,
|
||||||
|
const uint8_t *sk);
|
||||||
|
|
||||||
|
#define crypto_sign DILITHIUM_NAMESPACETOP
|
||||||
|
int crypto_sign(uint8_t *sm, size_t *smlen,
|
||||||
|
const uint8_t *m, size_t mlen,
|
||||||
|
const uint8_t *ctx, size_t ctxlen,
|
||||||
|
const uint8_t *sk);
|
||||||
|
|
||||||
|
#define crypto_sign_verify_internal DILITHIUM_NAMESPACE(verify_internal)
|
||||||
|
int crypto_sign_verify_internal(const uint8_t *sig,
|
||||||
|
size_t siglen,
|
||||||
|
const uint8_t *m,
|
||||||
|
size_t mlen,
|
||||||
|
const uint8_t *pre,
|
||||||
|
size_t prelen,
|
||||||
|
const uint8_t *pk);
|
||||||
|
|
||||||
|
#define crypto_sign_verify DILITHIUM_NAMESPACE(verify)
|
||||||
|
int crypto_sign_verify(const uint8_t *sig, size_t siglen,
|
||||||
|
const uint8_t *m, size_t mlen,
|
||||||
|
const uint8_t *ctx, size_t ctxlen,
|
||||||
|
const uint8_t *pk);
|
||||||
|
|
||||||
|
#define crypto_sign_open DILITHIUM_NAMESPACE(open)
|
||||||
|
int crypto_sign_open(uint8_t *m, size_t *mlen,
|
||||||
|
const uint8_t *sm, size_t smlen,
|
||||||
|
const uint8_t *ctx, size_t ctxlen,
|
||||||
|
const uint8_t *pk);
|
||||||
|
|
||||||
|
#endif
|
||||||
28
src/crypto/pq/_d/ref/symmetric-shake.c
Normal file
28
src/crypto/pq/_d/ref/symmetric-shake.c
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "params.h"
|
||||||
|
#include "symmetric.h"
|
||||||
|
#include "fips202.h"
|
||||||
|
|
||||||
|
void dilithium_shake128_stream_init(keccak_state *state, const uint8_t seed[SEEDBYTES], uint16_t nonce)
|
||||||
|
{
|
||||||
|
uint8_t t[2];
|
||||||
|
t[0] = nonce;
|
||||||
|
t[1] = nonce >> 8;
|
||||||
|
|
||||||
|
shake128_init(state);
|
||||||
|
shake128_absorb(state, seed, SEEDBYTES);
|
||||||
|
shake128_absorb(state, t, 2);
|
||||||
|
shake128_finalize(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
void dilithium_shake256_stream_init(keccak_state *state, const uint8_t seed[CRHBYTES], uint16_t nonce)
|
||||||
|
{
|
||||||
|
uint8_t t[2];
|
||||||
|
t[0] = nonce;
|
||||||
|
t[1] = nonce >> 8;
|
||||||
|
|
||||||
|
shake256_init(state);
|
||||||
|
shake256_absorb(state, seed, CRHBYTES);
|
||||||
|
shake256_absorb(state, t, 2);
|
||||||
|
shake256_finalize(state);
|
||||||
|
}
|
||||||
34
src/crypto/pq/_d/ref/symmetric.h
Normal file
34
src/crypto/pq/_d/ref/symmetric.h
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
#ifndef SYMMETRIC_H
|
||||||
|
#define SYMMETRIC_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "params.h"
|
||||||
|
|
||||||
|
#include "fips202.h"
|
||||||
|
|
||||||
|
typedef keccak_state stream128_state;
|
||||||
|
typedef keccak_state stream256_state;
|
||||||
|
|
||||||
|
#define dilithium_shake128_stream_init DILITHIUM_NAMESPACE(dilithium_shake128_stream_init)
|
||||||
|
void dilithium_shake128_stream_init(keccak_state *state,
|
||||||
|
const uint8_t seed[SEEDBYTES],
|
||||||
|
uint16_t nonce);
|
||||||
|
|
||||||
|
#define dilithium_shake256_stream_init DILITHIUM_NAMESPACE(dilithium_shake256_stream_init)
|
||||||
|
void dilithium_shake256_stream_init(keccak_state *state,
|
||||||
|
const uint8_t seed[CRHBYTES],
|
||||||
|
uint16_t nonce);
|
||||||
|
|
||||||
|
#define STREAM128_BLOCKBYTES SHAKE128_RATE
|
||||||
|
#define STREAM256_BLOCKBYTES SHAKE256_RATE
|
||||||
|
|
||||||
|
#define stream128_init(STATE, SEED, NONCE) \
|
||||||
|
dilithium_shake128_stream_init(STATE, SEED, NONCE)
|
||||||
|
#define stream128_squeezeblocks(OUT, OUTBLOCKS, STATE) \
|
||||||
|
shake128_squeezeblocks(OUT, OUTBLOCKS, STATE)
|
||||||
|
#define stream256_init(STATE, SEED, NONCE) \
|
||||||
|
dilithium_shake256_stream_init(STATE, SEED, NONCE)
|
||||||
|
#define stream256_squeezeblocks(OUT, OUTBLOCKS, STATE) \
|
||||||
|
shake256_squeezeblocks(OUT, OUTBLOCKS, STATE)
|
||||||
|
|
||||||
|
#endif
|
||||||
10
src/crypto/pq/_d/ref/test/.gitignore
vendored
Normal file
10
src/crypto/pq/_d/ref/test/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
test_dilithium2
|
||||||
|
test_dilithium3
|
||||||
|
test_dilithium5
|
||||||
|
test_vectors2
|
||||||
|
test_vectors3
|
||||||
|
test_vectors5
|
||||||
|
test_speed2
|
||||||
|
test_speed3
|
||||||
|
test_speed5
|
||||||
|
test_mul
|
||||||
17
src/crypto/pq/_d/ref/test/cpucycles.c
Normal file
17
src/crypto/pq/_d/ref/test/cpucycles.c
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "cpucycles.h"
|
||||||
|
|
||||||
|
uint64_t cpucycles_overhead(void) {
|
||||||
|
uint64_t t0, t1, overhead = -1LL;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for(i=0;i<100000;i++) {
|
||||||
|
t0 = cpucycles();
|
||||||
|
__asm__ volatile("");
|
||||||
|
t1 = cpucycles();
|
||||||
|
if(t1 - t0 < overhead)
|
||||||
|
overhead = t1 - t0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return overhead;
|
||||||
|
}
|
||||||
33
src/crypto/pq/_d/ref/test/cpucycles.h
Normal file
33
src/crypto/pq/_d/ref/test/cpucycles.h
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
#ifndef CPUCYCLES_H
|
||||||
|
#define CPUCYCLES_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#ifdef USE_RDPMC /* Needs echo 2 > /sys/devices/cpu/rdpmc */
|
||||||
|
|
||||||
|
static inline uint64_t cpucycles(void) {
|
||||||
|
const uint32_t ecx = (1U << 30) + 1;
|
||||||
|
uint64_t result;
|
||||||
|
|
||||||
|
__asm__ volatile ("rdpmc; shlq $32,%%rdx; orq %%rdx,%%rax"
|
||||||
|
: "=a" (result) : "c" (ecx) : "rdx");
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
static inline uint64_t cpucycles(void) {
|
||||||
|
uint64_t result;
|
||||||
|
|
||||||
|
__asm__ volatile ("rdtsc; shlq $32,%%rdx; orq %%rdx,%%rax"
|
||||||
|
: "=a" (result) : : "%rdx");
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uint64_t cpucycles_overhead(void);
|
||||||
|
|
||||||
|
#endif
|
||||||
51
src/crypto/pq/_d/ref/test/speed_print.c
Normal file
51
src/crypto/pq/_d/ref/test/speed_print.c
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "cpucycles.h"
|
||||||
|
#include "speed_print.h"
|
||||||
|
|
||||||
|
static int cmp_uint64(const void *a, const void *b) {
|
||||||
|
if(*(uint64_t *)a < *(uint64_t *)b) return -1;
|
||||||
|
if(*(uint64_t *)a > *(uint64_t *)b) return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint64_t median(uint64_t *l, size_t llen) {
|
||||||
|
qsort(l,llen,sizeof(uint64_t),cmp_uint64);
|
||||||
|
|
||||||
|
if(llen%2) return l[llen/2];
|
||||||
|
else return (l[llen/2-1]+l[llen/2])/2;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint64_t average(uint64_t *t, size_t tlen) {
|
||||||
|
size_t i;
|
||||||
|
uint64_t acc=0;
|
||||||
|
|
||||||
|
for(i=0;i<tlen;i++)
|
||||||
|
acc += t[i];
|
||||||
|
|
||||||
|
return acc/tlen;
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_results(const char *s, uint64_t *t, size_t tlen) {
|
||||||
|
size_t i;
|
||||||
|
static uint64_t overhead = -1;
|
||||||
|
|
||||||
|
if(tlen < 2) {
|
||||||
|
fprintf(stderr, "ERROR: Need a least two cycle counts!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(overhead == (uint64_t)-1)
|
||||||
|
overhead = cpucycles_overhead();
|
||||||
|
|
||||||
|
tlen--;
|
||||||
|
for(i=0;i<tlen;++i)
|
||||||
|
t[i] = t[i+1] - t[i] - overhead;
|
||||||
|
|
||||||
|
printf("%s\n", s);
|
||||||
|
printf("median: %llu cycles/ticks\n", (unsigned long long)median(t, tlen));
|
||||||
|
printf("average: %llu cycles/ticks\n", (unsigned long long)average(t, tlen));
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
9
src/crypto/pq/_d/ref/test/speed_print.h
Normal file
9
src/crypto/pq/_d/ref/test/speed_print.h
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
#ifndef PRINT_SPEED_H
|
||||||
|
#define PRINT_SPEED_H
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
void print_results(const char *s, uint64_t *t, size_t tlen);
|
||||||
|
|
||||||
|
#endif
|
||||||
69
src/crypto/pq/_d/ref/test/test_dilithium.c
Normal file
69
src/crypto/pq/_d/ref/test/test_dilithium.c
Normal file
|
|
@ -0,0 +1,69 @@
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "../randombytes.h"
|
||||||
|
#include "../sign.h"
|
||||||
|
|
||||||
|
#define MLEN 59
|
||||||
|
#define CTXLEN 14
|
||||||
|
#define NTESTS 10000
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
size_t i, j;
|
||||||
|
int ret;
|
||||||
|
size_t mlen, smlen;
|
||||||
|
uint8_t b;
|
||||||
|
uint8_t ctx[CTXLEN] = {0};
|
||||||
|
uint8_t m[MLEN + CRYPTO_BYTES];
|
||||||
|
uint8_t m2[MLEN + CRYPTO_BYTES];
|
||||||
|
uint8_t sm[MLEN + CRYPTO_BYTES];
|
||||||
|
uint8_t pk[CRYPTO_PUBLICKEYBYTES];
|
||||||
|
uint8_t sk[CRYPTO_SECRETKEYBYTES];
|
||||||
|
|
||||||
|
snprintf((char*)ctx,CTXLEN,"test_dilitium");
|
||||||
|
|
||||||
|
for(i = 0; i < NTESTS; ++i) {
|
||||||
|
randombytes(m, MLEN);
|
||||||
|
|
||||||
|
crypto_sign_keypair(pk, sk);
|
||||||
|
crypto_sign(sm, &smlen, m, MLEN, ctx, CTXLEN, sk);
|
||||||
|
ret = crypto_sign_open(m2, &mlen, sm, smlen, ctx, CTXLEN, pk);
|
||||||
|
|
||||||
|
if(ret) {
|
||||||
|
fprintf(stderr, "Verification failed\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if(smlen != MLEN + CRYPTO_BYTES) {
|
||||||
|
fprintf(stderr, "Signed message lengths wrong\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if(mlen != MLEN) {
|
||||||
|
fprintf(stderr, "Message lengths wrong\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
for(j = 0; j < MLEN; ++j) {
|
||||||
|
if(m2[j] != m[j]) {
|
||||||
|
fprintf(stderr, "Messages don't match\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
randombytes((uint8_t *)&j, sizeof(j));
|
||||||
|
do {
|
||||||
|
randombytes(&b, 1);
|
||||||
|
} while(!b);
|
||||||
|
sm[j % (MLEN + CRYPTO_BYTES)] += b;
|
||||||
|
ret = crypto_sign_open(m2, &mlen, sm, smlen, ctx, CTXLEN, pk);
|
||||||
|
if(!ret) {
|
||||||
|
fprintf(stderr, "Trivial forgeries possible\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("CRYPTO_PUBLICKEYBYTES = %d\n", CRYPTO_PUBLICKEYBYTES);
|
||||||
|
printf("CRYPTO_SECRETKEYBYTES = %d\n", CRYPTO_SECRETKEYBYTES);
|
||||||
|
printf("CRYPTO_BYTES = %d\n", CRYPTO_BYTES);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
60
src/crypto/pq/_d/ref/test/test_mul.c
Normal file
60
src/crypto/pq/_d/ref/test/test_mul.c
Normal file
|
|
@ -0,0 +1,60 @@
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "../params.h"
|
||||||
|
#include "../randombytes.h"
|
||||||
|
#include "../poly.h"
|
||||||
|
|
||||||
|
#define NTESTS 100000
|
||||||
|
|
||||||
|
static void poly_naivemul(poly *c, const poly *a, const poly *b) {
|
||||||
|
unsigned int i,j;
|
||||||
|
int32_t r[2*N] = {0};
|
||||||
|
|
||||||
|
for(i = 0; i < N; i++)
|
||||||
|
for(j = 0; j < N; j++)
|
||||||
|
r[i+j] = (r[i+j] + (int64_t)a->coeffs[i]*b->coeffs[j]) % Q;
|
||||||
|
|
||||||
|
for(i = N; i < 2*N; i++)
|
||||||
|
r[i-N] = (r[i-N] - r[i]) % Q;
|
||||||
|
|
||||||
|
for(i = 0; i < N; i++)
|
||||||
|
c->coeffs[i] = r[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
unsigned int i, j;
|
||||||
|
uint8_t seed[SEEDBYTES];
|
||||||
|
uint16_t nonce = 0;
|
||||||
|
poly a, b, c, d;
|
||||||
|
|
||||||
|
randombytes(seed, sizeof(seed));
|
||||||
|
for(i = 0; i < NTESTS; ++i) {
|
||||||
|
poly_uniform(&a, seed, nonce++);
|
||||||
|
poly_uniform(&b, seed, nonce++);
|
||||||
|
|
||||||
|
c = a;
|
||||||
|
poly_ntt(&c);
|
||||||
|
for(j = 0; j < N; ++j)
|
||||||
|
c.coeffs[j] = (int64_t)c.coeffs[j]*-114592 % Q;
|
||||||
|
poly_invntt_tomont(&c);
|
||||||
|
for(j = 0; j < N; ++j) {
|
||||||
|
if((c.coeffs[j] - a.coeffs[j]) % Q)
|
||||||
|
fprintf(stderr, "ERROR in ntt/invntt: c[%d] = %d != %d\n",
|
||||||
|
j, c.coeffs[j]%Q, a.coeffs[j]);
|
||||||
|
}
|
||||||
|
|
||||||
|
poly_naivemul(&c, &a, &b);
|
||||||
|
poly_ntt(&a);
|
||||||
|
poly_ntt(&b);
|
||||||
|
poly_pointwise_montgomery(&d, &a, &b);
|
||||||
|
poly_invntt_tomont(&d);
|
||||||
|
|
||||||
|
for(j = 0; j < N; ++j) {
|
||||||
|
if((d.coeffs[j] - c.coeffs[j]) % Q)
|
||||||
|
fprintf(stderr, "ERROR in multiplication: d[%d] = %d != %d\n",
|
||||||
|
j, d.coeffs[j], c.coeffs[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
87
src/crypto/pq/_d/ref/test/test_speed.c
Normal file
87
src/crypto/pq/_d/ref/test/test_speed.c
Normal file
|
|
@ -0,0 +1,87 @@
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "../sign.h"
|
||||||
|
#include "../poly.h"
|
||||||
|
#include "../polyvec.h"
|
||||||
|
#include "../params.h"
|
||||||
|
#include "cpucycles.h"
|
||||||
|
#include "speed_print.h"
|
||||||
|
|
||||||
|
#define NTESTS 1000
|
||||||
|
|
||||||
|
uint64_t t[NTESTS];
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
size_t siglen;
|
||||||
|
uint8_t pk[CRYPTO_PUBLICKEYBYTES];
|
||||||
|
uint8_t sk[CRYPTO_SECRETKEYBYTES];
|
||||||
|
uint8_t sig[CRYPTO_BYTES];
|
||||||
|
uint8_t seed[CRHBYTES];
|
||||||
|
polyvecl mat[K];
|
||||||
|
poly *a = &mat[0].vec[0];
|
||||||
|
poly *b = &mat[0].vec[1];
|
||||||
|
poly *c = &mat[0].vec[2];
|
||||||
|
|
||||||
|
for(i = 0; i < NTESTS; ++i) {
|
||||||
|
t[i] = cpucycles();
|
||||||
|
polyvec_matrix_expand(mat, seed);
|
||||||
|
}
|
||||||
|
print_results("polyvec_matrix_expand:", t, NTESTS);
|
||||||
|
|
||||||
|
for(i = 0; i < NTESTS; ++i) {
|
||||||
|
t[i] = cpucycles();
|
||||||
|
poly_uniform_eta(a, seed, 0);
|
||||||
|
}
|
||||||
|
print_results("poly_uniform_eta:", t, NTESTS);
|
||||||
|
|
||||||
|
for(i = 0; i < NTESTS; ++i) {
|
||||||
|
t[i] = cpucycles();
|
||||||
|
poly_uniform_gamma1(a, seed, 0);
|
||||||
|
}
|
||||||
|
print_results("poly_uniform_gamma1:", t, NTESTS);
|
||||||
|
|
||||||
|
for(i = 0; i < NTESTS; ++i) {
|
||||||
|
t[i] = cpucycles();
|
||||||
|
poly_ntt(a);
|
||||||
|
}
|
||||||
|
print_results("poly_ntt:", t, NTESTS);
|
||||||
|
|
||||||
|
for(i = 0; i < NTESTS; ++i) {
|
||||||
|
t[i] = cpucycles();
|
||||||
|
poly_invntt_tomont(a);
|
||||||
|
}
|
||||||
|
print_results("poly_invntt_tomont:", t, NTESTS);
|
||||||
|
|
||||||
|
for(i = 0; i < NTESTS; ++i) {
|
||||||
|
t[i] = cpucycles();
|
||||||
|
poly_pointwise_montgomery(c, a, b);
|
||||||
|
}
|
||||||
|
print_results("poly_pointwise_montgomery:", t, NTESTS);
|
||||||
|
|
||||||
|
for(i = 0; i < NTESTS; ++i) {
|
||||||
|
t[i] = cpucycles();
|
||||||
|
poly_challenge(c, seed);
|
||||||
|
}
|
||||||
|
print_results("poly_challenge:", t, NTESTS);
|
||||||
|
|
||||||
|
for(i = 0; i < NTESTS; ++i) {
|
||||||
|
t[i] = cpucycles();
|
||||||
|
crypto_sign_keypair(pk, sk);
|
||||||
|
}
|
||||||
|
print_results("Keypair:", t, NTESTS);
|
||||||
|
|
||||||
|
for(i = 0; i < NTESTS; ++i) {
|
||||||
|
t[i] = cpucycles();
|
||||||
|
crypto_sign_signature(sig, &siglen, sig, CRHBYTES, NULL, 0, sk);
|
||||||
|
}
|
||||||
|
print_results("Sign:", t, NTESTS);
|
||||||
|
|
||||||
|
for(i = 0; i < NTESTS; ++i) {
|
||||||
|
t[i] = cpucycles();
|
||||||
|
crypto_sign_verify(sig, CRYPTO_BYTES, sig, CRHBYTES, NULL, 0, pk);
|
||||||
|
}
|
||||||
|
print_results("Verify:", t, NTESTS);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
251
src/crypto/pq/_d/ref/test/test_vectors.c
Normal file
251
src/crypto/pq/_d/ref/test/test_vectors.c
Normal file
|
|
@ -0,0 +1,251 @@
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "../randombytes.h"
|
||||||
|
#include "../fips202.h"
|
||||||
|
#include "../params.h"
|
||||||
|
#include "../sign.h"
|
||||||
|
#include "../poly.h"
|
||||||
|
#include "../polyvec.h"
|
||||||
|
#include "../packing.h"
|
||||||
|
|
||||||
|
#define MLEN 32
|
||||||
|
#define CTXLEN 13
|
||||||
|
#define NVECTORS 10000
|
||||||
|
|
||||||
|
/* Initital state after absorbing empty string
|
||||||
|
* Permute before squeeze is achieved by setting pos to SHAKE128_RATE */
|
||||||
|
static keccak_state rngstate = {{0x1F, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, (1ULL << 63), 0, 0, 0, 0}, SHAKE128_RATE};
|
||||||
|
|
||||||
|
void randombytes(uint8_t *x,size_t xlen) {
|
||||||
|
shake128_squeeze(x, xlen, &rngstate);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
unsigned int i, j, k, l;
|
||||||
|
uint8_t pk[CRYPTO_PUBLICKEYBYTES];
|
||||||
|
uint8_t sk[CRYPTO_SECRETKEYBYTES];
|
||||||
|
uint8_t sig[CRYPTO_BYTES];
|
||||||
|
uint8_t m[MLEN];
|
||||||
|
uint8_t ctx[CTXLEN] = {0};
|
||||||
|
uint8_t seed[CRHBYTES];
|
||||||
|
uint8_t buf[CRYPTO_SECRETKEYBYTES];
|
||||||
|
size_t siglen;
|
||||||
|
poly c, tmp;
|
||||||
|
polyvecl s, y, mat[K];
|
||||||
|
polyveck w, w1, w0, t1, t0, h;
|
||||||
|
|
||||||
|
snprintf((char*)ctx,CTXLEN,"test_vectors");
|
||||||
|
|
||||||
|
for(i = 0; i < NVECTORS; ++i) {
|
||||||
|
printf("count = %u\n", i);
|
||||||
|
|
||||||
|
randombytes(m, MLEN);
|
||||||
|
printf("m = ");
|
||||||
|
for(j = 0; j < MLEN; ++j)
|
||||||
|
printf("%02x", m[j]);
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
crypto_sign_keypair(pk, sk);
|
||||||
|
shake256(buf, 32, pk, CRYPTO_PUBLICKEYBYTES);
|
||||||
|
printf("pk = ");
|
||||||
|
for(j = 0; j < 32; ++j)
|
||||||
|
printf("%02x", buf[j]);
|
||||||
|
printf("\n");
|
||||||
|
shake256(buf, 32, sk, CRYPTO_SECRETKEYBYTES);
|
||||||
|
printf("sk = ");
|
||||||
|
for(j = 0; j < 32; ++j)
|
||||||
|
printf("%02x", buf[j]);
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
crypto_sign_signature(sig, &siglen, m, MLEN, ctx, CTXLEN, sk);
|
||||||
|
shake256(buf, 32, sig, CRYPTO_BYTES);
|
||||||
|
printf("sig = ");
|
||||||
|
for(j = 0; j < 32; ++j)
|
||||||
|
printf("%02x", buf[j]);
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
if(crypto_sign_verify(sig, siglen, m, MLEN, ctx, CTXLEN, pk))
|
||||||
|
fprintf(stderr,"Signature verification failed!\n");
|
||||||
|
|
||||||
|
randombytes(seed, sizeof(seed));
|
||||||
|
printf("seed = ");
|
||||||
|
for(j = 0; j < sizeof(seed); ++j)
|
||||||
|
printf("%02X", seed[j]);
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
polyvec_matrix_expand(mat, seed);
|
||||||
|
printf("A = ([");
|
||||||
|
for(j = 0; j < K; ++j) {
|
||||||
|
for(k = 0; k < L; ++k) {
|
||||||
|
for(l = 0; l < N; ++l) {
|
||||||
|
printf("%8d", mat[j].vec[k].coeffs[l]);
|
||||||
|
if(l < N-1) printf(", ");
|
||||||
|
else if(k < L-1) printf("], [");
|
||||||
|
else if(j < K-1) printf("];\n [");
|
||||||
|
else printf("])\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
polyvecl_uniform_eta(&s, seed, 0);
|
||||||
|
|
||||||
|
polyeta_pack(buf, &s.vec[0]);
|
||||||
|
polyeta_unpack(&tmp, buf);
|
||||||
|
for(j = 0; j < N; ++j)
|
||||||
|
if(tmp.coeffs[j] != s.vec[0].coeffs[j])
|
||||||
|
fprintf(stderr, "ERROR in polyeta_(un)pack!\n");
|
||||||
|
|
||||||
|
if(polyvecl_chknorm(&s, ETA+1))
|
||||||
|
fprintf(stderr, "ERROR in polyvecl_chknorm(&s ,ETA+1)!\n");
|
||||||
|
|
||||||
|
printf("s = ([");
|
||||||
|
for(j = 0; j < L; ++j) {
|
||||||
|
for(k = 0; k < N; ++k) {
|
||||||
|
printf("%3d", s.vec[j].coeffs[k]);
|
||||||
|
if(k < N-1) printf(", ");
|
||||||
|
else if(j < L-1) printf("],\n [");
|
||||||
|
else printf("])\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
polyvecl_uniform_gamma1(&y, seed, 0);
|
||||||
|
|
||||||
|
polyz_pack(buf, &y.vec[0]);
|
||||||
|
polyz_unpack(&tmp, buf);
|
||||||
|
for(j = 0; j < N; ++j)
|
||||||
|
if(tmp.coeffs[j] != y.vec[0].coeffs[j])
|
||||||
|
fprintf(stderr, "ERROR in polyz_(un)pack!\n");
|
||||||
|
|
||||||
|
if(polyvecl_chknorm(&y, GAMMA1+1))
|
||||||
|
fprintf(stderr, "ERROR in polyvecl_chknorm(&y, GAMMA1)!\n");
|
||||||
|
|
||||||
|
printf("y = ([");
|
||||||
|
for(j = 0; j < L; ++j) {
|
||||||
|
for(k = 0; k < N; ++k) {
|
||||||
|
printf("%8d", y.vec[j].coeffs[k]);
|
||||||
|
if(k < N-1) printf(", ");
|
||||||
|
else if(j < L-1) printf("],\n [");
|
||||||
|
else printf("])\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
polyvecl_ntt(&y);
|
||||||
|
polyvec_matrix_pointwise_montgomery(&w, mat, &y);
|
||||||
|
polyveck_reduce(&w);
|
||||||
|
polyveck_invntt_tomont(&w);
|
||||||
|
polyveck_caddq(&w);
|
||||||
|
polyveck_decompose(&w1, &w0, &w);
|
||||||
|
|
||||||
|
for(j = 0; j < N; ++j) {
|
||||||
|
tmp.coeffs[j] = w1.vec[0].coeffs[j]*2*GAMMA2 + w0.vec[0].coeffs[j];
|
||||||
|
if(tmp.coeffs[j] < 0) tmp.coeffs[j] += Q;
|
||||||
|
if(tmp.coeffs[j] != w.vec[0].coeffs[j])
|
||||||
|
fprintf(stderr, "ERROR in poly_decompose!\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
polyw1_pack(buf, &w1.vec[0]);
|
||||||
|
#if GAMMA2 == (Q-1)/32
|
||||||
|
for(j = 0; j < N/2; ++j) {
|
||||||
|
tmp.coeffs[2*j+0] = buf[j] & 0xF;
|
||||||
|
tmp.coeffs[2*j+1] = buf[j] >> 4;
|
||||||
|
if(tmp.coeffs[2*j+0] != w1.vec[0].coeffs[2*j+0]
|
||||||
|
|| tmp.coeffs[2*j+1] != w1.vec[0].coeffs[2*j+1])
|
||||||
|
fprintf(stderr, "ERROR in polyw1_pack!\n");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if GAMMA2 == (Q-1)/32
|
||||||
|
if(polyveck_chknorm(&w1, 16))
|
||||||
|
fprintf(stderr, "ERROR in polyveck_chknorm(&w1, 16)!\n");
|
||||||
|
#elif GAMMA2 == (Q-1)/88
|
||||||
|
if(polyveck_chknorm(&w1, 44))
|
||||||
|
fprintf(stderr, "ERROR in polyveck_chknorm(&w1, 44)!\n");
|
||||||
|
#endif
|
||||||
|
if(polyveck_chknorm(&w0, GAMMA2 + 1))
|
||||||
|
fprintf(stderr, "ERROR in polyveck_chknorm(&w0, GAMMA2+1)!\n");
|
||||||
|
|
||||||
|
printf("w1 = ([");
|
||||||
|
for(j = 0; j < K; ++j) {
|
||||||
|
for(k = 0; k < N; ++k) {
|
||||||
|
printf("%2d", w1.vec[j].coeffs[k]);
|
||||||
|
if(k < N-1) printf(", ");
|
||||||
|
else if(j < K-1) printf("],\n [");
|
||||||
|
else printf("])\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("w0 = ([");
|
||||||
|
for(j = 0; j < K; ++j) {
|
||||||
|
for(k = 0; k < N; ++k) {
|
||||||
|
printf("%8d", w0.vec[j].coeffs[k]);
|
||||||
|
if(k < N-1) printf(", ");
|
||||||
|
else if(j < K-1) printf("],\n [");
|
||||||
|
else printf("])\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
polyveck_power2round(&t1, &t0, &w);
|
||||||
|
|
||||||
|
for(j = 0; j < N; ++j) {
|
||||||
|
tmp.coeffs[j] = (t1.vec[0].coeffs[j] << D) + t0.vec[0].coeffs[j];
|
||||||
|
if(tmp.coeffs[j] != w.vec[0].coeffs[j])
|
||||||
|
fprintf(stderr, "ERROR in poly_power2round!\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
polyt1_pack(buf, &t1.vec[0]);
|
||||||
|
polyt1_unpack(&tmp, buf);
|
||||||
|
for(j = 0; j < N; ++j) {
|
||||||
|
if(tmp.coeffs[j] != t1.vec[0].coeffs[j])
|
||||||
|
fprintf(stderr, "ERROR in polyt1_(un)pack!\n");
|
||||||
|
}
|
||||||
|
polyt0_pack(buf, &t0.vec[0]);
|
||||||
|
polyt0_unpack(&tmp, buf);
|
||||||
|
for(j = 0; j < N; ++j) {
|
||||||
|
if(tmp.coeffs[j] != t0.vec[0].coeffs[j])
|
||||||
|
fprintf(stderr, "ERROR in polyt0_(un)pack!\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(polyveck_chknorm(&t1, 1024))
|
||||||
|
fprintf(stderr, "ERROR in polyveck_chknorm(&t1, 1024)!\n");
|
||||||
|
if(polyveck_chknorm(&t0, (1U << (D-1)) + 1))
|
||||||
|
fprintf(stderr, "ERROR in polyveck_chknorm(&t0, (1 << (D-1)) + 1)!\n");
|
||||||
|
|
||||||
|
printf("t1 = ([");
|
||||||
|
for(j = 0; j < K; ++j) {
|
||||||
|
for(k = 0; k < N; ++k) {
|
||||||
|
printf("%3d", t1.vec[j].coeffs[k]);
|
||||||
|
if(k < N-1) printf(", ");
|
||||||
|
else if(j < K-1) printf("],\n [");
|
||||||
|
else printf("])\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("t0 = ([");
|
||||||
|
for(j = 0; j < K; ++j) {
|
||||||
|
for(k = 0; k < N; ++k) {
|
||||||
|
printf("%5d", t0.vec[j].coeffs[k]);
|
||||||
|
if(k < N-1) printf(", ");
|
||||||
|
else if(j < K-1) printf("],\n [");
|
||||||
|
else printf("])\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
poly_challenge(&c, seed);
|
||||||
|
printf("c = [");
|
||||||
|
for(j = 0; j < N; ++j) {
|
||||||
|
printf("%2d", c.coeffs[j]);
|
||||||
|
if(j < N-1) printf(", ");
|
||||||
|
else printf("]\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
polyveck_make_hint(&h, &w0, &w1);
|
||||||
|
pack_sig(buf, seed, &y, &h);
|
||||||
|
unpack_sig(seed, &y, &w, buf);
|
||||||
|
if(memcmp(&h,&w,sizeof(h)))
|
||||||
|
fprintf(stderr, "ERROR in (un)pack_sig!\n");
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
21
src/crypto/pq/_d/runlcov.sh
Executable file
21
src/crypto/pq/_d/runlcov.sh
Executable file
|
|
@ -0,0 +1,21 @@
|
||||||
|
#!/bin/sh -e
|
||||||
|
|
||||||
|
cd ref
|
||||||
|
|
||||||
|
for alg in 2 3 5; do
|
||||||
|
make -B test/test_dilithium$alg CFLAGS="-O0 -g --coverage"
|
||||||
|
./test/test_dilithium$alg
|
||||||
|
lcov -c -d . -o dilithium$alg.lcov
|
||||||
|
lcov -z -d .
|
||||||
|
rm test/test_dilithium$alg
|
||||||
|
done
|
||||||
|
|
||||||
|
lcov -o dilithium.lcov \
|
||||||
|
-a dilithium2.lcov \
|
||||||
|
-a dilithium3.lcov \
|
||||||
|
-a dilithium5.lcov \
|
||||||
|
|
||||||
|
lcov -r dilithium.lcov -o dilithium.lcov \
|
||||||
|
'*/test/test_dilithium.c'
|
||||||
|
|
||||||
|
exit 0
|
||||||
33
src/crypto/pq/_d/runtests.sh
Executable file
33
src/crypto/pq/_d/runtests.sh
Executable file
|
|
@ -0,0 +1,33 @@
|
||||||
|
#!/bin/sh -e
|
||||||
|
nproc="${nproc:-2}"
|
||||||
|
|
||||||
|
ARCH="${ARCH:-amd64}"
|
||||||
|
ARCH="${TRAVIS_CPU_ARCH:-$ARCH}"
|
||||||
|
|
||||||
|
if [ "$ARCH" = "amd64" -a "$TRAVIS_OS_NAME" != "osx" ]; then
|
||||||
|
DIRS="ref avx2"
|
||||||
|
else
|
||||||
|
DIRS="ref"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$ARCH" = "amd64" -o "$ARCH" = "arm64" ]; then
|
||||||
|
export CC=/usr/bin/clang
|
||||||
|
export CFLAGS="-fsanitize=undefined,address ${CFLAGS}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
for dir in $DIRS; do
|
||||||
|
make -j$(nproc) -C $dir clean
|
||||||
|
make -j$(nproc) -C $dir
|
||||||
|
for alg in 2 3 5; do
|
||||||
|
#valgrind --vex-guest-max-insns=25 ./$dir/test/test_dilithium$alg
|
||||||
|
./$dir/test/test_dilithium$alg &
|
||||||
|
PID1=$!
|
||||||
|
echo testvec$alg
|
||||||
|
./$dir/test/test_vectors$alg > tvecs$alg &
|
||||||
|
PID2=$!
|
||||||
|
wait $PID1 $PID2
|
||||||
|
done
|
||||||
|
shasum -a256 -c SHA256SUMS
|
||||||
|
done
|
||||||
|
|
||||||
|
exit 0
|
||||||
33
src/crypto/pq/_s/.github/workflows/test-haraka-aesni.yml
vendored
Normal file
33
src/crypto/pq/_s/.github/workflows/test-haraka-aesni.yml
vendored
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
name: Tests for haraka-aesni implementation
|
||||||
|
|
||||||
|
on:
|
||||||
|
- push
|
||||||
|
- pull_request
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
size:
|
||||||
|
- 128
|
||||||
|
- 192
|
||||||
|
- 256
|
||||||
|
option:
|
||||||
|
- s
|
||||||
|
- f
|
||||||
|
thash:
|
||||||
|
- simple
|
||||||
|
- robust
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v1
|
||||||
|
- name: Run make
|
||||||
|
run: |
|
||||||
|
make -C haraka-aesni THASH=${{ matrix.thash }} clean
|
||||||
|
make -C haraka-aesni THASH=${{ matrix.thash }} PARAMS=sphincs-haraka-${{ matrix.size }}${{ matrix.option }} tests
|
||||||
|
make -C haraka-aesni THASH=${{ matrix.thash }} PARAMS=sphincs-haraka-${{ matrix.size }}${{ matrix.option }} test
|
||||||
|
make -C haraka-aesni THASH=${{ matrix.thash }} PARAMS=sphincs-haraka-${{ matrix.size }}${{ matrix.option }} PQCgenKAT_sign
|
||||||
|
- name: Run PQCgenKAT_sign
|
||||||
|
run: python3 vectors.py sphincs-haraka-${{ matrix.size }}${{ matrix.option }}-${{ matrix.thash }} haraka-aesni
|
||||||
|
|
||||||
|
# vim: set ft=yaml ts=2 sw=2 et :
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue