From 2f8aa5e22853a00f7718c4f6d8c999dfffce795d Mon Sep 17 00:00:00 2001 From: Robert Primas Date: Wed, 16 Mar 2022 22:46:42 +0000 Subject: [PATCH] isap 3rd round optimizations --- isap/Implementations/crypto_aead/README.md | 17 ++++++----------- isap/Implementations/crypto_aead/isapa128av20/avx_512/api.h | 11 +++++++++++ isap/Implementations/crypto_aead/isapa128av20/avx_512/crypto_aead.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ isap/Implementations/crypto_aead/isapa128av20/avx_512/isap.c | 554 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ isap/Implementations/crypto_aead/isapa128av20/avx_512/isap.h | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ isap/Implementations/crypto_aead/isapa128av20/bi_32/api.h | 16 ++++++++++++++++ isap/Implementations/crypto_aead/isapa128av20/bi_32/asconp.h | 182 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ isap/Implementations/crypto_aead/isapa128av20/bi_32/config.h | 16 ++++++++++++++++ isap/Implementations/crypto_aead/isapa128av20/bi_32/crypto_aead.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ isap/Implementations/crypto_aead/isapa128av20/bi_32/forceinline.h | 19 +++++++++++++++++++ isap/Implementations/crypto_aead/isapa128av20/bi_32/isap.c | 226 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ isap/Implementations/crypto_aead/isapa128av20/bi_32/isap.h | 44 ++++++++++++++++++++++++++++++++++++++++++++ isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6/api.h | 1 + isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6/asconp.h | 206 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6/config.h | 16 ++++++++++++++++ isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6/crypto_aead.c | 1 + isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6/forceinline.h | 1 + isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6/isap.c | 1 + isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6/isap.h | 1 + isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m/api.h | 1 + isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m/asconp.h | 285 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m/config.h | 16 ++++++++++++++++ isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m/crypto_aead.c | 1 + isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m/forceinline.h | 1 + isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m/isap.c | 1 + isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m/isap.h | 1 + isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m_compact/api.h | 1 + isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m_compact/asconp.h | 273 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m_compact/config.h | 16 ++++++++++++++++ isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m_compact/crypto_aead.c | 1 + isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m_compact/forceinline.h | 1 + isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m_compact/isap.c | 1 + isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m_compact/isap.h | 1 + isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m_stp/api.h | 1 + isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m_stp/asconp.h | 275 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m_stp/config.h | 16 ++++++++++++++++ isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m_stp/crypto_aead.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m_stp/forceinline.h | 1 + isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m_stp/isap.c | 276 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m_stp/isap.h | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ isap/Implementations/crypto_aead/isapa128av20/bi_32_armv7m/api.h | 1 + isap/Implementations/crypto_aead/isapa128av20/bi_32_armv7m/asconp.h | 203 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ isap/Implementations/crypto_aead/isapa128av20/bi_32_armv7m/config.h | 16 ++++++++++++++++ isap/Implementations/crypto_aead/isapa128av20/bi_32_armv7m/crypto_aead.c | 1 + isap/Implementations/crypto_aead/isapa128av20/bi_32_armv7m/forceinline.h | 1 + isap/Implementations/crypto_aead/isapa128av20/bi_32_armv7m/isap.c | 1 + isap/Implementations/crypto_aead/isapa128av20/bi_32_armv7m/isap.h | 1 + isap/Implementations/crypto_aead/isapa128av20/bi_32_compact/api.h | 1 + isap/Implementations/crypto_aead/isapa128av20/bi_32_compact/asconp.h | 170 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ isap/Implementations/crypto_aead/isapa128av20/bi_32_compact/config.h | 16 ++++++++++++++++ isap/Implementations/crypto_aead/isapa128av20/bi_32_compact/crypto_aead.c | 1 + isap/Implementations/crypto_aead/isapa128av20/bi_32_compact/forceinline.h | 1 + isap/Implementations/crypto_aead/isapa128av20/bi_32_compact/isap.c | 1 + isap/Implementations/crypto_aead/isapa128av20/bi_32_compact/isap.h | 1 + isap/Implementations/crypto_aead/isapa128av20/bi_32_stp/api.h | 1 + isap/Implementations/crypto_aead/isapa128av20/bi_32_stp/asconp.h | 172 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ isap/Implementations/crypto_aead/isapa128av20/bi_32_stp/config.h | 16 ++++++++++++++++ isap/Implementations/crypto_aead/isapa128av20/bi_32_stp/crypto_aead.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ isap/Implementations/crypto_aead/isapa128av20/bi_32_stp/forceinline.h | 1 + isap/Implementations/crypto_aead/isapa128av20/bi_32_stp/isap.c | 276 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ isap/Implementations/crypto_aead/isapa128av20/bi_32_stp/isap.h | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ isap/Implementations/crypto_aead/isapa128av20/bi_8/api.h | 16 ++++++++++++++++ isap/Implementations/crypto_aead/isapa128av20/bi_8/asconp.h | 144 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ isap/Implementations/crypto_aead/isapa128av20/bi_8/config.h | 16 ++++++++++++++++ isap/Implementations/crypto_aead/isapa128av20/bi_8/crypto_aead.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ isap/Implementations/crypto_aead/isapa128av20/bi_8/forceinline.h | 19 +++++++++++++++++++ isap/Implementations/crypto_aead/isapa128av20/bi_8/isap.c | 226 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ isap/Implementations/crypto_aead/isapa128av20/bi_8/isap.h | 44 ++++++++++++++++++++++++++++++++++++++++++++ isap/Implementations/crypto_aead/isapa128av20/opt_32/api.h | 7 ++++++- isap/Implementations/crypto_aead/isapa128av20/opt_32/asconp.h | 199 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------------------------------------------------------------------------------------------ isap/Implementations/crypto_aead/isapa128av20/opt_32/config.h | 16 ++++++++++++++++ isap/Implementations/crypto_aead/isapa128av20/opt_32/forceinline.h | 19 +++++++++++++++++++ isap/Implementations/crypto_aead/isapa128av20/opt_32/isap.c | 338 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ isap/Implementations/crypto_aead/isapa128av20/opt_32/isap.h | 33 ++++++++++++++------------------- isap/Implementations/crypto_aead/isapa128av20/opt_32_compact/api.h | 1 + isap/Implementations/crypto_aead/isapa128av20/opt_32_compact/asconp.h | 110 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ isap/Implementations/crypto_aead/isapa128av20/opt_32_compact/config.h | 16 ++++++++++++++++ isap/Implementations/crypto_aead/isapa128av20/opt_32_compact/crypto_aead.c | 1 + isap/Implementations/crypto_aead/isapa128av20/opt_32_compact/forceinline.h | 1 + isap/Implementations/crypto_aead/isapa128av20/opt_32_compact/isap.c | 1 + isap/Implementations/crypto_aead/isapa128av20/opt_32_compact/isap.h | 1 + isap/Implementations/crypto_aead/isapa128av20/opt_32_stp/api.h | 1 + isap/Implementations/crypto_aead/isapa128av20/opt_32_stp/asconp.h | 112 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ isap/Implementations/crypto_aead/isapa128av20/opt_32_stp/config.h | 16 ++++++++++++++++ isap/Implementations/crypto_aead/isapa128av20/opt_32_stp/crypto_aead.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ isap/Implementations/crypto_aead/isapa128av20/opt_32_stp/forceinline.h | 1 + isap/Implementations/crypto_aead/isapa128av20/opt_32_stp/isap.c | 276 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ isap/Implementations/crypto_aead/isapa128av20/opt_32_stp/isap.h | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ isap/Implementations/crypto_aead/isapa128av20/opt_32_tiny/api.h | 1 + isap/Implementations/crypto_aead/isapa128av20/opt_32_tiny/asconp.h | 103 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ isap/Implementations/crypto_aead/isapa128av20/opt_32_tiny/config.h | 16 ++++++++++++++++ isap/Implementations/crypto_aead/isapa128av20/opt_32_tiny/crypto_aead.c | 1 + isap/Implementations/crypto_aead/isapa128av20/opt_32_tiny/forceinline.h | 1 + isap/Implementations/crypto_aead/isapa128av20/opt_32_tiny/isap.c | 226 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ isap/Implementations/crypto_aead/isapa128av20/opt_32_tiny/isap.h | 1 + isap/Implementations/crypto_aead/isapa128av20/opt_64/api.h | 7 +++++-- isap/Implementations/crypto_aead/isapa128av20/opt_64/asconp.h | 226 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------------------------------------------------------------------------------------- isap/Implementations/crypto_aead/isapa128av20/opt_64/config.h | 16 ++++++++++++++++ isap/Implementations/crypto_aead/isapa128av20/opt_64/forceinline.h | 19 +++++++++++++++++++ isap/Implementations/crypto_aead/isapa128av20/opt_64/isap.c | 340 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------------------------------------------------------------------------------------------------------------------------------------------- isap/Implementations/crypto_aead/isapa128av20/opt_64/isap.h | 39 +++++++++++++++------------------------ isap/Implementations/crypto_aead/isapa128av20/opt_8/api.h | 16 ++++++++++++++++ isap/Implementations/crypto_aead/isapa128av20/opt_8/asconp.h | 171 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ isap/Implementations/crypto_aead/isapa128av20/opt_8/config.h | 16 ++++++++++++++++ isap/Implementations/crypto_aead/isapa128av20/opt_8/crypto_aead.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ isap/Implementations/crypto_aead/isapa128av20/opt_8/forceinline.h | 19 +++++++++++++++++++ isap/Implementations/crypto_aead/isapa128av20/opt_8/isap.c | 226 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ isap/Implementations/crypto_aead/isapa128av20/opt_8/isap.h | 44 ++++++++++++++++++++++++++++++++++++++++++++ isap/Implementations/crypto_aead/isapa128av20/opt_8_tiny/api.h | 1 + isap/Implementations/crypto_aead/isapa128av20/opt_8_tiny/asconp.h | 164 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ isap/Implementations/crypto_aead/isapa128av20/opt_8_tiny/config.h | 16 ++++++++++++++++ isap/Implementations/crypto_aead/isapa128av20/opt_8_tiny/crypto_aead.c | 1 + isap/Implementations/crypto_aead/isapa128av20/opt_8_tiny/forceinline.h | 1 + isap/Implementations/crypto_aead/isapa128av20/opt_8_tiny/isap.c | 226 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ isap/Implementations/crypto_aead/isapa128av20/opt_8_tiny/isap.h | 1 + isap/Implementations/crypto_aead/isapxv20/ref/.gitignore | 2 ++ 116 files changed, 6939 insertions(+), 588 deletions(-) create mode 100644 isap/Implementations/crypto_aead/isapa128av20/avx_512/api.h create mode 100644 isap/Implementations/crypto_aead/isapa128av20/avx_512/crypto_aead.c create mode 100644 isap/Implementations/crypto_aead/isapa128av20/avx_512/isap.c create mode 100644 isap/Implementations/crypto_aead/isapa128av20/avx_512/isap.h create mode 100644 isap/Implementations/crypto_aead/isapa128av20/bi_32/api.h create mode 100644 isap/Implementations/crypto_aead/isapa128av20/bi_32/asconp.h create mode 100644 isap/Implementations/crypto_aead/isapa128av20/bi_32/config.h create mode 100644 isap/Implementations/crypto_aead/isapa128av20/bi_32/crypto_aead.c create mode 100644 isap/Implementations/crypto_aead/isapa128av20/bi_32/forceinline.h create mode 100644 isap/Implementations/crypto_aead/isapa128av20/bi_32/isap.c create mode 100644 isap/Implementations/crypto_aead/isapa128av20/bi_32/isap.h create mode 120000 isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6/api.h create mode 100644 isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6/asconp.h create mode 100644 isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6/config.h create mode 120000 isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6/crypto_aead.c create mode 120000 isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6/forceinline.h create mode 120000 isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6/isap.c create mode 120000 isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6/isap.h create mode 120000 isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m/api.h create mode 100644 isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m/asconp.h create mode 100644 isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m/config.h create mode 120000 isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m/crypto_aead.c create mode 120000 isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m/forceinline.h create mode 120000 isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m/isap.c create mode 120000 isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m/isap.h create mode 120000 isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m_compact/api.h create mode 100644 isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m_compact/asconp.h create mode 100644 isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m_compact/config.h create mode 120000 isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m_compact/crypto_aead.c create mode 120000 isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m_compact/forceinline.h create mode 120000 isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m_compact/isap.c create mode 120000 isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m_compact/isap.h create mode 120000 isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m_stp/api.h create mode 100644 isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m_stp/asconp.h create mode 100644 isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m_stp/config.h create mode 100644 isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m_stp/crypto_aead.c create mode 120000 isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m_stp/forceinline.h create mode 100644 isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m_stp/isap.c create mode 100644 isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m_stp/isap.h create mode 120000 isap/Implementations/crypto_aead/isapa128av20/bi_32_armv7m/api.h create mode 100644 isap/Implementations/crypto_aead/isapa128av20/bi_32_armv7m/asconp.h create mode 100644 isap/Implementations/crypto_aead/isapa128av20/bi_32_armv7m/config.h create mode 120000 isap/Implementations/crypto_aead/isapa128av20/bi_32_armv7m/crypto_aead.c create mode 120000 isap/Implementations/crypto_aead/isapa128av20/bi_32_armv7m/forceinline.h create mode 120000 isap/Implementations/crypto_aead/isapa128av20/bi_32_armv7m/isap.c create mode 120000 isap/Implementations/crypto_aead/isapa128av20/bi_32_armv7m/isap.h create mode 120000 isap/Implementations/crypto_aead/isapa128av20/bi_32_compact/api.h create mode 100644 isap/Implementations/crypto_aead/isapa128av20/bi_32_compact/asconp.h create mode 100644 isap/Implementations/crypto_aead/isapa128av20/bi_32_compact/config.h create mode 120000 isap/Implementations/crypto_aead/isapa128av20/bi_32_compact/crypto_aead.c create mode 120000 isap/Implementations/crypto_aead/isapa128av20/bi_32_compact/forceinline.h create mode 120000 isap/Implementations/crypto_aead/isapa128av20/bi_32_compact/isap.c create mode 120000 isap/Implementations/crypto_aead/isapa128av20/bi_32_compact/isap.h create mode 120000 isap/Implementations/crypto_aead/isapa128av20/bi_32_stp/api.h create mode 100644 isap/Implementations/crypto_aead/isapa128av20/bi_32_stp/asconp.h create mode 100644 isap/Implementations/crypto_aead/isapa128av20/bi_32_stp/config.h create mode 100644 isap/Implementations/crypto_aead/isapa128av20/bi_32_stp/crypto_aead.c create mode 120000 isap/Implementations/crypto_aead/isapa128av20/bi_32_stp/forceinline.h create mode 100644 isap/Implementations/crypto_aead/isapa128av20/bi_32_stp/isap.c create mode 100644 isap/Implementations/crypto_aead/isapa128av20/bi_32_stp/isap.h create mode 100644 isap/Implementations/crypto_aead/isapa128av20/bi_8/api.h create mode 100644 isap/Implementations/crypto_aead/isapa128av20/bi_8/asconp.h create mode 100644 isap/Implementations/crypto_aead/isapa128av20/bi_8/config.h create mode 100644 isap/Implementations/crypto_aead/isapa128av20/bi_8/crypto_aead.c create mode 100644 isap/Implementations/crypto_aead/isapa128av20/bi_8/forceinline.h create mode 100644 isap/Implementations/crypto_aead/isapa128av20/bi_8/isap.c create mode 100644 isap/Implementations/crypto_aead/isapa128av20/bi_8/isap.h create mode 100644 isap/Implementations/crypto_aead/isapa128av20/opt_32/config.h create mode 100644 isap/Implementations/crypto_aead/isapa128av20/opt_32/forceinline.h create mode 120000 isap/Implementations/crypto_aead/isapa128av20/opt_32_compact/api.h create mode 100644 isap/Implementations/crypto_aead/isapa128av20/opt_32_compact/asconp.h create mode 100644 isap/Implementations/crypto_aead/isapa128av20/opt_32_compact/config.h create mode 120000 isap/Implementations/crypto_aead/isapa128av20/opt_32_compact/crypto_aead.c create mode 120000 isap/Implementations/crypto_aead/isapa128av20/opt_32_compact/forceinline.h create mode 120000 isap/Implementations/crypto_aead/isapa128av20/opt_32_compact/isap.c create mode 120000 isap/Implementations/crypto_aead/isapa128av20/opt_32_compact/isap.h create mode 120000 isap/Implementations/crypto_aead/isapa128av20/opt_32_stp/api.h create mode 100644 isap/Implementations/crypto_aead/isapa128av20/opt_32_stp/asconp.h create mode 100644 isap/Implementations/crypto_aead/isapa128av20/opt_32_stp/config.h create mode 100644 isap/Implementations/crypto_aead/isapa128av20/opt_32_stp/crypto_aead.c create mode 120000 isap/Implementations/crypto_aead/isapa128av20/opt_32_stp/forceinline.h create mode 100644 isap/Implementations/crypto_aead/isapa128av20/opt_32_stp/isap.c create mode 100644 isap/Implementations/crypto_aead/isapa128av20/opt_32_stp/isap.h create mode 120000 isap/Implementations/crypto_aead/isapa128av20/opt_32_tiny/api.h create mode 100644 isap/Implementations/crypto_aead/isapa128av20/opt_32_tiny/asconp.h create mode 100644 isap/Implementations/crypto_aead/isapa128av20/opt_32_tiny/config.h create mode 120000 isap/Implementations/crypto_aead/isapa128av20/opt_32_tiny/crypto_aead.c create mode 120000 isap/Implementations/crypto_aead/isapa128av20/opt_32_tiny/forceinline.h create mode 100644 isap/Implementations/crypto_aead/isapa128av20/opt_32_tiny/isap.c create mode 120000 isap/Implementations/crypto_aead/isapa128av20/opt_32_tiny/isap.h create mode 100644 isap/Implementations/crypto_aead/isapa128av20/opt_64/config.h create mode 100644 isap/Implementations/crypto_aead/isapa128av20/opt_64/forceinline.h create mode 100644 isap/Implementations/crypto_aead/isapa128av20/opt_8/api.h create mode 100644 isap/Implementations/crypto_aead/isapa128av20/opt_8/asconp.h create mode 100644 isap/Implementations/crypto_aead/isapa128av20/opt_8/config.h create mode 100644 isap/Implementations/crypto_aead/isapa128av20/opt_8/crypto_aead.c create mode 100644 isap/Implementations/crypto_aead/isapa128av20/opt_8/forceinline.h create mode 100644 isap/Implementations/crypto_aead/isapa128av20/opt_8/isap.c create mode 100644 isap/Implementations/crypto_aead/isapa128av20/opt_8/isap.h create mode 120000 isap/Implementations/crypto_aead/isapa128av20/opt_8_tiny/api.h create mode 100644 isap/Implementations/crypto_aead/isapa128av20/opt_8_tiny/asconp.h create mode 100644 isap/Implementations/crypto_aead/isapa128av20/opt_8_tiny/config.h create mode 120000 isap/Implementations/crypto_aead/isapa128av20/opt_8_tiny/crypto_aead.c create mode 120000 isap/Implementations/crypto_aead/isapa128av20/opt_8_tiny/forceinline.h create mode 100644 isap/Implementations/crypto_aead/isapa128av20/opt_8_tiny/isap.c create mode 120000 isap/Implementations/crypto_aead/isapa128av20/opt_8_tiny/isap.h create mode 100644 isap/Implementations/crypto_aead/isapxv20/ref/.gitignore diff --git a/isap/Implementations/crypto_aead/README.md b/isap/Implementations/crypto_aead/README.md index c5dcd3e..126e702 100644 --- a/isap/Implementations/crypto_aead/README.md +++ b/isap/Implementations/crypto_aead/README.md @@ -1,13 +1,8 @@ -### Folder Structure: +**Folder Structure:** -* **isapa128av20** - * Code for ISAP128a using Ascon-p. -* **isapa128v20** - * Code for ISAP128 using Ascon-p. -* **isapk128av20** - * Code for ISAP128a using Keccak-p[400]. -* **isapk128v20** - * Code for ISAP128 using Keccak-p[400]. -* **isapxv20** - * A common codebase that can be used to build reference code for all four instances of ISAP. +- `isapa128av20`: Code for ISAP128a using Ascon-p (primary recommendation). +- `isapa128v20`: Code for ISAP128 using Ascon-p. +- `isapk128av20`: Code for ISAP128a using Keccak-p[400]. +- `isapk128v20`: Code for ISAP128 using Keccak-p[400]. +- `isapxv20`: A generic codebase that can be used to build reference code for all four instances of ISAP. diff --git a/isap/Implementations/crypto_aead/isapa128av20/avx_512/api.h b/isap/Implementations/crypto_aead/isapa128av20/avx_512/api.h new file mode 100644 index 0000000..13792e9 --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/avx_512/api.h @@ -0,0 +1,11 @@ +#ifndef API_H +#define API_H + +#define CRYPTO_VERSION "2.0.1" +#define CRYPTO_KEYBYTES 16 +#define CRYPTO_NSECBYTES 0 +#define CRYPTO_NPUBBYTES 16 +#define CRYPTO_ABYTES 16 +#define CRYPTO_NOOVERLAP 1 + +#endif diff --git a/isap/Implementations/crypto_aead/isapa128av20/avx_512/crypto_aead.c b/isap/Implementations/crypto_aead/isapa128av20/avx_512/crypto_aead.c new file mode 100644 index 0000000..58f7641 --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/avx_512/crypto_aead.c @@ -0,0 +1,56 @@ +#include "api.h" +#include "isap.h" +#include "crypto_aead.h" + +int crypto_aead_encrypt( + unsigned char *c, unsigned long long *clen, + const unsigned char *m, unsigned long long mlen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k +){ + (void)nsec; + + // Ciphertext length is mlen + tag length + *clen = mlen+ISAP_TAG_SZ; + + // Encrypt plaintext and Generate tag + unsigned char *tag = c+mlen; + isap_mac_enc(k,npub,ad,adlen,c,mlen,m,mlen,tag); + return 0; +} + +int crypto_aead_decrypt( + unsigned char *m, unsigned long long *mlen, + unsigned char *nsec, + const unsigned char *c, unsigned long long clen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k +){ + (void)nsec; + + // Plaintext length is clen - tag length + *mlen = clen-ISAP_TAG_SZ; + + // Generate tag + unsigned char tag[ISAP_TAG_SZ]; + isap_mac(k,npub,ad,adlen,c,*mlen,tag); + + // Compare tag + unsigned long eq_cnt = 0; + for(unsigned int i = 0; i < ISAP_TAG_SZ; i++) { + eq_cnt += (tag[i] == c[(*mlen)+i]); + } + + // Perform decryption if tag is correct + if(eq_cnt == (unsigned long)ISAP_TAG_SZ){ + if (*mlen > 0) { + isap_enc(k,npub,c,*mlen,m); + } + return 0; + } else { + return -1; + } +} diff --git a/isap/Implementations/crypto_aead/isapa128av20/avx_512/isap.c b/isap/Implementations/crypto_aead/isapa128av20/avx_512/isap.c new file mode 100644 index 0000000..c431075 --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/avx_512/isap.c @@ -0,0 +1,554 @@ +#include +#include +#include +#include "api.h" +#include "isap.h" + +typedef unsigned char u8; +typedef unsigned long long u64; +typedef unsigned long u32; +typedef long long i64; + +const u8 ISAP_IV1[] = {0x01,ISAP_K,ISAP_rH,ISAP_rB,ISAP_sH,ISAP_sB,ISAP_sE,ISAP_sK}; +const u8 ISAP_IV2[] = {0x02,ISAP_K,ISAP_rH,ISAP_rB,ISAP_sH,ISAP_sB,ISAP_sE,ISAP_sK}; +const u8 ISAP_IV3[] = {0x03,ISAP_K,ISAP_rH,ISAP_rB,ISAP_sH,ISAP_sB,ISAP_sE,ISAP_sK}; + +#define RATE (64 / 8) +#define PA_ROUNDS 12 +#define PB_ROUNDS 6 + +#define ROTR(x,n) (((x)>>(n))|((x)<<(64-(n)))) +#define EXT_BYTE(x,n) ((u8)((u64)(x)>>(8*(7-(n))))) +#define INS_BYTE(x,n) ((u64)(x)<<(8*(7-(n)))) + +#define U64BIG(x) \ + ((ROTR(x, 8) & (0xFF000000FF000000ULL)) | \ + (ROTR(x,24) & (0x00FF000000FF0000ULL)) | \ + (ROTR(x,40) & (0x0000FF000000FF00ULL)) | \ + (ROTR(x,56) & (0x000000FF000000FFULL))) + +#define ROUND(C) ({\ + x2 ^= C;\ + x0 ^= x4;\ + x4 ^= x3;\ + x2 ^= x1;\ + t0 = x0;\ + t4 = x4;\ + t3 = x3;\ + t1 = x1;\ + t2 = x2;\ + x0 = t0 ^ ((~t1) & t2);\ + x2 = t2 ^ ((~t3) & t4);\ + x4 = t4 ^ ((~t0) & t1);\ + x1 = t1 ^ ((~t2) & t3);\ + x3 = t3 ^ ((~t4) & t0);\ + x1 ^= x0;\ + t1 = x1;\ + x1 = ROTR(x1, R[1][0]);\ + x3 ^= x2;\ + t2 = x2;\ + x2 = ROTR(x2, R[2][0]);\ + t4 = x4;\ + t2 ^= x2;\ + x2 = ROTR(x2, R[2][1] - R[2][0]);\ + t3 = x3;\ + t1 ^= x1;\ + x3 = ROTR(x3, R[3][0]);\ + x0 ^= x4;\ + x4 = ROTR(x4, R[4][0]);\ + t3 ^= x3;\ + x2 ^= t2;\ + x1 = ROTR(x1, R[1][1] - R[1][0]);\ + t0 = x0;\ + x2 = ~x2;\ + x3 = ROTR(x3, R[3][1] - R[3][0]);\ + t4 ^= x4;\ + x4 = ROTR(x4, R[4][1] - R[4][0]);\ + x3 ^= t3;\ + x1 ^= t1;\ + x0 = ROTR(x0, R[0][0]);\ + x4 ^= t4;\ + t0 ^= x0;\ + x0 = ROTR(x0, R[0][1] - R[0][0]);\ + x0 ^= t0;\ +}) + +#define ROUNDAVX(C1,C2) ({\ + x2a = _mm_ternarylogic_epi64(x2a, _mm_set_epi64x (C1, C2), x1a, 0x96);\ + x0a =_mm_xor_si128 (x0a, x4a);\ + x4a =_mm_xor_si128 (x4a, x3a);\ + t0a = x0a;\ + t4a = x4a;\ + t3a = x3a;\ + t1a = x1a;\ + t2a = x2a;\ + x0a = _mm_ternarylogic_epi64(t0a, t1a, t2a, 0xd2);\ + x2a = _mm_ternarylogic_epi64(t2a, t3a, t4a, 0xd2);\ + x4a = _mm_ternarylogic_epi64(t4a, t0a, t1a, 0xd2);\ + x1a = _mm_ternarylogic_epi64(t1a, t2a, t3a, 0xd2);\ + x3a = _mm_ternarylogic_epi64(t3a, t4a, t0a, 0xd2);\ + x1a =_mm_xor_si128 (x1a, x0a);\ + x3a =_mm_xor_si128 (x3a, x2a);\ + x0a =_mm_xor_si128 (x0a, x4a);\ + t0a = _mm_ror_epi64(x0a, R[0][0]);\ + t1a = _mm_ror_epi64(x0a, R[0][1]);\ + t2a = _mm_ror_epi64(x1a, R[1][0]);\ + t3a = _mm_ror_epi64(x1a, R[1][1]);\ + x0a = _mm_ternarylogic_epi64(x0a, t0a, t1a, 0x96);\ + x1a = _mm_ternarylogic_epi64(x1a, t2a, t3a, 0x96);\ + t0a = _mm_ror_epi64(x2a, R[2][0]);\ + t1a = _mm_ror_epi64(x2a, R[2][1]);\ + t2a = _mm_ror_epi64(x3a, R[3][0]);\ + t3a = _mm_ror_epi64(x3a, R[3][1]);\ + x2a = _mm_ternarylogic_epi64(x2a, t0a, t1a, 0x69);\ + x3a = _mm_ternarylogic_epi64(x3a, t2a, t3a, 0x96);\ + t0a = _mm_ror_epi64(x4a, R[4][0]);\ + t1a = _mm_ror_epi64(x4a, R[4][1]);\ + x4a = _mm_ternarylogic_epi64(x4a, t0a, t1a, 0x96);\ +}) + +#define P12 ({\ + ROUND(0xf0);\ + ROUND(0xe1);\ + ROUND(0xd2);\ + ROUND(0xc3);\ + ROUND(0xb4);\ + ROUND(0xa5);\ + ROUND(0x96);\ + ROUND(0x87);\ + ROUND(0x78);\ + ROUND(0x69);\ + ROUND(0x5a);\ + ROUND(0x4b);\ +}) + +#define P6 ({\ + ROUND(0x96);\ + ROUND(0x87);\ + ROUND(0x78);\ + ROUND(0x69);\ + ROUND(0x5a);\ + ROUND(0x4b);\ +}) + +#define P6_avx_first ({\ + ROUNDAVX(0xf0,0x96);\ + ROUNDAVX(0xe1,0x87);\ + ROUNDAVX(0xd2,0x78);\ + ROUNDAVX(0xc3,0x69);\ + ROUNDAVX(0xb4,0x5a);\ + ROUNDAVX(0xa5,0x4b);\ +}) + +#define P6_avx_second ({\ + ROUNDAVX(0x96,0x96);\ + ROUNDAVX(0x87,0x87);\ + ROUNDAVX(0x78,0x78);\ + ROUNDAVX(0x69,0x69);\ + ROUNDAVX(0x5a,0x5a);\ + ROUNDAVX(0x4b,0x4b);\ +}) + +#define P1 ({\ + ROUND(0x4b);\ +}) + +static const int R[5][2] = { + {19, 28}, {39, 61}, {1, 6}, {10, 17}, {7, 41} +}; + +#define ABSORB_LANES(src, len) ({ \ + u32 rem_bytes = len; \ + u64 *src64 = (u64 *)src; \ + u32 idx64 = 0; \ + while(1){ \ + if(rem_bytes>ISAP_rH_SZ){ \ + x0 ^= U64BIG(src64[idx64]); \ + idx64++; \ + P12; \ + rem_bytes -= ISAP_rH_SZ; \ + } else if(rem_bytes==ISAP_rH_SZ){ \ + x0 ^= U64BIG(src64[idx64]); \ + P12; \ + x0 ^= 0x8000000000000000ULL; \ + break; \ + } else { \ + u64 lane64; \ + u8 *lane8 = (u8 *)&lane64; \ + u32 idx8 = idx64*8; \ + for (u32 i = 0; i < 8; i++) { \ + if(i<(rem_bytes)){ \ + lane8[i] = src[idx8]; \ + idx8++; \ + } else if(i==rem_bytes){ \ + lane8[i] = 0x80; \ + } else { \ + lane8[i] = 0x00; \ + } \ + } \ + x0 ^= U64BIG(lane64); \ + break; \ + } \ + } \ +}) + +/******************************************************************************/ +/* IsapRk */ +/******************************************************************************/ + +void isap_rk( + const u8 *k, + const u8 *iv, + const u8 *y, + const u64 ylen, + u8 *out, + const u64 outlen +){ + const u64 *k64 = (u64 *)k; + const u64 *iv64 = (u64 *)iv; + u64 *out64 = (u64 *)out; + u64 x0, x1, x2, x3, x4; + u64 t0, t1, t2, t3, t4; + + // Init state + t0 = t1 = t2 = t3 = t4 = 0; + x0 = U64BIG(k64[0]); + x1 = U64BIG(k64[1]); + x2 = U64BIG(iv64[0]); + x3 = x4 = 0; + P12; + + // Absorb Y + for (size_t i = 0; i < ylen*8-1; i++){ + size_t cur_byte_pos = i/8; + size_t cur_bit_pos = 7-(i%8); + u8 cur_bit = ((y[cur_byte_pos] >> (cur_bit_pos)) & 0x01) << 7; + x0 ^= ((u64)cur_bit) << 56; + P1; + } + u8 cur_bit = ((y[ylen-1]) & 0x01) << 7; + x0 ^= ((u64)cur_bit) << 56; + P12; + + // Extract K* + out64[0] = U64BIG(x0); + out64[1] = U64BIG(x1); + if(outlen == 24){ + out64[2] = U64BIG(x2); + } +} + +/******************************************************************************/ +/* IsapMac */ +/******************************************************************************/ + +void isap_mac( + const u8 *k, + const u8 *npub, + const u8 *ad, const u64 adlen, + const u8 *c, const u64 clen, + u8 *tag +){ + u8 state[ISAP_STATE_SZ]; + const u64 *npub64 = (u64 *)npub; + u64 *state64 = (u64 *)state; + u64 x0, x1, x2, x3, x4; + u64 t0, t1, t2, t3, t4; + t0 = t1 = t2 = t3 = t4 = 0; + + // Init state + x0 = U64BIG(npub64[0]); + x1 = U64BIG(npub64[1]); + x2 = U64BIG(((u64 *)ISAP_IV1)[0]); + x3 = x4 = 0; + P12; + + // Absorb AD + ABSORB_LANES(ad,adlen); + + // Domain seperation + P12; + x4 ^= 0x0000000000000001ULL; + + // Absorb C + ABSORB_LANES(c,clen); + P12; + + // Derive K* + state64[0] = U64BIG(x0); + state64[1] = U64BIG(x1); + state64[2] = U64BIG(x2); + state64[3] = U64BIG(x3); + state64[4] = U64BIG(x4); + isap_rk(k,ISAP_IV2,(u8 *)state64,CRYPTO_KEYBYTES,(u8 *)state64,CRYPTO_KEYBYTES); + x0 = U64BIG(state64[0]); + x1 = U64BIG(state64[1]); + x2 = U64BIG(state64[2]); + x3 = U64BIG(state64[3]); + x4 = U64BIG(state64[4]); + + // Squeeze tag + P12; + unsigned long long *tag64 = (u64 *)tag; + tag64[0] = U64BIG(x0); + tag64[1] = U64BIG(x1); +} + +/******************************************************************************/ +/* IsapEnc */ +/******************************************************************************/ + +void isap_enc( + const u8 *k, + const u8 *npub, + const u8 *m, + const u64 mlen, + u8 *c +){ + u8 state[ISAP_STATE_SZ]; + + // Init state + u64 *state64 = (u64 *)state; + u64 *npub64 = (u64 *)npub; + isap_rk(k,ISAP_IV3,npub,CRYPTO_NPUBBYTES,state,ISAP_STATE_SZ-CRYPTO_NPUBBYTES); + u64 x0, x1, x2, x3, x4; + u64 t0, t1, t2, t3, t4; + t0 = t1 = t2 = t3 = t4 = 0; + x0 = U64BIG(state64[0]); + x1 = U64BIG(state64[1]); + x2 = U64BIG(state64[2]); + x3 = U64BIG(npub64[0]); + x4 = U64BIG(npub64[1]); + P6; + + // Squeeze key stream + u64 rem_bytes = mlen; + u64 *m64 = (u64 *)m; + u64 *c64 = (u64 *)c; + u32 idx64 = 0; + while(1){ + if(rem_bytes>ISAP_rH_SZ){ + // Squeeze full lane + c64[idx64] = U64BIG(x0) ^ m64[idx64]; + idx64++; + P6; + rem_bytes -= ISAP_rH_SZ; + } else if(rem_bytes==ISAP_rH_SZ){ + // Squeeze full lane and stop + c64[idx64] = U64BIG(x0) ^ m64[idx64]; + break; + } else { + // Squeeze partial lane and stop + u64 lane64 = U64BIG(x0); + u8 *lane8 = (u8 *)&lane64; + u32 idx8 = idx64*8; + for (u32 i = 0; i < rem_bytes; i++) { + c[idx8] = lane8[i] ^ m[idx8]; + idx8++; + } + break; + } + } +} + + +/******************************************************************************/ +/* IsapMac and Enc */ +/******************************************************************************/ + +void isap_mac_enc( + const u8 *k, + const u8 *npub, + const u8 *ad, const u64 adlen, + u8 *c, const u64 clen, + const u8 *m, const u64 mlen, + u8 *tag +){ + u8 state_mac[ISAP_STATE_SZ]; + const u64 *npub64 = (u64 *)npub; + u64 *state_mac64 = (u64 *)state_mac; + u64 x0, x1, x2, x3, x4; + u64 t0, t1, t2, t3, t4; + __m128i x0a, x1a, x2a, x3a, x4a; + __m128i t0a, t1a, t2a, t3a, t4a; + t0 = t1 = t2 = t3 = t4 = 0; + + u8 state_enc[ISAP_STATE_SZ]; + + // Init state_enc + u64 *state_enc64 = (u64 *)state_enc; + isap_rk(k,ISAP_IV3,npub,CRYPTO_NPUBBYTES,state_enc,ISAP_STATE_SZ-CRYPTO_NPUBBYTES); + t0 = t1 = t2 = t3 = t4 = 0; + + state_enc64[3] = npub64[0]; + state_enc64[4] = npub64[1]; + + // Init state_mac + x0 = U64BIG(npub64[0]); + x1 = U64BIG(npub64[1]); + x2 = U64BIG(((u64 *)ISAP_IV1)[0]); + x3 = x4 = 0; + P12; + + // Absorb AD + ABSORB_LANES(ad,adlen); + + + //Initialize AVX registers + t0 = U64BIG(state_enc64[0]); + t1 = U64BIG(state_enc64[1]); + t2 = U64BIG(state_enc64[2]); + t3 = U64BIG(state_enc64[3]); + t4 = U64BIG(state_enc64[4]); + + + u64 tmp[2]; + tmp[1] = x0; + tmp[0] = t0; + x0a = _mm_maskz_loadu_epi64 (3, tmp); + tmp[1] = x1; + tmp[0] = t1; + x1a = _mm_maskz_loadu_epi64 (3, tmp); + tmp[1] = x2; + tmp[0] = t2; + x2a = _mm_maskz_loadu_epi64 (3, tmp); + tmp[1] = x3; + tmp[0] = t3; + x3a = _mm_maskz_loadu_epi64 (3, tmp); + tmp[1] = x4; + tmp[0] = t4; + x4a = _mm_maskz_loadu_epi64 (3, tmp); + + + + // Squeeze key stream while absorbing ciphertext + long long rem_enc_bytes = mlen; + u64 tmpc1,tmpc2; + u64 tmpm1,tmpm2; + u64 encbytes1,encbytes2; + u32 idx8_enc = 0; + u32 idx8_mac = 0; + u64 tmpc_mac[2]; + __m128i domain_separation = _mm_set_epi64x (0x0000000000000001ULL, 0); + long long rem_mac_bytes = clen; + do{ + //prepare plaintext to encrypt + tmpm1 = 0; + tmpm2 = 0; + if(rem_enc_bytes>=ISAP_rH_SZ) + encbytes1 = 8; + else + encbytes1 = rem_enc_bytes; + if((rem_enc_bytes-encbytes1)>=ISAP_rH_SZ) + encbytes2 = 8; + else + if(encbytes1 < 8) + encbytes2 = 0; + else + encbytes2 = rem_enc_bytes - encbytes1; + for (u32 i = 0; i < encbytes1; i++) + tmpm1 = (tmpm1 << 8) | ((u64)m[idx8_enc+(encbytes1-i-1)]); + for (u32 i = 0; i < encbytes2; i++) + tmpm2 = (tmpm2 << 8) | ((u64)m[idx8_enc+encbytes1+(encbytes2-i-1)]); + + //prepare ciphertext to authenticate + tmpc_mac[1] = 0; + if(rem_enc_bytes < mlen){ + u8 *lane8 = (u8 *)&tmpc_mac[1]; + for (u32 i = 0; i < 8; i++) { + if(i<(rem_mac_bytes)){ + lane8[i] = c[idx8_mac]; + idx8_mac++; + } else if(i==rem_mac_bytes){ + lane8[i] = 0x80; + } else { + lane8[i] = 0x00; + } + } + tmpc_mac[1] = U64BIG(tmpc_mac[1]); + rem_mac_bytes -= ISAP_rH_SZ; + } + + + + x0a = _mm_xor_si128 (x0a, _mm_maskz_loadu_epi64 (2, tmpc_mac)); + P6_avx_first; + _mm_mask_storeu_epi64 (tmp, 1, x0a); + tmpc1 = U64BIG(tmp[0]) ^ tmpm1; + P6_avx_second; + _mm_mask_storeu_epi64 (tmp, 1, x0a); + tmpc2 = U64BIG(tmp[0]) ^ tmpm2; + x4a = _mm_xor_si128 (x4a, domain_separation); + domain_separation = _mm_andnot_si128 (domain_separation,domain_separation); + + + + // Squeeze lane + u8 *lane8 = (u8 *)&tmpc1; + for (u32 i = 0; i < encbytes1; i++) { + c[idx8_enc] = lane8[i]; + idx8_enc++; + } + lane8 = (u8 *)&tmpc2; + for (u32 i = 0; i < encbytes2; i++) { + c[idx8_enc] = lane8[i]; + idx8_enc++; + } + rem_enc_bytes -= 2*ISAP_rH_SZ; + + }while(rem_enc_bytes>0); + //end encrypting + + + //Restore MAC state + _mm_mask_storeu_epi64 (tmp, 2, x0a); + x0 = tmp[1]; + _mm_mask_storeu_epi64 (tmp, 2, x1a); + x1 = tmp[1]; + _mm_mask_storeu_epi64 (tmp, 2, x2a); + x2 = tmp[1]; + _mm_mask_storeu_epi64 (tmp, 2, x3a); + x3 = tmp[1]; + _mm_mask_storeu_epi64 (tmp, 2, x4a); + x4 = tmp[1]; + + + // Absorb rest of C + while(rem_mac_bytes>=0){ + tmpc_mac[1] = 0; + u8 *lane8 = (u8 *)&tmpc_mac[1]; + for (u32 i = 0; i < 8; i++) { + if(i<(rem_mac_bytes)){ + lane8[i] = c[idx8_mac]; + idx8_mac++; + } else if(i==rem_mac_bytes){ + lane8[i] = 0x80; + } else { + lane8[i] = 0x00; + } + } + x0 ^= U64BIG(tmpc_mac[1]); + P12; + rem_mac_bytes -= ISAP_rH_SZ; + } + + + // Derive K* + state_mac64[0] = U64BIG(x0); + state_mac64[1] = U64BIG(x1); + state_mac64[2] = U64BIG(x2); + state_mac64[3] = U64BIG(x3); + state_mac64[4] = U64BIG(x4); + isap_rk(k,ISAP_IV2,(u8 *)state_mac64,CRYPTO_KEYBYTES,(u8 *)state_mac64,CRYPTO_KEYBYTES); + x0 = U64BIG(state_mac64[0]); + x1 = U64BIG(state_mac64[1]); + x2 = U64BIG(state_mac64[2]); + x3 = U64BIG(state_mac64[3]); + x4 = U64BIG(state_mac64[4]); + + // Squeeze tag + P12; + unsigned long long *tag64 = (u64 *)tag; + tag64[0] = U64BIG(x0); + tag64[1] = U64BIG(x1); +} diff --git a/isap/Implementations/crypto_aead/isapa128av20/avx_512/isap.h b/isap/Implementations/crypto_aead/isapa128av20/avx_512/isap.h new file mode 100644 index 0000000..4b4be44 --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/avx_512/isap.h @@ -0,0 +1,62 @@ +#ifndef ISAP_H +#define ISAP_H + +// Rate in bits +#define ISAP_rH 64 +#define ISAP_rB 1 + +// Number of rounds +#define ISAP_sH 12 +#define ISAP_sB 1 +#define ISAP_sE 6 +#define ISAP_sK 12 + +// State size in bytes +#define ISAP_STATE_SZ 40 + +// Size of rate in bytes +#define ISAP_rH_SZ ((ISAP_rH+7)/8) + +// Size of zero truncated IV in bytes +#define ISAP_IV_SZ 8 + +// Size of tag in bytes +#define ISAP_TAG_SZ 16 + +// Security level +#define ISAP_K 128 + +void isap_mac( + const unsigned char *k, + const unsigned char *npub, + const unsigned char *ad, const unsigned long long adlen, + const unsigned char *c, const unsigned long long clen, + unsigned char *tag +); + +void isap_mac_enc( + const unsigned char *k, + const unsigned char *npub, + const unsigned char *ad, const unsigned long long adlen, + unsigned char *c, const unsigned long long clen, + const unsigned char *m, const unsigned long long mlen, + unsigned char *tag +); + +void isap_rk( + const unsigned char *k, + const unsigned char *iv, + const unsigned char *in, + const unsigned long long inlen, + unsigned char *out, + const unsigned long long outlen +); + +void isap_enc( + const unsigned char *k, + const unsigned char *npub, + const unsigned char *m, const unsigned long long mlen, + unsigned char *c +); + +#endif diff --git a/isap/Implementations/crypto_aead/isapa128av20/bi_32/api.h b/isap/Implementations/crypto_aead/isapa128av20/bi_32/api.h new file mode 100644 index 0000000..83ebf98 --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/bi_32/api.h @@ -0,0 +1,16 @@ +#ifndef API_H +#define API_H + +// isapa128a +#define CRYPTO_KEYBYTES 16 +#define CRYPTO_NSECBYTES 0 +#define CRYPTO_NPUBBYTES 16 +#define CRYPTO_ABYTES 16 +#define CRYPTO_NOOVERLAP 1 + +// asconhashv12 +#define CRYPTO_BYTES 32 +#define ASCON_HASH_OUTLEN 32 +#define ASCON_HASH_ROUNDS 12 + +#endif diff --git a/isap/Implementations/crypto_aead/isapa128av20/bi_32/asconp.h b/isap/Implementations/crypto_aead/isapa128av20/bi_32/asconp.h new file mode 100644 index 0000000..2adb7c4 --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/bi_32/asconp.h @@ -0,0 +1,182 @@ +#ifndef ASCONP_H_ +#define ASCONP_H_ + +#include +#include "forceinline.h" + +typedef union +{ + uint64_t x; + uint32_t w[2]; + uint8_t b[8]; +} lane_t; + +typedef union +{ + lane_t l[5]; + uint64_t x[5]; + uint32_t w[5][2]; + uint8_t b[5][8]; +} state_t; + +/* ---------------------------------------------------------------- */ + +#define P_sH P12ROUNDS(s) +#define P_sB P1ROUNDS(s) +#define P_sE P6ROUNDS(s) +#define P_sK P12ROUNDS(s) + +/* ---------------------------------------------------------------- */ + +#define U64TOWORD(x) to_bit_interleaving(U64BIG(x)) +#define WORDTOU64(x) U64BIG(from_bit_interleaving(x)) + +/* ---------------------------------------------------------------- */ + +#define TOBI(x) to_bit_interleaving(x) +#define FROMBI(x) from_bit_interleaving(x) + +/* ---------------------------------------------------------------- */ + +forceinline lane_t U64BIG(lane_t x) +{ + x.x = ((((x.x) & 0x00000000000000FFULL) << 56) | (((x.x) & 0x000000000000FF00ULL) << 40) | + (((x.x) & 0x0000000000FF0000ULL) << 24) | (((x.x) & 0x00000000FF000000ULL) << 8) | + (((x.x) & 0x000000FF00000000ULL) >> 8) | (((x.x) & 0x0000FF0000000000ULL) >> 24) | + (((x.x) & 0x00FF000000000000ULL) >> 40) | (((x.x) & 0xFF00000000000000ULL) >> 56)); + return x; +} + +/* ---------------------------------------------------------------- */ + +// Credit to Henry S. Warren, Hacker's Delight, Addison-Wesley, 2002 +forceinline lane_t to_bit_interleaving(lane_t in) +{ + uint32_t lo = in.w[0]; + uint32_t hi = in.w[1]; + uint32_t r0, r1; + r0 = (lo ^ (lo >> 1)) & 0x22222222, lo ^= r0 ^ (r0 << 1); + r0 = (lo ^ (lo >> 2)) & 0x0C0C0C0C, lo ^= r0 ^ (r0 << 2); + r0 = (lo ^ (lo >> 4)) & 0x00F000F0, lo ^= r0 ^ (r0 << 4); + r0 = (lo ^ (lo >> 8)) & 0x0000FF00, lo ^= r0 ^ (r0 << 8); + r1 = (hi ^ (hi >> 1)) & 0x22222222, hi ^= r1 ^ (r1 << 1); + r1 = (hi ^ (hi >> 2)) & 0x0C0C0C0C, hi ^= r1 ^ (r1 << 2); + r1 = (hi ^ (hi >> 4)) & 0x00F000F0, hi ^= r1 ^ (r1 << 4); + r1 = (hi ^ (hi >> 8)) & 0x0000FF00, hi ^= r1 ^ (r1 << 8); + lane_t out; + out.w[0] = (lo & 0x0000FFFF) | (hi << 16); + out.w[1] = (lo >> 16) | (hi & 0xFFFF0000); + return out; +} + +/* ---------------------------------------------------------------- */ + +// Credit to Henry S. Warren, Hacker's Delight, Addison-Wesley, 2002 +forceinline lane_t from_bit_interleaving(lane_t in) +{ + uint32_t lo = ((in).w[0] & 0x0000FFFF) | ((in).w[1] << 16); + uint32_t hi = ((in).w[0] >> 16) | ((in).w[1] & 0xFFFF0000); + uint32_t r0, r1; + r0 = (lo ^ (lo >> 8)) & 0x0000FF00, lo ^= r0 ^ (r0 << 8); + r0 = (lo ^ (lo >> 4)) & 0x00F000F0, lo ^= r0 ^ (r0 << 4); + r0 = (lo ^ (lo >> 2)) & 0x0C0C0C0C, lo ^= r0 ^ (r0 << 2); + r0 = (lo ^ (lo >> 1)) & 0x22222222, lo ^= r0 ^ (r0 << 1); + r1 = (hi ^ (hi >> 8)) & 0x0000FF00, hi ^= r1 ^ (r1 << 8); + r1 = (hi ^ (hi >> 4)) & 0x00F000F0, hi ^= r1 ^ (r1 << 4); + r1 = (hi ^ (hi >> 2)) & 0x0C0C0C0C, hi ^= r1 ^ (r1 << 2); + r1 = (hi ^ (hi >> 1)) & 0x22222222, hi ^= r1 ^ (r1 << 1); + lane_t out; + out.x = (uint64_t)hi << 32 | lo; + return out; +} + +/* ---------------------------------------------------------------- */ + +forceinline uint32_t ROR32(uint32_t x, int n) +{ + return x >> n | x << (-n & 31); +} + +/* ---------------------------------------------------------------- */ + +forceinline uint64_t ROR(uint64_t x, int n) +{ + lane_t b, a = {.x = x}; + b.w[0] = (n % 2) ? ROR32(a.w[1], (n - 1) / 2) : ROR32(a.w[0], n / 2); + b.w[1] = (n % 2) ? ROR32(a.w[0], (n + 1) / 2) : ROR32(a.w[1], n / 2); + return b.x; +} + +/* ---------------------------------------------------------------- */ + +forceinline void ROUND(state_t *s, uint64_t C) +{ + state_t t; + /* round constant */ + s->x[2] ^= C; + /* s-box layer */ + s->x[0] ^= s->x[4]; + s->x[4] ^= s->x[3]; + s->x[2] ^= s->x[1]; + t.x[0] = s->x[0] ^ (~s->x[1] & s->x[2]); + t.x[2] = s->x[2] ^ (~s->x[3] & s->x[4]); + t.x[4] = s->x[4] ^ (~s->x[0] & s->x[1]); + t.x[1] = s->x[1] ^ (~s->x[2] & s->x[3]); + t.x[3] = s->x[3] ^ (~s->x[4] & s->x[0]); + t.x[1] ^= t.x[0]; + t.x[3] ^= t.x[2]; + t.x[0] ^= t.x[4]; + /* linear layer */ + s->x[2] = t.x[2] ^ ROR(t.x[2], 6 - 1); + s->x[3] = t.x[3] ^ ROR(t.x[3], 17 - 10); + s->x[4] = t.x[4] ^ ROR(t.x[4], 41 - 7); + s->x[0] = t.x[0] ^ ROR(t.x[0], 28 - 19); + s->x[1] = t.x[1] ^ ROR(t.x[1], 61 - 39); + s->x[2] = t.x[2] ^ ROR(s->x[2], 1); + s->x[3] = t.x[3] ^ ROR(s->x[3], 10); + s->x[4] = t.x[4] ^ ROR(s->x[4], 7); + s->x[0] = t.x[0] ^ ROR(s->x[0], 19); + s->x[1] = t.x[1] ^ ROR(s->x[1], 39); + s->x[2] = ~s->x[2]; +} + +/* ---------------------------------------------------------------- */ + +forceinline void P12ROUNDS(state_t *s) +{ + ROUND(s, 0xc0000000c); + ROUND(s, 0xc00000009); + ROUND(s, 0x90000000c); + ROUND(s, 0x900000009); + ROUND(s, 0xc00000006); + ROUND(s, 0xc00000003); + ROUND(s, 0x900000006); + ROUND(s, 0x900000003); + ROUND(s, 0x60000000c); + ROUND(s, 0x600000009); + ROUND(s, 0x30000000c); + ROUND(s, 0x300000009); +} + +/* ---------------------------------------------------------------- */ + +forceinline void P6ROUNDS(state_t *s) +{ + ROUND(s, 0x900000006); + ROUND(s, 0x900000003); + ROUND(s, 0x60000000c); + ROUND(s, 0x600000009); + ROUND(s, 0x30000000c); + ROUND(s, 0x300000009); +} + +/* ---------------------------------------------------------------- */ + +forceinline void P1ROUNDS(state_t *s) +{ + ROUND(s, 0x300000009); +} + +/* ---------------------------------------------------------------- */ + +#endif // ASCONP_H diff --git a/isap/Implementations/crypto_aead/isapa128av20/bi_32/config.h b/isap/Implementations/crypto_aead/isapa128av20/bi_32/config.h new file mode 100644 index 0000000..2e1c76f --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/bi_32/config.h @@ -0,0 +1,16 @@ +#ifndef CONFIG_H +#define CONFIG_H + +#define ENABLE_HASH 0 + +#include "isap.h" + +// ISAP-A-128a +const uint8_t ISAP_IV_A[] = {0x01, ISAP_K, ISAP_rH, ISAP_rB, ISAP_sH, ISAP_sB, ISAP_sE, ISAP_sK}; +const uint8_t ISAP_IV_KA[] = {0x02, ISAP_K, ISAP_rH, ISAP_rB, ISAP_sH, ISAP_sB, ISAP_sE, ISAP_sK}; +const uint8_t ISAP_IV_KE[] = {0x03, ISAP_K, ISAP_rH, ISAP_rB, ISAP_sH, ISAP_sB, ISAP_sE, ISAP_sK}; + +// Ascon-Hash +const uint8_t ASCON_HASH_IV[] = {0x00, 0x40, 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00}; + +#endif // CONFIG_H diff --git a/isap/Implementations/crypto_aead/isapa128av20/bi_32/crypto_aead.c b/isap/Implementations/crypto_aead/isapa128av20/bi_32/crypto_aead.c new file mode 100644 index 0000000..4a9bd29 --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/bi_32/crypto_aead.c @@ -0,0 +1,61 @@ +#include "api.h" +#include "isap.h" +#include "crypto_aead.h" + +int crypto_aead_encrypt( + unsigned char *c, unsigned long long *clen, + const unsigned char *m, unsigned long long mlen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k +){ + (void)nsec; + + // Ciphertext length is mlen + tag length + *clen = mlen+ISAP_TAG_SZ; + + // Encrypt plaintext + if (mlen > 0) { + isap_enc(k,npub,m,mlen,c); + } + + // Generate tag + unsigned char *tag = c+mlen; + isap_mac(k,npub,ad,adlen,c,mlen,tag); + return 0; +} + +int crypto_aead_decrypt( + unsigned char *m, unsigned long long *mlen, + unsigned char *nsec, + const unsigned char *c, unsigned long long clen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k +){ + (void)nsec; + + // Plaintext length is clen - tag length + *mlen = clen-ISAP_TAG_SZ; + + // Generate tag + unsigned char tag[ISAP_TAG_SZ]; + isap_mac(k,npub,ad,adlen,c,*mlen,tag); + + // Compare tag + unsigned long eq_cnt = 0; + for(unsigned int i = 0; i < ISAP_TAG_SZ; i++) { + eq_cnt += (tag[i] == c[(*mlen)+i]); + } + + // Perform decryption if tag is correct + if(eq_cnt == (unsigned long)ISAP_TAG_SZ){ + if (*mlen > 0) { + isap_enc(k,npub,c,*mlen,m); + } + return 0; + } else { + return -1; + } +} diff --git a/isap/Implementations/crypto_aead/isapa128av20/bi_32/forceinline.h b/isap/Implementations/crypto_aead/isapa128av20/bi_32/forceinline.h new file mode 100644 index 0000000..ba695cb --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/bi_32/forceinline.h @@ -0,0 +1,19 @@ +#ifndef FORCEINLINE_H_ +#define FORCEINLINE_H_ + +/* define forceinline macro */ +#ifdef _MSC_VER +#define forceinline __forceinline +#elif defined(__GNUC__) +#define forceinline inline __attribute__((__always_inline__)) +#elif defined(__CLANG__) +#if __has_attribute(__always_inline__) +#define forceinline inline __attribute__((__always_inline__)) +#else +#define forceinline inline +#endif +#else +#define forceinline inline +#endif + +#endif /* FORCEINLINE_H_ */ diff --git a/isap/Implementations/crypto_aead/isapa128av20/bi_32/isap.c b/isap/Implementations/crypto_aead/isapa128av20/bi_32/isap.c new file mode 100644 index 0000000..d4009e0 --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/bi_32/isap.c @@ -0,0 +1,226 @@ +#include +#include +#include "api.h" +#include "isap.h" +#include "asconp.h" +#include "config.h" + +forceinline void ABSORB_LANES(state_t *s, const uint8_t *src, uint64_t len) +{ + while (len >= 8) + { + // Absorb full lanes + lane_t t0 = U64TOWORD(*(lane_t *)(src + 0)); + s->x[0] ^= t0.x; + len -= ISAP_rH / 8; + src += ISAP_rH / 8; + P_sH; + } + + if (len > 0) + { + // Absorb partial lane and padding + size_t i; + lane_t t0 = {0}; + for (i = 0; i < len; i++) + { + t0.b[7 - i] ^= *src; + src++; + } + t0.b[7 - i] ^= 0x80; + t0 = TOBI(t0); + s->x[0] ^= t0.x; + P_sH; + } + else + { + // Absorb padded empty lane + s->b[0][7] ^= 0x80; + P_sH; + } +} + +/******************************************************************************/ +/* ISAP_RK */ +/******************************************************************************/ + +void isap_rk( + const uint8_t *k, + const uint8_t *iv, + const uint8_t *y, + state_t *out, + const size_t outlen) +{ + state_t state; + state_t *s = &state; + + // Initialize + s->l[0] = U64TOWORD(*(lane_t *)(k + 0)); + s->l[1] = U64TOWORD(*(lane_t *)(k + 8)); + s->l[2] = U64TOWORD(*(lane_t *)(iv + 0)); + s->x[3] = 0; + s->x[4] = 0; + P_sK; + + // Absorb Y, bit by bit + for (size_t i = 0; i < 16; i++) + { + uint8_t y_byte = *y; + s->b[0][7] ^= (y_byte & 0x80) << 0; + P_sB; + s->b[0][7] ^= (y_byte & 0x40) << 1; + P_sB; + s->b[0][7] ^= (y_byte & 0x20) << 2; + P_sB; + s->b[0][7] ^= (y_byte & 0x10) << 3; + P_sB; + s->b[0][7] ^= (y_byte & 0x08) << 4; + P_sB; + s->b[0][7] ^= (y_byte & 0x04) << 5; + P_sB; + s->b[0][7] ^= (y_byte & 0x02) << 6; + P_sB; + s->b[0][7] ^= (y_byte & 0x01) << 7; + if (i != 15) + { + P_sB; + y += 1; + } + } + + // Squeeze K* + P_sK; + out->x[0] = s->x[0]; + out->x[1] = s->x[1]; + if (outlen > 16) + { + out->x[2] = s->x[2]; + } +} + +/******************************************************************************/ +/* ISAP_MAC */ +/******************************************************************************/ + +void isap_mac( + const uint8_t *k, + const uint8_t *npub, + const uint8_t *ad, uint64_t adlen, + const uint8_t *c, uint64_t clen, + uint8_t *tag) +{ + state_t state; + state_t *s = &state; + + // Initialize + s->l[0] = U64TOWORD(*(lane_t *)(npub + 0)); + s->l[1] = U64TOWORD(*(lane_t *)(npub + 8)); + s->l[2] = U64TOWORD(*(lane_t *)(ISAP_IV_A + 0)); + s->x[3] = 0; + s->x[4] = 0; + P_sH; + + // Absorb associated data + ABSORB_LANES(s, ad, adlen); + + // Domain seperation + s->w[4][0] ^= 0x1UL; + + // Absorb ciphertext + ABSORB_LANES(s, c, clen); + + // Derive KA* + s->l[0] = WORDTOU64(s->l[0]); + s->l[1] = WORDTOU64(s->l[1]); + isap_rk(k, ISAP_IV_KA, (const uint8_t *)(s->b), s, CRYPTO_KEYBYTES); + + // Squeeze tag + P_sH; + lane_t t0 = WORDTOU64(s->l[0]); + memcpy(tag + 0, t0.b, 8); + t0 = WORDTOU64(s->l[1]); + memcpy(tag + 8, t0.b, 8); +} + +/******************************************************************************/ +/* ISAP_ENC */ +/******************************************************************************/ + +void isap_enc( + const uint8_t *k, + const uint8_t *npub, + const uint8_t *m, uint64_t mlen, + uint8_t *c) + +{ + state_t state; + state_t *s = &state; + + // Init state + isap_rk(k, ISAP_IV_KE, npub, s, ISAP_STATE_SZ - CRYPTO_NPUBBYTES); + s->l[3] = U64TOWORD(*(lane_t *)(npub + 0)); + s->l[4] = U64TOWORD(*(lane_t *)(npub + 8)); + + while (mlen >= ISAP_rH / 8) + { + // Encrypt full lanes + P_sE; + lane_t t0 = WORDTOU64(s->l[0]); + *(uint64_t *)c = *(uint64_t *)m ^ t0.x; + mlen -= ISAP_rH / 8; + m += ISAP_rH / 8; + c += ISAP_rH / 8; + } + + if (mlen > 0) + { + // Encrypt partial lanes + P_sE; + lane_t t0 = WORDTOU64(s->l[0]); + for (uint8_t i = 0; i < mlen; i++) + { + *c = *m ^ t0.b[i]; + m += 1; + c += 1; + } + } +} + +/******************************************************************************/ +/* Ascon-Hash */ +/******************************************************************************/ + +#if ENABLE_HASH == 1 + +int crypto_hash(uint8_t *out, const uint8_t *in, unsigned long long inlen) +{ + + state_t state; + state_t *s = &state; + + // Initialize + s->l[0] = U64TOWORD(*(lane_t *)(ASCON_HASH_IV + 0)); + s->x[1] = 0; + s->x[2] = 0; + s->x[3] = 0; + s->x[4] = 0; + P_sH; + + // Absorb input + ABSORB_LANES(s, in, inlen); + + for (size_t i = 0; i < 4; i++) + { + // Squeeze full lanes + lane_t t0 = WORDTOU64(s->l[0]); + *(uint64_t *)(out + 8 * i) = t0.x; + if (i < 3) + { + P_sH; + } + } + + return 0; +} + +#endif diff --git a/isap/Implementations/crypto_aead/isapa128av20/bi_32/isap.h b/isap/Implementations/crypto_aead/isapa128av20/bi_32/isap.h new file mode 100644 index 0000000..abec1ca --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/bi_32/isap.h @@ -0,0 +1,44 @@ +#ifndef ISAP_H +#define ISAP_H + +#include + +// Rate in bits +#define ISAP_rH 64 +#define ISAP_rB 1 + +// Number of rounds +#define ISAP_sH 12 +#define ISAP_sB 1 +#define ISAP_sE 6 +#define ISAP_sK 12 + +// State size in bytes +#define ISAP_STATE_SZ 40 + +// Size of rate in bytes +#define ISAP_rH_SZ ((ISAP_rH + 7) / 8) + +// Size of zero truncated IV in bytes +#define ISAP_IV_SZ 8 + +// Size of tag in bytes +#define ISAP_TAG_SZ 16 + +// Security level +#define ISAP_K 128 + +void isap_mac( + const uint8_t *k, + const uint8_t *npub, + const uint8_t *ad, const uint64_t adlen, + const uint8_t *c, const uint64_t clen, + uint8_t *tag); + +void isap_enc( + const uint8_t *k, + const uint8_t *npub, + const uint8_t *m, const uint64_t mlen, + uint8_t *c); + +#endif diff --git a/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6/api.h b/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6/api.h new file mode 120000 index 0000000..ee9607d --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6/api.h @@ -0,0 +1 @@ +../bi_32/api.h \ No newline at end of file diff --git a/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6/asconp.h b/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6/asconp.h new file mode 100644 index 0000000..8bde1c4 --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6/asconp.h @@ -0,0 +1,206 @@ +#ifndef ASCONP_H_ +#define ASCONP_H_ + +#include +#include "forceinline.h" + +typedef union +{ + uint64_t x; + uint32_t w[2]; + uint8_t b[8]; +} lane_t; + +typedef union +{ + lane_t l[5]; + uint64_t x[5]; + uint32_t w[5][2]; + uint8_t b[5][8]; +} state_t; + +/* ---------------------------------------------------------------- */ + +#define P_sH P12ROUNDS(s) +#define P_sB P1ROUNDS(s) +#define P_sE P6ROUNDS(s) +#define P_sK P12ROUNDS(s) + +/* ---------------------------------------------------------------- */ + +#define U64TOWORD(x) to_bit_interleaving(U64BIG(x)) +#define WORDTOU64(x) U64BIG(from_bit_interleaving(x)) + +/* ---------------------------------------------------------------- */ + +#define TOBI(x) to_bit_interleaving(x) +#define FROMBI(x) from_bit_interleaving(x) + +/* ---------------------------------------------------------------- */ + +forceinline lane_t U64BIG(lane_t x) +{ + x.x = ((((x.x) & 0x00000000000000FFULL) << 56) | (((x.x) & 0x000000000000FF00ULL) << 40) | + (((x.x) & 0x0000000000FF0000ULL) << 24) | (((x.x) & 0x00000000FF000000ULL) << 8) | + (((x.x) & 0x000000FF00000000ULL) >> 8) | (((x.x) & 0x0000FF0000000000ULL) >> 24) | + (((x.x) & 0x00FF000000000000ULL) >> 40) | (((x.x) & 0xFF00000000000000ULL) >> 56)); + return x; +} + +/* ---------------------------------------------------------------- */ + +// Credit to Henry S. Warren, Hacker's Delight, Addison-Wesley, 2002 +forceinline lane_t to_bit_interleaving(lane_t in) +{ + uint32_t lo = in.w[0]; + uint32_t hi = in.w[1]; + uint32_t r0, r1; + r0 = (lo ^ (lo >> 1)) & 0x22222222, lo ^= r0 ^ (r0 << 1); + r0 = (lo ^ (lo >> 2)) & 0x0C0C0C0C, lo ^= r0 ^ (r0 << 2); + r0 = (lo ^ (lo >> 4)) & 0x00F000F0, lo ^= r0 ^ (r0 << 4); + r0 = (lo ^ (lo >> 8)) & 0x0000FF00, lo ^= r0 ^ (r0 << 8); + r1 = (hi ^ (hi >> 1)) & 0x22222222, hi ^= r1 ^ (r1 << 1); + r1 = (hi ^ (hi >> 2)) & 0x0C0C0C0C, hi ^= r1 ^ (r1 << 2); + r1 = (hi ^ (hi >> 4)) & 0x00F000F0, hi ^= r1 ^ (r1 << 4); + r1 = (hi ^ (hi >> 8)) & 0x0000FF00, hi ^= r1 ^ (r1 << 8); + lane_t out; + out.w[0] = (lo & 0x0000FFFF) | (hi << 16); + out.w[1] = (lo >> 16) | (hi & 0xFFFF0000); + return out; +} + +/* ---------------------------------------------------------------- */ + +// Credit to Henry S. Warren, Hacker's Delight, Addison-Wesley, 2002 +forceinline lane_t from_bit_interleaving(lane_t in) +{ + uint32_t lo = ((in).w[0] & 0x0000FFFF) | ((in).w[1] << 16); + uint32_t hi = ((in).w[0] >> 16) | ((in).w[1] & 0xFFFF0000); + uint32_t r0, r1; + r0 = (lo ^ (lo >> 8)) & 0x0000FF00, lo ^= r0 ^ (r0 << 8); + r0 = (lo ^ (lo >> 4)) & 0x00F000F0, lo ^= r0 ^ (r0 << 4); + r0 = (lo ^ (lo >> 2)) & 0x0C0C0C0C, lo ^= r0 ^ (r0 << 2); + r0 = (lo ^ (lo >> 1)) & 0x22222222, lo ^= r0 ^ (r0 << 1); + r1 = (hi ^ (hi >> 8)) & 0x0000FF00, hi ^= r1 ^ (r1 << 8); + r1 = (hi ^ (hi >> 4)) & 0x00F000F0, hi ^= r1 ^ (r1 << 4); + r1 = (hi ^ (hi >> 2)) & 0x0C0C0C0C, hi ^= r1 ^ (r1 << 2); + r1 = (hi ^ (hi >> 1)) & 0x22222222, hi ^= r1 ^ (r1 << 1); + lane_t out; + out.x = (uint64_t)hi << 32 | lo; + return out; +} + +/* ---------------------------------------------------------------- */ + +forceinline void ROUND(state_t *s, uint64_t C) +{ + uint32_t tmp0, tmp1; + __asm__ __volatile__( + "eor %[x0_e], %[x0_e], %[x4_e]\n\t" + "eor %[x4_e], %[x4_e], %[x3_e]\n\t" + "eor %[x2_e], %[x2_e], %[x1_e]\n\t" + "mvn %[tmp0], %[x0_e]\n\t" + "orr %[tmp0], %[x4_e], %[tmp0]\n\t" + "eor %[x2_e], %[x2_e], %[C_e]\n\t" + "bic %[tmp1], %[x2_e], %[x1_e]\n\t" + "eor %[x0_e], %[x0_e], %[tmp1]\n\t" + "mvn %[tmp1], %[x4_e]\n\t" + "orr %[tmp1], %[x3_e], %[tmp1]\n\t" + "eor %[x2_e], %[x2_e], %[tmp1]\n\t" + "bic %[tmp1], %[x1_e], %[x0_e]\n\t" + "eor %[x4_e], %[x4_e], %[tmp1]\n\t" + "and %[tmp1], %[x3_e], %[x2_e]\n\t" + "eor %[x1_e], %[x1_e], %[tmp1]\n\t" + "eor %[x3_e], %[x3_e], %[tmp0]\n\t" + "eor %[x1_e], %[x1_e], %[x0_e]\n\t" + "eor %[x3_e], %[x3_e], %[x2_e]\n\t" + "eor %[x0_e], %[x0_e], %[x4_e]\n\t" + "eor %[x0_o], %[x0_o], %[x4_o]\n\t" + "eor %[x4_o], %[x4_o], %[x3_o]\n\t" + "eor %[x2_o], %[x2_o], %[C_o]\n\t" + "eor %[x2_o], %[x2_o], %[x1_o]\n\t" + "mvn %[tmp0], %[x0_o]\n\t" + "orr %[tmp0], %[x4_o], %[tmp0]\n\t" + "bic %[tmp1], %[x2_o], %[x1_o]\n\t" + "eor %[x0_o], %[x0_o], %[tmp1]\n\t" + "mvn %[tmp1], %[x4_o]\n\t" + "orr %[tmp1], %[x3_o], %[tmp1]\n\t" + "eor %[x2_o], %[x2_o], %[tmp1]\n\t" + "bic %[tmp1], %[x1_o], %[x0_o]\n\t" + "eor %[x4_o], %[x4_o], %[tmp1]\n\t" + "and %[tmp1], %[x3_o], %[x2_o]\n\t" + "eor %[x1_o], %[x1_o], %[tmp1]\n\t" + "eor %[x3_o], %[x3_o], %[tmp0]\n\t" + "eor %[x1_o], %[x1_o], %[x0_o]\n\t" + "eor %[x3_o], %[x3_o], %[x2_o]\n\t" + "eor %[x0_o], %[x0_o], %[x4_o]\n\t" + "eor %[tmp0], %[x0_e], %[x0_o], ror #4\n\t" + "eor %[tmp1], %[x0_o], %[x0_e], ror #5\n\t" + "eor %[x0_o], %[x0_o], %[tmp0], ror #10\n\t" + "eor %[x0_e], %[x0_e], %[tmp1], ror #9\n\t" + "eor %[tmp0], %[x1_e], %[x1_e], ror #11\n\t" + "eor %[tmp1], %[x1_o], %[x1_o], ror #11\n\t" + "eor %[x1_o], %[x1_o], %[tmp0], ror #20\n\t" + "eor %[x1_e], %[x1_e], %[tmp1], ror #19\n\t" + "eor %[tmp0], %[x2_e], %[x2_o], ror #2\n\t" + "eor %[tmp1], %[x2_o], %[x2_e], ror #3\n\t" + "eor %[x2_o], %[x2_o], %[tmp0], ror #1\n\t" + "eor %[x2_e], %[x2_e], %[tmp1]\n\t" + "eor %[tmp0], %[x3_e], %[x3_o], ror #3\n\t" + "eor %[tmp1], %[x3_o], %[x3_e], ror #4\n\t" + "eor %[x3_e], %[x3_e], %[tmp0], ror #5\n\t" + "eor %[x3_o], %[x3_o], %[tmp1], ror #5\n\t" + "eor %[tmp0], %[x4_e], %[x4_e], ror #17\n\t" + "eor %[tmp1], %[x4_o], %[x4_o], ror #17\n\t" + "eor %[x4_o], %[x4_o], %[tmp0], ror #4\n\t" + "eor %[x4_e], %[x4_e], %[tmp1], ror #3\n\t" + : [x0_e] "+r"(s->w[0][0]), [x0_o] "+r"(s->w[0][1]), + [x1_e] "+r"(s->w[1][0]), [x1_o] "+r"(s->w[1][1]), + [x2_e] "+r"(s->w[2][0]), [x2_o] "+r"(s->w[2][1]), + [x3_e] "+r"(s->w[3][0]), [x3_o] "+r"(s->w[3][1]), + [x4_e] "+r"(s->w[4][0]), [x4_o] "+r"(s->w[4][1]), [tmp0] "=r"(tmp0), + [tmp1] "=r"(tmp1) + : [C_e] "i"((uint32_t)C), [C_o] "i"((uint32_t)(C >> 32)) + :); +} + +/* ---------------------------------------------------------------- */ + +forceinline void P12ROUNDS(state_t *s) +{ + ROUND(s, 0xc0000000c); + ROUND(s, 0xc00000009); + ROUND(s, 0x90000000c); + ROUND(s, 0x900000009); + ROUND(s, 0xc00000006); + ROUND(s, 0xc00000003); + ROUND(s, 0x900000006); + ROUND(s, 0x900000003); + ROUND(s, 0x60000000c); + ROUND(s, 0x600000009); + ROUND(s, 0x30000000c); + ROUND(s, 0x300000009); +} + +/* ---------------------------------------------------------------- */ + +forceinline void P6ROUNDS(state_t *s) +{ + ROUND(s, 0x900000006); + ROUND(s, 0x900000003); + ROUND(s, 0x60000000c); + ROUND(s, 0x600000009); + ROUND(s, 0x30000000c); + ROUND(s, 0x300000009); +} + +/* ---------------------------------------------------------------- */ + +forceinline void P1ROUNDS(state_t *s) +{ + ROUND(s, 0x300000009); +} + +/* ---------------------------------------------------------------- */ + +#endif // ASCONP_H_ diff --git a/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6/config.h b/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6/config.h new file mode 100644 index 0000000..2e1c76f --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6/config.h @@ -0,0 +1,16 @@ +#ifndef CONFIG_H +#define CONFIG_H + +#define ENABLE_HASH 0 + +#include "isap.h" + +// ISAP-A-128a +const uint8_t ISAP_IV_A[] = {0x01, ISAP_K, ISAP_rH, ISAP_rB, ISAP_sH, ISAP_sB, ISAP_sE, ISAP_sK}; +const uint8_t ISAP_IV_KA[] = {0x02, ISAP_K, ISAP_rH, ISAP_rB, ISAP_sH, ISAP_sB, ISAP_sE, ISAP_sK}; +const uint8_t ISAP_IV_KE[] = {0x03, ISAP_K, ISAP_rH, ISAP_rB, ISAP_sH, ISAP_sB, ISAP_sE, ISAP_sK}; + +// Ascon-Hash +const uint8_t ASCON_HASH_IV[] = {0x00, 0x40, 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00}; + +#endif // CONFIG_H diff --git a/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6/crypto_aead.c b/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6/crypto_aead.c new file mode 120000 index 0000000..e4f019c --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6/crypto_aead.c @@ -0,0 +1 @@ +../bi_32/crypto_aead.c \ No newline at end of file diff --git a/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6/forceinline.h b/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6/forceinline.h new file mode 120000 index 0000000..c156e37 --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6/forceinline.h @@ -0,0 +1 @@ +../bi_32/forceinline.h \ No newline at end of file diff --git a/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6/isap.c b/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6/isap.c new file mode 120000 index 0000000..9b7816c --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6/isap.c @@ -0,0 +1 @@ +../bi_32/isap.c \ No newline at end of file diff --git a/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6/isap.h b/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6/isap.h new file mode 120000 index 0000000..6175b4f --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6/isap.h @@ -0,0 +1 @@ +../bi_32/isap.h \ No newline at end of file diff --git a/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m/api.h b/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m/api.h new file mode 120000 index 0000000..ee9607d --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m/api.h @@ -0,0 +1 @@ +../bi_32/api.h \ No newline at end of file diff --git a/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m/asconp.h b/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m/asconp.h new file mode 100644 index 0000000..0e9b69b --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m/asconp.h @@ -0,0 +1,285 @@ +#ifndef ASCONP_H_ +#define ASCONP_H_ + +#include +#include "forceinline.h" + +typedef union +{ + uint64_t x; + uint32_t w[2]; + uint8_t b[8]; +} lane_t; + +typedef union +{ + lane_t l[5]; + uint64_t x[5]; + uint32_t w[5][2]; + uint8_t b[5][8]; +} state_t; + +/* ---------------------------------------------------------------- */ + +#define P_sH P12ROUNDS(s) +#define P_sB P1ROUNDS(s) +#define P_sE P6ROUNDS(s) +#define P_sK P12ROUNDS(s) + +/* ---------------------------------------------------------------- */ + +#define U64TOWORD(x) to_bit_interleaving(U64BIG(x)) +#define WORDTOU64(x) U64BIG(from_bit_interleaving(x)) + +/* ---------------------------------------------------------------- */ + +#define TOBI(x) to_bit_interleaving(x) +#define FROMBI(x) from_bit_interleaving(x) + +/* ---------------------------------------------------------------- */ + +forceinline lane_t U64BIG(lane_t x) +{ + x.x = ((((x.x) & 0x00000000000000FFULL) << 56) | (((x.x) & 0x000000000000FF00ULL) << 40) | + (((x.x) & 0x0000000000FF0000ULL) << 24) | (((x.x) & 0x00000000FF000000ULL) << 8) | + (((x.x) & 0x000000FF00000000ULL) >> 8) | (((x.x) & 0x0000FF0000000000ULL) >> 24) | + (((x.x) & 0x00FF000000000000ULL) >> 40) | (((x.x) & 0xFF00000000000000ULL) >> 56)); + return x; +} + +/* ---------------------------------------------------------------- */ + +// Credit to Henry S. Warren, Hacker's Delight, Addison-Wesley, 2002 +forceinline lane_t to_bit_interleaving(lane_t in) +{ + uint32_t lo = in.w[0]; + uint32_t hi = in.w[1]; + uint32_t r0, r1; + r0 = (lo ^ (lo >> 1)) & 0x22222222, lo ^= r0 ^ (r0 << 1); + r0 = (lo ^ (lo >> 2)) & 0x0C0C0C0C, lo ^= r0 ^ (r0 << 2); + r0 = (lo ^ (lo >> 4)) & 0x00F000F0, lo ^= r0 ^ (r0 << 4); + r0 = (lo ^ (lo >> 8)) & 0x0000FF00, lo ^= r0 ^ (r0 << 8); + r1 = (hi ^ (hi >> 1)) & 0x22222222, hi ^= r1 ^ (r1 << 1); + r1 = (hi ^ (hi >> 2)) & 0x0C0C0C0C, hi ^= r1 ^ (r1 << 2); + r1 = (hi ^ (hi >> 4)) & 0x00F000F0, hi ^= r1 ^ (r1 << 4); + r1 = (hi ^ (hi >> 8)) & 0x0000FF00, hi ^= r1 ^ (r1 << 8); + lane_t out; + out.w[0] = (lo & 0x0000FFFF) | (hi << 16); + out.w[1] = (lo >> 16) | (hi & 0xFFFF0000); + return out; +} + +/* ---------------------------------------------------------------- */ + +// Credit to Henry S. Warren, Hacker's Delight, Addison-Wesley, 2002 +forceinline lane_t from_bit_interleaving(lane_t in) +{ + uint32_t lo = ((in).w[0] & 0x0000FFFF) | ((in).w[1] << 16); + uint32_t hi = ((in).w[0] >> 16) | ((in).w[1] & 0xFFFF0000); + uint32_t r0, r1; + r0 = (lo ^ (lo >> 8)) & 0x0000FF00, lo ^= r0 ^ (r0 << 8); + r0 = (lo ^ (lo >> 4)) & 0x00F000F0, lo ^= r0 ^ (r0 << 4); + r0 = (lo ^ (lo >> 2)) & 0x0C0C0C0C, lo ^= r0 ^ (r0 << 2); + r0 = (lo ^ (lo >> 1)) & 0x22222222, lo ^= r0 ^ (r0 << 1); + r1 = (hi ^ (hi >> 8)) & 0x0000FF00, hi ^= r1 ^ (r1 << 8); + r1 = (hi ^ (hi >> 4)) & 0x00F000F0, hi ^= r1 ^ (r1 << 4); + r1 = (hi ^ (hi >> 2)) & 0x0C0C0C0C, hi ^= r1 ^ (r1 << 2); + r1 = (hi ^ (hi >> 1)) & 0x22222222, hi ^= r1 ^ (r1 << 1); + lane_t out; + out.x = (uint64_t)hi << 32 | lo; + return out; +} + +/* ---------------------------------------------------------------- */ + +forceinline void ROUND(state_t *s, uint64_t C) +{ + uint32_t tmp0, tmp1, tmp2; + __asm__ __volatile__( + "@.syntax_unified\n\t" + "movs %[tmp1], %[C_e]\n\t" + "eor %[x2_e], %[x2_e], %[tmp1]\n\t" + "eor %[x0_e], %[x0_e], %[x4_e]\n\t" + "eor %[x4_e], %[x4_e], %[x3_e]\n\t" + "eor %[x2_e], %[x2_e], %[x1_e]\n\t" + "movs %[tmp0], %[x0_e]\n\t" + "bic %[tmp0], %[tmp0], %[x4_e]\n\t" + "movs %[tmp1], %[x2_e]\n\t" + "bic %[tmp1], %[tmp1], %[x1_e]\n\t" + "eor %[x0_e], %[x0_e], %[tmp1]\n\t" + "movs %[tmp1], %[x4_e]\n\t" + "bic %[tmp1], %[tmp1], %[x3_e]\n\t" + "eor %[x2_e], %[x2_e], %[tmp1]\n\t" + "movs %[tmp2], %[x1_e]\n\t" + "bic %[tmp2], %[tmp2], %[x0_e]\n\t" + "eor %[tmp2], %[x4_e], %[tmp2]\n\t" + "movs %[tmp1], %[x3_e]\n\t" + "bic %[tmp1], %[tmp1], %[x2_e]\n\t" + "eor %[tmp1], %[x1_e], %[tmp1]\n\t" + "eor %[tmp0], %[x3_e], %[tmp0]\n\t" + "eor %[tmp0], %[tmp0], %[x2_e]\n\t" + "eor %[tmp1], %[tmp1], %[x0_e]\n\t" + "eor %[x0_e], %[x0_e], %[tmp2]\n\t" + "movs %[x4_e], %[x4_o]\n\t" + "movs %[x1_e], %[x1_o]\n\t" + "movs %[x3_e], %[x3_o]\n\t" + "movs %[x3_o], %[tmp0]\n\t" + "movs %[x1_o], %[tmp1]\n\t" + "movs %[tmp0], %[x0_o]\n\t" + "movs %[tmp1], %[x2_o]\n\t" + "movs %[x0_o], %[x0_e]\n\t" + "movs %[x2_o], %[x2_e]\n\t" + "movs %[x0_e], %[C_o]\n\t" + "eor %[tmp1], %[tmp1], %[x0_e]\n\t" + "eor %[tmp0], %[tmp0], %[x4_e]\n\t" + "eor %[x4_e], %[x4_e], %[x3_e]\n\t" + "eor %[tmp1], %[tmp1], %[x1_e]\n\t" + "movs %[x0_e], %[tmp0] \n\t" + "bic %[x0_e], %[x0_e], %[x4_e]\n\t" + "movs %[x2_e], %[tmp1] \n\t" + "bic %[x2_e], %[x2_e], %[x1_e]\n\t" + "eor %[tmp0], %[tmp0], %[x2_e]\n\t" + "movs %[x2_e], %[x4_e] \n\t" + "bic %[x2_e], %[x2_e], %[x3_e]\n\t" + "eor %[tmp1], %[tmp1], %[x2_e]\n\t" + "movs %[x2_e], %[x1_e]\n\t" + "bic %[x2_e], %[x2_e], %[tmp0]\n\t" + "eor %[x4_e], %[x4_e], %[x2_e]\n\t" + "movs %[x2_e], %[x3_e] \n\t" + "bic %[x2_e], %[x2_e], %[tmp1]\n\t" + "eor %[x1_e], %[x1_e], %[x2_e]\n\t" + "eor %[x3_e], %[x3_e], %[x0_e]\n\t" + "eor %[x3_e], %[x3_e], %[tmp1]\n\t" + "eor %[x1_e], %[x1_e], %[tmp0]\n\t" + "eor %[tmp0], %[tmp0], %[x4_e]\n\t" + "movs %[x4_o], %[tmp1]\n\t" + "movs %[x2_e], %[x3_o]\n\t" + "movs %[x3_o], %[x1_e]\n\t" + "movs %[tmp1], #17\n\t" + "movs %[x0_e], %[tmp2]\n\t" + "ror %[x0_e], %[x0_e], %[tmp1]\n\t" + "eor %[x0_e], %[tmp2], %[x0_e]\n\t" + "movs %[x1_e], %[x4_e]\n\t" + "ror %[x1_e], %[x1_e], %[tmp1]\n\t" + "eor %[x1_e], %[x4_e], %[x1_e]\n\t" + "movs %[tmp1], #3\n\t" + "ror %[x1_e], %[x1_e], %[tmp1]\n\t" + "eor %[tmp2], %[tmp2], %[x1_e]\n\t" + "movs %[tmp1], #4\n\t" + "ror %[x0_e], %[x0_e], %[tmp1]\n\t" + "eor %[x4_e], %[x4_e], %[x0_e]\n\t" + "movs %[x1_e], %[x2_e]\n\t" + "ror %[x1_e], %[x1_e], %[tmp1]\n\t" + "eor %[x1_e], %[x3_e], %[x1_e]\n\t" + "movs %[tmp1], #3\n\t" + "movs %[x0_e], %[x3_e]\n\t" + "ror %[x0_e], %[x0_e], %[tmp1]\n\t" + "eor %[x0_e], %[x2_e], %[x0_e]\n\t" + "movs %[tmp1], #5\n\t" + "ror %[x0_e], %[x0_e], %[tmp1]\n\t" + "eor %[x2_e], %[x2_e], %[x0_e]\n\t" + "ror %[x1_e], %[x1_e], %[tmp1]\n\t" + "eor %[x3_e], %[x3_e], %[x1_e]\n\t" + "movs %[x0_e], %[x0_o]\n\t" + "movs %[x1_e], %[x1_o]\n\t" + "movs %[x1_o], %[x2_e]\n\t" + "movs %[x0_o], %[tmp2]\n\t" + "movs %[tmp2], %[x4_o]\n\t" + "movs %[x4_o], %[x4_e]\n\t" + "movs %[x4_e], %[x3_o]\n\t" + "movs %[x3_o], %[x3_e]\n\t" + "movs %[x3_e], %[x0_e]\n\t" + "ror %[x3_e], %[x3_e], %[tmp1]\n\t" + "eor %[x3_e], %[tmp0], %[x3_e]\n\t" + "movs %[tmp1], #4\n\t" + "movs %[x2_e], %[tmp0]\n\t" + "ror %[x2_e], %[x2_e], %[tmp1]\n\t" + "eor %[x2_e], %[x0_e], %[x2_e]\n\t" + "movs %[tmp1], #9\n\t" + "ror %[x3_e], %[x3_e], %[tmp1]\n\t" + "eor %[x0_e], %[x0_e], %[x3_e]\n\t" + "movs %[tmp1], #10\n\t" + "ror %[x2_e], %[x2_e], %[tmp1]\n\t" + "eor %[tmp0], %[tmp0], %[x2_e]\n\t" + "movs %[tmp1], #11\n\t" + "movs %[x2_e], %[x1_e]\n\t" + "ror %[x2_e], %[x2_e], %[tmp1]\n\t" + "eor %[x2_e], %[x1_e], %[x2_e]\n\t" + "movs %[x3_e], %[x4_e]\n\t" + "ror %[x3_e], %[x3_e], %[tmp1]\n\t" + "eor %[x3_e], %[x4_e], %[x3_e]\n\t" + "movs %[tmp1], #19\n\t" + "ror %[x3_e], %[x3_e], %[tmp1]\n\t" + "eor %[x1_e], %[x1_e], %[x3_e]\n\t" + "movs %[tmp1], #20\n\t" + "ror %[x2_e], %[x2_e], %[tmp1]\n\t" + "eor %[x4_e], %[x4_e], %[x2_e]\n\t" + "movs %[x2_e], %[x2_o]\n\t" + "movs %[x3_e], %[x1_o]\n\t" + "movs %[x1_o], %[x4_e]\n\t" + "movs %[x2_o], %[tmp0]\n\t" + "movs %[x4_e], #2\n\t" + "mvn %[tmp0], %[tmp2]\n\t" + "ror %[tmp0], %[tmp0], %[x4_e]\n\t" + "eor %[tmp0], %[x2_e], %[tmp0]\n\t" + "movs %[x4_e], #3\n\t" + "mvn %[tmp1], %[x2_e]\n\t" + "ror %[tmp1], %[tmp1], %[x4_e]\n\t" + "eor %[tmp1], %[tmp2], %[tmp1]\n\t" + "eor %[x2_e], %[x2_e], %[tmp1]\n\t" + "movs %[x4_e], #1\n\t" + "ror %[tmp0], %[tmp0], %[x4_e]\n\t" + "eor %[tmp2], %[tmp2], %[tmp0]\n\t" + "movs %[x4_e], %[x0_o]\n\t" + "movs %[x0_o], %[x2_o]\n\t" + "movs %[x2_o], %[tmp2]\n\t" + : [x0_e] "+l"(s->w[0][0]), [x1_e] "+l"(s->w[1][0]), + [x2_e] "+l"(s->w[2][0]), [x3_e] "+l"(s->w[3][0]), + [x4_e] "+l"(s->w[4][0]), [x0_o] "+r"(s->w[0][1]), + [x1_o] "+r"(s->w[1][1]), [x2_o] "+r"(s->w[2][1]), + [x3_o] "+r"(s->w[3][1]), [x4_o] "+r"(s->w[4][1]), + [tmp0] "=l"(tmp0), [tmp1] "=l"(tmp1), [tmp2] "=l"(tmp2) + : [C_e] "ri"((uint32_t)C), [C_o] "ri"((uint32_t)(C >> 32)) + :); +} + +/* ---------------------------------------------------------------- */ + +forceinline void P12ROUNDS(state_t *s) +{ + ROUND(s, 0xc0000000c); + ROUND(s, 0xc00000009); + ROUND(s, 0x90000000c); + ROUND(s, 0x900000009); + ROUND(s, 0xc00000006); + ROUND(s, 0xc00000003); + ROUND(s, 0x900000006); + ROUND(s, 0x900000003); + ROUND(s, 0x60000000c); + ROUND(s, 0x600000009); + ROUND(s, 0x30000000c); + ROUND(s, 0x300000009); +} + +/* ---------------------------------------------------------------- */ + +forceinline void P6ROUNDS(state_t *s) +{ + ROUND(s, 0x900000006); + ROUND(s, 0x900000003); + ROUND(s, 0x60000000c); + ROUND(s, 0x600000009); + ROUND(s, 0x30000000c); + ROUND(s, 0x300000009); +} + +/* ---------------------------------------------------------------- */ + +forceinline void P1ROUNDS(state_t *s) +{ + ROUND(s, 0x300000009); +} + +/* ---------------------------------------------------------------- */ + +#endif // ASCONP_H_ diff --git a/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m/config.h b/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m/config.h new file mode 100644 index 0000000..2e1c76f --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m/config.h @@ -0,0 +1,16 @@ +#ifndef CONFIG_H +#define CONFIG_H + +#define ENABLE_HASH 0 + +#include "isap.h" + +// ISAP-A-128a +const uint8_t ISAP_IV_A[] = {0x01, ISAP_K, ISAP_rH, ISAP_rB, ISAP_sH, ISAP_sB, ISAP_sE, ISAP_sK}; +const uint8_t ISAP_IV_KA[] = {0x02, ISAP_K, ISAP_rH, ISAP_rB, ISAP_sH, ISAP_sB, ISAP_sE, ISAP_sK}; +const uint8_t ISAP_IV_KE[] = {0x03, ISAP_K, ISAP_rH, ISAP_rB, ISAP_sH, ISAP_sB, ISAP_sE, ISAP_sK}; + +// Ascon-Hash +const uint8_t ASCON_HASH_IV[] = {0x00, 0x40, 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00}; + +#endif // CONFIG_H diff --git a/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m/crypto_aead.c b/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m/crypto_aead.c new file mode 120000 index 0000000..e4f019c --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m/crypto_aead.c @@ -0,0 +1 @@ +../bi_32/crypto_aead.c \ No newline at end of file diff --git a/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m/forceinline.h b/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m/forceinline.h new file mode 120000 index 0000000..c156e37 --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m/forceinline.h @@ -0,0 +1 @@ +../bi_32/forceinline.h \ No newline at end of file diff --git a/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m/isap.c b/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m/isap.c new file mode 120000 index 0000000..9b7816c --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m/isap.c @@ -0,0 +1 @@ +../bi_32/isap.c \ No newline at end of file diff --git a/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m/isap.h b/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m/isap.h new file mode 120000 index 0000000..6175b4f --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m/isap.h @@ -0,0 +1 @@ +../bi_32/isap.h \ No newline at end of file diff --git a/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m_compact/api.h b/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m_compact/api.h new file mode 120000 index 0000000..ee9607d --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m_compact/api.h @@ -0,0 +1 @@ +../bi_32/api.h \ No newline at end of file diff --git a/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m_compact/asconp.h b/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m_compact/asconp.h new file mode 100644 index 0000000..f94d080 --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m_compact/asconp.h @@ -0,0 +1,273 @@ +#ifndef ASCONP_H_ +#define ASCONP_H_ + +#include +#include "forceinline.h" + +typedef union +{ + uint64_t x; + uint32_t w[2]; + uint8_t b[8]; +} lane_t; + +typedef union +{ + lane_t l[5]; + uint64_t x[5]; + uint32_t w[5][2]; + uint8_t b[5][8]; +} state_t; + +/* ---------------------------------------------------------------- */ + +#define P_sH PROUNDS(s, 12) +#define P_sB PROUNDS(s, 1) +#define P_sE PROUNDS(s, 6) +#define P_sK PROUNDS(s, 12) + +/* ---------------------------------------------------------------- */ + +#define U64TOWORD(x) to_bit_interleaving(U64BIG(x)) +#define WORDTOU64(x) U64BIG(from_bit_interleaving(x)) + +/* ---------------------------------------------------------------- */ + +#define TOBI(x) to_bit_interleaving(x) +#define FROMBI(x) from_bit_interleaving(x) + +/* ---------------------------------------------------------------- */ + +lane_t U64BIG(lane_t x) +{ + x.x = ((((x.x) & 0x00000000000000FFULL) << 56) | (((x.x) & 0x000000000000FF00ULL) << 40) | + (((x.x) & 0x0000000000FF0000ULL) << 24) | (((x.x) & 0x00000000FF000000ULL) << 8) | + (((x.x) & 0x000000FF00000000ULL) >> 8) | (((x.x) & 0x0000FF0000000000ULL) >> 24) | + (((x.x) & 0x00FF000000000000ULL) >> 40) | (((x.x) & 0xFF00000000000000ULL) >> 56)); + return x; +} + +/* ---------------------------------------------------------------- */ + +// Credit to Henry S. Warren, Hacker's Delight, Addison-Wesley, 2002 +lane_t to_bit_interleaving(lane_t in) +{ + uint32_t lo = in.w[0]; + uint32_t hi = in.w[1]; + uint32_t r0, r1; + r0 = (lo ^ (lo >> 1)) & 0x22222222, lo ^= r0 ^ (r0 << 1); + r0 = (lo ^ (lo >> 2)) & 0x0C0C0C0C, lo ^= r0 ^ (r0 << 2); + r0 = (lo ^ (lo >> 4)) & 0x00F000F0, lo ^= r0 ^ (r0 << 4); + r0 = (lo ^ (lo >> 8)) & 0x0000FF00, lo ^= r0 ^ (r0 << 8); + r1 = (hi ^ (hi >> 1)) & 0x22222222, hi ^= r1 ^ (r1 << 1); + r1 = (hi ^ (hi >> 2)) & 0x0C0C0C0C, hi ^= r1 ^ (r1 << 2); + r1 = (hi ^ (hi >> 4)) & 0x00F000F0, hi ^= r1 ^ (r1 << 4); + r1 = (hi ^ (hi >> 8)) & 0x0000FF00, hi ^= r1 ^ (r1 << 8); + lane_t out; + out.w[0] = (lo & 0x0000FFFF) | (hi << 16); + out.w[1] = (lo >> 16) | (hi & 0xFFFF0000); + return out; +} + +/* ---------------------------------------------------------------- */ + +// Credit to Henry S. Warren, Hacker's Delight, Addison-Wesley, 2002 +lane_t from_bit_interleaving(lane_t in) +{ + uint32_t lo = ((in).w[0] & 0x0000FFFF) | ((in).w[1] << 16); + uint32_t hi = ((in).w[0] >> 16) | ((in).w[1] & 0xFFFF0000); + uint32_t r0, r1; + r0 = (lo ^ (lo >> 8)) & 0x0000FF00, lo ^= r0 ^ (r0 << 8); + r0 = (lo ^ (lo >> 4)) & 0x00F000F0, lo ^= r0 ^ (r0 << 4); + r0 = (lo ^ (lo >> 2)) & 0x0C0C0C0C, lo ^= r0 ^ (r0 << 2); + r0 = (lo ^ (lo >> 1)) & 0x22222222, lo ^= r0 ^ (r0 << 1); + r1 = (hi ^ (hi >> 8)) & 0x0000FF00, hi ^= r1 ^ (r1 << 8); + r1 = (hi ^ (hi >> 4)) & 0x00F000F0, hi ^= r1 ^ (r1 << 4); + r1 = (hi ^ (hi >> 2)) & 0x0C0C0C0C, hi ^= r1 ^ (r1 << 2); + r1 = (hi ^ (hi >> 1)) & 0x22222222, hi ^= r1 ^ (r1 << 1); + lane_t out; + out.x = (uint64_t)hi << 32 | lo; + return out; +} + +/* ---------------------------------------------------------------- */ + +forceinline void ROUND(state_t *s, uint64_t C) +{ + uint32_t tmp0, tmp1, tmp2; + __asm__ __volatile__( + "@.syntax_unified\n\t" + "movs %[tmp1], %[C_e]\n\t" + "eor %[x2_e], %[x2_e], %[tmp1]\n\t" + "eor %[x0_e], %[x0_e], %[x4_e]\n\t" + "eor %[x4_e], %[x4_e], %[x3_e]\n\t" + "eor %[x2_e], %[x2_e], %[x1_e]\n\t" + "movs %[tmp0], %[x0_e]\n\t" + "bic %[tmp0], %[tmp0], %[x4_e]\n\t" + "movs %[tmp1], %[x2_e]\n\t" + "bic %[tmp1], %[tmp1], %[x1_e]\n\t" + "eor %[x0_e], %[x0_e], %[tmp1]\n\t" + "movs %[tmp1], %[x4_e]\n\t" + "bic %[tmp1], %[tmp1], %[x3_e]\n\t" + "eor %[x2_e], %[x2_e], %[tmp1]\n\t" + "movs %[tmp2], %[x1_e]\n\t" + "bic %[tmp2], %[tmp2], %[x0_e]\n\t" + "eor %[tmp2], %[x4_e], %[tmp2]\n\t" + "movs %[tmp1], %[x3_e]\n\t" + "bic %[tmp1], %[tmp1], %[x2_e]\n\t" + "eor %[tmp1], %[x1_e], %[tmp1]\n\t" + "eor %[tmp0], %[x3_e], %[tmp0]\n\t" + "eor %[tmp0], %[tmp0], %[x2_e]\n\t" + "eor %[tmp1], %[tmp1], %[x0_e]\n\t" + "eor %[x0_e], %[x0_e], %[tmp2]\n\t" + "movs %[x4_e], %[x4_o]\n\t" + "movs %[x1_e], %[x1_o]\n\t" + "movs %[x3_e], %[x3_o]\n\t" + "movs %[x3_o], %[tmp0]\n\t" + "movs %[x1_o], %[tmp1]\n\t" + "movs %[tmp0], %[x0_o]\n\t" + "movs %[tmp1], %[x2_o]\n\t" + "movs %[x0_o], %[x0_e]\n\t" + "movs %[x2_o], %[x2_e]\n\t" + "movs %[x0_e], %[C_o]\n\t" + "eor %[tmp1], %[tmp1], %[x0_e]\n\t" + "eor %[tmp0], %[tmp0], %[x4_e]\n\t" + "eor %[x4_e], %[x4_e], %[x3_e]\n\t" + "eor %[tmp1], %[tmp1], %[x1_e]\n\t" + "movs %[x0_e], %[tmp0] \n\t" + "bic %[x0_e], %[x0_e], %[x4_e]\n\t" + "movs %[x2_e], %[tmp1] \n\t" + "bic %[x2_e], %[x2_e], %[x1_e]\n\t" + "eor %[tmp0], %[tmp0], %[x2_e]\n\t" + "movs %[x2_e], %[x4_e] \n\t" + "bic %[x2_e], %[x2_e], %[x3_e]\n\t" + "eor %[tmp1], %[tmp1], %[x2_e]\n\t" + "movs %[x2_e], %[x1_e]\n\t" + "bic %[x2_e], %[x2_e], %[tmp0]\n\t" + "eor %[x4_e], %[x4_e], %[x2_e]\n\t" + "movs %[x2_e], %[x3_e] \n\t" + "bic %[x2_e], %[x2_e], %[tmp1]\n\t" + "eor %[x1_e], %[x1_e], %[x2_e]\n\t" + "eor %[x3_e], %[x3_e], %[x0_e]\n\t" + "eor %[x3_e], %[x3_e], %[tmp1]\n\t" + "eor %[x1_e], %[x1_e], %[tmp0]\n\t" + "eor %[tmp0], %[tmp0], %[x4_e]\n\t" + "movs %[x4_o], %[tmp1]\n\t" + "movs %[x2_e], %[x3_o]\n\t" + "movs %[x3_o], %[x1_e]\n\t" + "movs %[tmp1], #17\n\t" + "movs %[x0_e], %[tmp2]\n\t" + "ror %[x0_e], %[x0_e], %[tmp1]\n\t" + "eor %[x0_e], %[tmp2], %[x0_e]\n\t" + "movs %[x1_e], %[x4_e]\n\t" + "ror %[x1_e], %[x1_e], %[tmp1]\n\t" + "eor %[x1_e], %[x4_e], %[x1_e]\n\t" + "movs %[tmp1], #3\n\t" + "ror %[x1_e], %[x1_e], %[tmp1]\n\t" + "eor %[tmp2], %[tmp2], %[x1_e]\n\t" + "movs %[tmp1], #4\n\t" + "ror %[x0_e], %[x0_e], %[tmp1]\n\t" + "eor %[x4_e], %[x4_e], %[x0_e]\n\t" + "movs %[x1_e], %[x2_e]\n\t" + "ror %[x1_e], %[x1_e], %[tmp1]\n\t" + "eor %[x1_e], %[x3_e], %[x1_e]\n\t" + "movs %[tmp1], #3\n\t" + "movs %[x0_e], %[x3_e]\n\t" + "ror %[x0_e], %[x0_e], %[tmp1]\n\t" + "eor %[x0_e], %[x2_e], %[x0_e]\n\t" + "movs %[tmp1], #5\n\t" + "ror %[x0_e], %[x0_e], %[tmp1]\n\t" + "eor %[x2_e], %[x2_e], %[x0_e]\n\t" + "ror %[x1_e], %[x1_e], %[tmp1]\n\t" + "eor %[x3_e], %[x3_e], %[x1_e]\n\t" + "movs %[x0_e], %[x0_o]\n\t" + "movs %[x1_e], %[x1_o]\n\t" + "movs %[x1_o], %[x2_e]\n\t" + "movs %[x0_o], %[tmp2]\n\t" + "movs %[tmp2], %[x4_o]\n\t" + "movs %[x4_o], %[x4_e]\n\t" + "movs %[x4_e], %[x3_o]\n\t" + "movs %[x3_o], %[x3_e]\n\t" + "movs %[x3_e], %[x0_e]\n\t" + "ror %[x3_e], %[x3_e], %[tmp1]\n\t" + "eor %[x3_e], %[tmp0], %[x3_e]\n\t" + "movs %[tmp1], #4\n\t" + "movs %[x2_e], %[tmp0]\n\t" + "ror %[x2_e], %[x2_e], %[tmp1]\n\t" + "eor %[x2_e], %[x0_e], %[x2_e]\n\t" + "movs %[tmp1], #9\n\t" + "ror %[x3_e], %[x3_e], %[tmp1]\n\t" + "eor %[x0_e], %[x0_e], %[x3_e]\n\t" + "movs %[tmp1], #10\n\t" + "ror %[x2_e], %[x2_e], %[tmp1]\n\t" + "eor %[tmp0], %[tmp0], %[x2_e]\n\t" + "movs %[tmp1], #11\n\t" + "movs %[x2_e], %[x1_e]\n\t" + "ror %[x2_e], %[x2_e], %[tmp1]\n\t" + "eor %[x2_e], %[x1_e], %[x2_e]\n\t" + "movs %[x3_e], %[x4_e]\n\t" + "ror %[x3_e], %[x3_e], %[tmp1]\n\t" + "eor %[x3_e], %[x4_e], %[x3_e]\n\t" + "movs %[tmp1], #19\n\t" + "ror %[x3_e], %[x3_e], %[tmp1]\n\t" + "eor %[x1_e], %[x1_e], %[x3_e]\n\t" + "movs %[tmp1], #20\n\t" + "ror %[x2_e], %[x2_e], %[tmp1]\n\t" + "eor %[x4_e], %[x4_e], %[x2_e]\n\t" + "movs %[x2_e], %[x2_o]\n\t" + "movs %[x3_e], %[x1_o]\n\t" + "movs %[x1_o], %[x4_e]\n\t" + "movs %[x2_o], %[tmp0]\n\t" + "movs %[x4_e], #2\n\t" + "mvn %[tmp0], %[tmp2]\n\t" + "ror %[tmp0], %[tmp0], %[x4_e]\n\t" + "eor %[tmp0], %[x2_e], %[tmp0]\n\t" + "movs %[x4_e], #3\n\t" + "mvn %[tmp1], %[x2_e]\n\t" + "ror %[tmp1], %[tmp1], %[x4_e]\n\t" + "eor %[tmp1], %[tmp2], %[tmp1]\n\t" + "eor %[x2_e], %[x2_e], %[tmp1]\n\t" + "movs %[x4_e], #1\n\t" + "ror %[tmp0], %[tmp0], %[x4_e]\n\t" + "eor %[tmp2], %[tmp2], %[tmp0]\n\t" + "movs %[x4_e], %[x0_o]\n\t" + "movs %[x0_o], %[x2_o]\n\t" + "movs %[x2_o], %[tmp2]\n\t" + : [x0_e] "+l"(s->w[0][0]), [x1_e] "+l"(s->w[1][0]), + [x2_e] "+l"(s->w[2][0]), [x3_e] "+l"(s->w[3][0]), + [x4_e] "+l"(s->w[4][0]), [x0_o] "+r"(s->w[0][1]), + [x1_o] "+r"(s->w[1][1]), [x2_o] "+r"(s->w[2][1]), + [x3_o] "+r"(s->w[3][1]), [x4_o] "+r"(s->w[4][1]), + [tmp0] "=l"(tmp0), [tmp1] "=l"(tmp1), [tmp2] "=l"(tmp2) + : [C_e] "ri"((uint32_t)C), [C_o] "ri"((uint32_t)(C >> 32)) + :); +} + +/* ---------------------------------------------------------------- */ + +void PROUNDS(state_t *s, uint8_t nr) +{ + switch (nr) + { + case 12: + ROUND(s, 0xc0000000c); + ROUND(s, 0xc00000009); + ROUND(s, 0x90000000c); + ROUND(s, 0x900000009); + ROUND(s, 0xc00000006); + ROUND(s, 0xc00000003); + case 6: + ROUND(s, 0x900000006); + ROUND(s, 0x900000003); + ROUND(s, 0x60000000c); + ROUND(s, 0x600000009); + ROUND(s, 0x30000000c); + default: + ROUND(s, 0x300000009); + ; + } +} + +/* ---------------------------------------------------------------- */ + +#endif // ASCONP_H diff --git a/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m_compact/config.h b/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m_compact/config.h new file mode 100644 index 0000000..2e1c76f --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m_compact/config.h @@ -0,0 +1,16 @@ +#ifndef CONFIG_H +#define CONFIG_H + +#define ENABLE_HASH 0 + +#include "isap.h" + +// ISAP-A-128a +const uint8_t ISAP_IV_A[] = {0x01, ISAP_K, ISAP_rH, ISAP_rB, ISAP_sH, ISAP_sB, ISAP_sE, ISAP_sK}; +const uint8_t ISAP_IV_KA[] = {0x02, ISAP_K, ISAP_rH, ISAP_rB, ISAP_sH, ISAP_sB, ISAP_sE, ISAP_sK}; +const uint8_t ISAP_IV_KE[] = {0x03, ISAP_K, ISAP_rH, ISAP_rB, ISAP_sH, ISAP_sB, ISAP_sE, ISAP_sK}; + +// Ascon-Hash +const uint8_t ASCON_HASH_IV[] = {0x00, 0x40, 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00}; + +#endif // CONFIG_H diff --git a/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m_compact/crypto_aead.c b/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m_compact/crypto_aead.c new file mode 120000 index 0000000..e4f019c --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m_compact/crypto_aead.c @@ -0,0 +1 @@ +../bi_32/crypto_aead.c \ No newline at end of file diff --git a/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m_compact/forceinline.h b/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m_compact/forceinline.h new file mode 120000 index 0000000..c156e37 --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m_compact/forceinline.h @@ -0,0 +1 @@ +../bi_32/forceinline.h \ No newline at end of file diff --git a/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m_compact/isap.c b/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m_compact/isap.c new file mode 120000 index 0000000..9b7816c --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m_compact/isap.c @@ -0,0 +1 @@ +../bi_32/isap.c \ No newline at end of file diff --git a/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m_compact/isap.h b/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m_compact/isap.h new file mode 120000 index 0000000..6175b4f --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m_compact/isap.h @@ -0,0 +1 @@ +../bi_32/isap.h \ No newline at end of file diff --git a/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m_stp/api.h b/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m_stp/api.h new file mode 120000 index 0000000..ee9607d --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m_stp/api.h @@ -0,0 +1 @@ +../bi_32/api.h \ No newline at end of file diff --git a/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m_stp/asconp.h b/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m_stp/asconp.h new file mode 100644 index 0000000..a78e026 --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m_stp/asconp.h @@ -0,0 +1,275 @@ +#ifndef ASCONP_H_ +#define ASCONP_H_ + +#include +#include "forceinline.h" + +typedef union +{ + uint64_t x; + uint32_t w[2]; + uint8_t b[8]; +} lane_t; + +typedef union +{ + lane_t l[5]; + uint64_t x[5]; + uint32_t w[5][2]; + uint8_t b[5][8]; +} state_t; + +/* ---------------------------------------------------------------- */ + +#define P_sH PROUNDS(s, 12) +#define P_sB PROUNDS(s, 1) +#define P_sE PROUNDS(s, 6) +#define P_sK PROUNDS(s, 12) +#define P_PVP PROUNDS(s, 7) + +/* ---------------------------------------------------------------- */ + +#define U64TOWORD(x) to_bit_interleaving(U64BIG(x)) +#define WORDTOU64(x) U64BIG(from_bit_interleaving(x)) + +/* ---------------------------------------------------------------- */ + +#define TOBI(x) to_bit_interleaving(x) +#define FROMBI(x) from_bit_interleaving(x) + +/* ---------------------------------------------------------------- */ + +lane_t U64BIG(lane_t x) +{ + x.x = ((((x.x) & 0x00000000000000FFULL) << 56) | (((x.x) & 0x000000000000FF00ULL) << 40) | + (((x.x) & 0x0000000000FF0000ULL) << 24) | (((x.x) & 0x00000000FF000000ULL) << 8) | + (((x.x) & 0x000000FF00000000ULL) >> 8) | (((x.x) & 0x0000FF0000000000ULL) >> 24) | + (((x.x) & 0x00FF000000000000ULL) >> 40) | (((x.x) & 0xFF00000000000000ULL) >> 56)); + return x; +} + +/* ---------------------------------------------------------------- */ + +// Credit to Henry S. Warren, Hacker's Delight, Addison-Wesley, 2002 +lane_t to_bit_interleaving(lane_t in) +{ + uint32_t lo = in.w[0]; + uint32_t hi = in.w[1]; + uint32_t r0, r1; + r0 = (lo ^ (lo >> 1)) & 0x22222222, lo ^= r0 ^ (r0 << 1); + r0 = (lo ^ (lo >> 2)) & 0x0C0C0C0C, lo ^= r0 ^ (r0 << 2); + r0 = (lo ^ (lo >> 4)) & 0x00F000F0, lo ^= r0 ^ (r0 << 4); + r0 = (lo ^ (lo >> 8)) & 0x0000FF00, lo ^= r0 ^ (r0 << 8); + r1 = (hi ^ (hi >> 1)) & 0x22222222, hi ^= r1 ^ (r1 << 1); + r1 = (hi ^ (hi >> 2)) & 0x0C0C0C0C, hi ^= r1 ^ (r1 << 2); + r1 = (hi ^ (hi >> 4)) & 0x00F000F0, hi ^= r1 ^ (r1 << 4); + r1 = (hi ^ (hi >> 8)) & 0x0000FF00, hi ^= r1 ^ (r1 << 8); + lane_t out; + out.w[0] = (lo & 0x0000FFFF) | (hi << 16); + out.w[1] = (lo >> 16) | (hi & 0xFFFF0000); + return out; +} + +/* ---------------------------------------------------------------- */ + +// Credit to Henry S. Warren, Hacker's Delight, Addison-Wesley, 2002 +lane_t from_bit_interleaving(lane_t in) +{ + uint32_t lo = ((in).w[0] & 0x0000FFFF) | ((in).w[1] << 16); + uint32_t hi = ((in).w[0] >> 16) | ((in).w[1] & 0xFFFF0000); + uint32_t r0, r1; + r0 = (lo ^ (lo >> 8)) & 0x0000FF00, lo ^= r0 ^ (r0 << 8); + r0 = (lo ^ (lo >> 4)) & 0x00F000F0, lo ^= r0 ^ (r0 << 4); + r0 = (lo ^ (lo >> 2)) & 0x0C0C0C0C, lo ^= r0 ^ (r0 << 2); + r0 = (lo ^ (lo >> 1)) & 0x22222222, lo ^= r0 ^ (r0 << 1); + r1 = (hi ^ (hi >> 8)) & 0x0000FF00, hi ^= r1 ^ (r1 << 8); + r1 = (hi ^ (hi >> 4)) & 0x00F000F0, hi ^= r1 ^ (r1 << 4); + r1 = (hi ^ (hi >> 2)) & 0x0C0C0C0C, hi ^= r1 ^ (r1 << 2); + r1 = (hi ^ (hi >> 1)) & 0x22222222, hi ^= r1 ^ (r1 << 1); + lane_t out; + out.x = (uint64_t)hi << 32 | lo; + return out; +} + +/* ---------------------------------------------------------------- */ + +forceinline void ROUND(state_t *s, uint64_t C) +{ + uint32_t tmp0, tmp1, tmp2; + __asm__ __volatile__( + "@.syntax_unified\n\t" + "movs %[tmp1], %[C_e]\n\t" + "eor %[x2_e], %[x2_e], %[tmp1]\n\t" + "eor %[x0_e], %[x0_e], %[x4_e]\n\t" + "eor %[x4_e], %[x4_e], %[x3_e]\n\t" + "eor %[x2_e], %[x2_e], %[x1_e]\n\t" + "movs %[tmp0], %[x0_e]\n\t" + "bic %[tmp0], %[tmp0], %[x4_e]\n\t" + "movs %[tmp1], %[x2_e]\n\t" + "bic %[tmp1], %[tmp1], %[x1_e]\n\t" + "eor %[x0_e], %[x0_e], %[tmp1]\n\t" + "movs %[tmp1], %[x4_e]\n\t" + "bic %[tmp1], %[tmp1], %[x3_e]\n\t" + "eor %[x2_e], %[x2_e], %[tmp1]\n\t" + "movs %[tmp2], %[x1_e]\n\t" + "bic %[tmp2], %[tmp2], %[x0_e]\n\t" + "eor %[tmp2], %[x4_e], %[tmp2]\n\t" + "movs %[tmp1], %[x3_e]\n\t" + "bic %[tmp1], %[tmp1], %[x2_e]\n\t" + "eor %[tmp1], %[x1_e], %[tmp1]\n\t" + "eor %[tmp0], %[x3_e], %[tmp0]\n\t" + "eor %[tmp0], %[tmp0], %[x2_e]\n\t" + "eor %[tmp1], %[tmp1], %[x0_e]\n\t" + "eor %[x0_e], %[x0_e], %[tmp2]\n\t" + "movs %[x4_e], %[x4_o]\n\t" + "movs %[x1_e], %[x1_o]\n\t" + "movs %[x3_e], %[x3_o]\n\t" + "movs %[x3_o], %[tmp0]\n\t" + "movs %[x1_o], %[tmp1]\n\t" + "movs %[tmp0], %[x0_o]\n\t" + "movs %[tmp1], %[x2_o]\n\t" + "movs %[x0_o], %[x0_e]\n\t" + "movs %[x2_o], %[x2_e]\n\t" + "movs %[x0_e], %[C_o]\n\t" + "eor %[tmp1], %[tmp1], %[x0_e]\n\t" + "eor %[tmp0], %[tmp0], %[x4_e]\n\t" + "eor %[x4_e], %[x4_e], %[x3_e]\n\t" + "eor %[tmp1], %[tmp1], %[x1_e]\n\t" + "movs %[x0_e], %[tmp0] \n\t" + "bic %[x0_e], %[x0_e], %[x4_e]\n\t" + "movs %[x2_e], %[tmp1] \n\t" + "bic %[x2_e], %[x2_e], %[x1_e]\n\t" + "eor %[tmp0], %[tmp0], %[x2_e]\n\t" + "movs %[x2_e], %[x4_e] \n\t" + "bic %[x2_e], %[x2_e], %[x3_e]\n\t" + "eor %[tmp1], %[tmp1], %[x2_e]\n\t" + "movs %[x2_e], %[x1_e]\n\t" + "bic %[x2_e], %[x2_e], %[tmp0]\n\t" + "eor %[x4_e], %[x4_e], %[x2_e]\n\t" + "movs %[x2_e], %[x3_e] \n\t" + "bic %[x2_e], %[x2_e], %[tmp1]\n\t" + "eor %[x1_e], %[x1_e], %[x2_e]\n\t" + "eor %[x3_e], %[x3_e], %[x0_e]\n\t" + "eor %[x3_e], %[x3_e], %[tmp1]\n\t" + "eor %[x1_e], %[x1_e], %[tmp0]\n\t" + "eor %[tmp0], %[tmp0], %[x4_e]\n\t" + "movs %[x4_o], %[tmp1]\n\t" + "movs %[x2_e], %[x3_o]\n\t" + "movs %[x3_o], %[x1_e]\n\t" + "movs %[tmp1], #17\n\t" + "movs %[x0_e], %[tmp2]\n\t" + "ror %[x0_e], %[x0_e], %[tmp1]\n\t" + "eor %[x0_e], %[tmp2], %[x0_e]\n\t" + "movs %[x1_e], %[x4_e]\n\t" + "ror %[x1_e], %[x1_e], %[tmp1]\n\t" + "eor %[x1_e], %[x4_e], %[x1_e]\n\t" + "movs %[tmp1], #3\n\t" + "ror %[x1_e], %[x1_e], %[tmp1]\n\t" + "eor %[tmp2], %[tmp2], %[x1_e]\n\t" + "movs %[tmp1], #4\n\t" + "ror %[x0_e], %[x0_e], %[tmp1]\n\t" + "eor %[x4_e], %[x4_e], %[x0_e]\n\t" + "movs %[x1_e], %[x2_e]\n\t" + "ror %[x1_e], %[x1_e], %[tmp1]\n\t" + "eor %[x1_e], %[x3_e], %[x1_e]\n\t" + "movs %[tmp1], #3\n\t" + "movs %[x0_e], %[x3_e]\n\t" + "ror %[x0_e], %[x0_e], %[tmp1]\n\t" + "eor %[x0_e], %[x2_e], %[x0_e]\n\t" + "movs %[tmp1], #5\n\t" + "ror %[x0_e], %[x0_e], %[tmp1]\n\t" + "eor %[x2_e], %[x2_e], %[x0_e]\n\t" + "ror %[x1_e], %[x1_e], %[tmp1]\n\t" + "eor %[x3_e], %[x3_e], %[x1_e]\n\t" + "movs %[x0_e], %[x0_o]\n\t" + "movs %[x1_e], %[x1_o]\n\t" + "movs %[x1_o], %[x2_e]\n\t" + "movs %[x0_o], %[tmp2]\n\t" + "movs %[tmp2], %[x4_o]\n\t" + "movs %[x4_o], %[x4_e]\n\t" + "movs %[x4_e], %[x3_o]\n\t" + "movs %[x3_o], %[x3_e]\n\t" + "movs %[x3_e], %[x0_e]\n\t" + "ror %[x3_e], %[x3_e], %[tmp1]\n\t" + "eor %[x3_e], %[tmp0], %[x3_e]\n\t" + "movs %[tmp1], #4\n\t" + "movs %[x2_e], %[tmp0]\n\t" + "ror %[x2_e], %[x2_e], %[tmp1]\n\t" + "eor %[x2_e], %[x0_e], %[x2_e]\n\t" + "movs %[tmp1], #9\n\t" + "ror %[x3_e], %[x3_e], %[tmp1]\n\t" + "eor %[x0_e], %[x0_e], %[x3_e]\n\t" + "movs %[tmp1], #10\n\t" + "ror %[x2_e], %[x2_e], %[tmp1]\n\t" + "eor %[tmp0], %[tmp0], %[x2_e]\n\t" + "movs %[tmp1], #11\n\t" + "movs %[x2_e], %[x1_e]\n\t" + "ror %[x2_e], %[x2_e], %[tmp1]\n\t" + "eor %[x2_e], %[x1_e], %[x2_e]\n\t" + "movs %[x3_e], %[x4_e]\n\t" + "ror %[x3_e], %[x3_e], %[tmp1]\n\t" + "eor %[x3_e], %[x4_e], %[x3_e]\n\t" + "movs %[tmp1], #19\n\t" + "ror %[x3_e], %[x3_e], %[tmp1]\n\t" + "eor %[x1_e], %[x1_e], %[x3_e]\n\t" + "movs %[tmp1], #20\n\t" + "ror %[x2_e], %[x2_e], %[tmp1]\n\t" + "eor %[x4_e], %[x4_e], %[x2_e]\n\t" + "movs %[x2_e], %[x2_o]\n\t" + "movs %[x3_e], %[x1_o]\n\t" + "movs %[x1_o], %[x4_e]\n\t" + "movs %[x2_o], %[tmp0]\n\t" + "movs %[x4_e], #2\n\t" + "mvn %[tmp0], %[tmp2]\n\t" + "ror %[tmp0], %[tmp0], %[x4_e]\n\t" + "eor %[tmp0], %[x2_e], %[tmp0]\n\t" + "movs %[x4_e], #3\n\t" + "mvn %[tmp1], %[x2_e]\n\t" + "ror %[tmp1], %[tmp1], %[x4_e]\n\t" + "eor %[tmp1], %[tmp2], %[tmp1]\n\t" + "eor %[x2_e], %[x2_e], %[tmp1]\n\t" + "movs %[x4_e], #1\n\t" + "ror %[tmp0], %[tmp0], %[x4_e]\n\t" + "eor %[tmp2], %[tmp2], %[tmp0]\n\t" + "movs %[x4_e], %[x0_o]\n\t" + "movs %[x0_o], %[x2_o]\n\t" + "movs %[x2_o], %[tmp2]\n\t" + : [x0_e] "+l"(s->w[0][0]), [x1_e] "+l"(s->w[1][0]), + [x2_e] "+l"(s->w[2][0]), [x3_e] "+l"(s->w[3][0]), + [x4_e] "+l"(s->w[4][0]), [x0_o] "+r"(s->w[0][1]), + [x1_o] "+r"(s->w[1][1]), [x2_o] "+r"(s->w[2][1]), + [x3_o] "+r"(s->w[3][1]), [x4_o] "+r"(s->w[4][1]), + [tmp0] "=l"(tmp0), [tmp1] "=l"(tmp1), [tmp2] "=l"(tmp2) + : [C_e] "ri"((uint32_t)C), [C_o] "ri"((uint32_t)(C >> 32)) + :); +} + +/* ---------------------------------------------------------------- */ + +void PROUNDS(state_t *s, uint8_t nr) +{ + switch (nr) + { + case 12: + ROUND(s, 0xc0000000c); + ROUND(s, 0xc00000009); + ROUND(s, 0x90000000c); + ROUND(s, 0x900000009); + ROUND(s, 0xc00000006); + case 7: + ROUND(s, 0xc00000003); + case 6: + ROUND(s, 0x900000006); + ROUND(s, 0x900000003); + ROUND(s, 0x60000000c); + ROUND(s, 0x600000009); + ROUND(s, 0x30000000c); + default: + ROUND(s, 0x300000009); + ; + } +} + +/* ---------------------------------------------------------------- */ + +#endif // ASCONP_H diff --git a/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m_stp/config.h b/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m_stp/config.h new file mode 100644 index 0000000..2e1c76f --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m_stp/config.h @@ -0,0 +1,16 @@ +#ifndef CONFIG_H +#define CONFIG_H + +#define ENABLE_HASH 0 + +#include "isap.h" + +// ISAP-A-128a +const uint8_t ISAP_IV_A[] = {0x01, ISAP_K, ISAP_rH, ISAP_rB, ISAP_sH, ISAP_sB, ISAP_sE, ISAP_sK}; +const uint8_t ISAP_IV_KA[] = {0x02, ISAP_K, ISAP_rH, ISAP_rB, ISAP_sH, ISAP_sB, ISAP_sE, ISAP_sK}; +const uint8_t ISAP_IV_KE[] = {0x03, ISAP_K, ISAP_rH, ISAP_rB, ISAP_sH, ISAP_sB, ISAP_sE, ISAP_sK}; + +// Ascon-Hash +const uint8_t ASCON_HASH_IV[] = {0x00, 0x40, 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00}; + +#endif // CONFIG_H diff --git a/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m_stp/crypto_aead.c b/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m_stp/crypto_aead.c new file mode 100644 index 0000000..e0d533c --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m_stp/crypto_aead.c @@ -0,0 +1,68 @@ +#include "api.h" +#include "isap.h" +#include "crypto_aead.h" + +int crypto_aead_encrypt( + unsigned char *c, unsigned long long *clen, + const unsigned char *m, unsigned long long mlen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k) +{ + (void)nsec; + + // Ciphertext length is mlen + tag length + *clen = mlen + ISAP_TAG_SZ; + + // Encrypt plaintext + if (mlen > 0) + { + isap_enc(k, npub, m, mlen, c); + } + + // Generate tag + unsigned char *tag = c + mlen; + isap_mac(k, npub, ad, adlen, c, mlen, tag); + return 0; +} + +int crypto_aead_decrypt( + unsigned char *m, unsigned long long *mlen, + unsigned char *nsec, + const unsigned char *c, unsigned long long clen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) +{ + (void)nsec; + + // Plaintext length is clen - tag length + *mlen = clen - ISAP_TAG_SZ; + + // Generate tag + unsigned char T[16]; + isap_mac(k, npub, ad, adlen, c, *mlen, T); + + // Compare tag + unsigned char T_star[16]; + for (int i = 0; i < 16; i++) + { + T_star[i] = *(c + *mlen + i); + } + int eq_cnt = pvp(T, T_star); + + // Perform decryption if tag is correct + if (eq_cnt == ISAP_TAG_SZ) + { + if (*mlen > 0) + { + isap_enc(k, npub, c, *mlen, m); + } + return 0; + } + else + { + return -1; + } +} diff --git a/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m_stp/forceinline.h b/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m_stp/forceinline.h new file mode 120000 index 0000000..c156e37 --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m_stp/forceinline.h @@ -0,0 +1 @@ +../bi_32/forceinline.h \ No newline at end of file diff --git a/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m_stp/isap.c b/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m_stp/isap.c new file mode 100644 index 0000000..2fa2aed --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m_stp/isap.c @@ -0,0 +1,276 @@ +#include +#include +#include "api.h" +#include "isap.h" +#include "asconp.h" +#include "config.h" + +// Needed for LR tag comparison +uint64_t s0, s1; + +forceinline void ABSORB_LANES(state_t *s, const uint8_t *src, uint64_t len) +{ + while (len >= 8) + { + // Absorb full lanes + lane_t t0 = U64TOWORD(*(lane_t *)(src + 0)); + s->x[0] ^= t0.x; + len -= ISAP_rH / 8; + src += ISAP_rH / 8; + P_sH; + } + + if (len > 0) + { + // Absorb partial lane and padding + size_t i; + lane_t t0 = {0}; + for (i = 0; i < len; i++) + { + t0.b[7 - i] ^= *src; + src++; + } + t0.b[7 - i] ^= 0x80; + t0 = TOBI(t0); + s->x[0] ^= t0.x; + P_sH; + } + else + { + // Absorb padded empty lane + s->b[0][7] ^= 0x80; + P_sH; + } +} + +/******************************************************************************/ +/* ISAP_RK */ +/******************************************************************************/ + +void isap_rk( + const uint8_t *k, + const uint8_t *iv, + const uint8_t *y, + state_t *out, + const size_t outlen) +{ + state_t state; + state_t *s = &state; + + // Initialize + s->l[0] = U64TOWORD(*(lane_t *)(k + 0)); + s->l[1] = U64TOWORD(*(lane_t *)(k + 8)); + s->l[2] = U64TOWORD(*(lane_t *)(iv + 0)); + s->x[3] = 0; + s->x[4] = 0; + P_sK; + + // Absorb Y, bit by bit + for (size_t i = 0; i < 16; i++) + { + uint8_t y_byte = *y; + s->b[0][7] ^= (y_byte & 0x80) << 0; + P_sB; + s->b[0][7] ^= (y_byte & 0x40) << 1; + P_sB; + s->b[0][7] ^= (y_byte & 0x20) << 2; + P_sB; + s->b[0][7] ^= (y_byte & 0x10) << 3; + P_sB; + s->b[0][7] ^= (y_byte & 0x08) << 4; + P_sB; + s->b[0][7] ^= (y_byte & 0x04) << 5; + P_sB; + s->b[0][7] ^= (y_byte & 0x02) << 6; + P_sB; + s->b[0][7] ^= (y_byte & 0x01) << 7; + if (i != 15) + { + P_sB; + y += 1; + } + } + + // Squeeze K* + P_sK; + out->x[0] = s->x[0]; + out->x[1] = s->x[1]; + if (outlen > 16) + { + out->x[2] = s->x[2]; + } +} + +/******************************************************************************/ +/* ISAP_MAC */ +/******************************************************************************/ + +void isap_mac( + const uint8_t *k, + const uint8_t *npub, + const uint8_t *ad, uint64_t adlen, + const uint8_t *c, uint64_t clen, + uint8_t *tag) +{ + state_t state; + state_t *s = &state; + + // Initialize + s->l[0] = U64TOWORD(*(lane_t *)(npub + 0)); + s->l[1] = U64TOWORD(*(lane_t *)(npub + 8)); + s->l[2] = U64TOWORD(*(lane_t *)(ISAP_IV_A + 0)); + s->x[3] = 0; + s->x[4] = 0; + P_sH; + + // Absorb associated data + ABSORB_LANES(s, ad, adlen); + + // Domain seperation + s->w[4][0] ^= 0x1UL; + + // Absorb ciphertext + ABSORB_LANES(s, c, clen); + + // Needed for LR tag comparison + s0 = s->x[0]; + s1 = s->x[1]; + + // Derive KA* + s->l[0] = WORDTOU64(s->l[0]); + s->l[1] = WORDTOU64(s->l[1]); + isap_rk(k, ISAP_IV_KA, (const uint8_t *)(s->b), s, CRYPTO_KEYBYTES); + + // Squeeze tag + P_sH; + lane_t t0 = WORDTOU64(s->l[0]); + memcpy(tag + 0, t0.b, 8); + t0 = WORDTOU64(s->l[1]); + memcpy(tag + 8, t0.b, 8); +} + +/******************************************************************************/ +/* Leakage resilient tag comparison. */ +/* Similar to Fig.3 of https://eprint.iacr.org/2021/402.pdf. */ +/******************************************************************************/ + +int pvp( + const uint8_t *T, const uint8_t *T_star) +{ + state_t state; + state_t *s = &state; + + // Calculate U + s->l[0] = U64TOWORD(*(lane_t *)(T + 0)); + s->l[1] = U64TOWORD(*(lane_t *)(T + 8)); + s->x[2] = s0; + s->x[3] = s1; + s->x[4] = 0; + P_PVP; + uint64_t u0, u1; + u0 = s->x[0]; + u1 = s->x[1]; + + // Calculate U' + s->l[0] = U64TOWORD(*(lane_t *)(T_star + 0)); + s->l[1] = U64TOWORD(*(lane_t *)(T_star + 8)); + s->x[2] = s0; + s->x[3] = s1; + s->x[4] = 0; + P_PVP; + + // Compare tag + int eq_cnt = 0; + for (size_t i = 0; i < 8; i++) + { + eq_cnt += (s->b[0][i] == ((uint8_t *)&u0)[i]); + } + for (size_t i = 0; i < 8; i++) + { + eq_cnt += (s->b[1][i] == ((uint8_t *)&u1)[i]); + } + return eq_cnt; +} + +/******************************************************************************/ +/* ISAP_ENC */ +/******************************************************************************/ + +void isap_enc( + const uint8_t *k, + const uint8_t *npub, + const uint8_t *m, uint64_t mlen, + uint8_t *c) + +{ + state_t state; + state_t *s = &state; + + // Init state + isap_rk(k, ISAP_IV_KE, npub, s, ISAP_STATE_SZ - CRYPTO_NPUBBYTES); + s->l[3] = U64TOWORD(*(lane_t *)(npub + 0)); + s->l[4] = U64TOWORD(*(lane_t *)(npub + 8)); + + while (mlen >= ISAP_rH / 8) + { + // Encrypt full lanes + P_sE; + lane_t t0 = WORDTOU64(s->l[0]); + *(uint64_t *)c = *(uint64_t *)m ^ t0.x; + mlen -= ISAP_rH / 8; + m += ISAP_rH / 8; + c += ISAP_rH / 8; + } + + if (mlen > 0) + { + // Encrypt partial lanes + P_sE; + lane_t t0 = WORDTOU64(s->l[0]); + for (uint8_t i = 0; i < mlen; i++) + { + *c = *m ^ t0.b[i]; + m += 1; + c += 1; + } + } +} + +/******************************************************************************/ +/* Ascon-Hash */ +/******************************************************************************/ + +#if ENABLE_HASH == 1 + +int crypto_hash(uint8_t *out, const uint8_t *in, unsigned long long inlen) +{ + + state_t state; + state_t *s = &state; + + // Initialize + s->l[0] = U64TOWORD(*(lane_t *)(ASCON_HASH_IV + 0)); + s->x[1] = 0; + s->x[2] = 0; + s->x[3] = 0; + s->x[4] = 0; + P_sH; + + // Absorb input + ABSORB_LANES(s, in, inlen); + + for (size_t i = 0; i < 4; i++) + { + // Squeeze full lanes + lane_t t0 = WORDTOU64(s->l[0]); + *(uint64_t *)(out + 8 * i) = t0.x; + if (i < 3) + { + P_sH; + } + } + + return 0; +} + +#endif diff --git a/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m_stp/isap.h b/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m_stp/isap.h new file mode 100644 index 0000000..ae37dcd --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv6m_stp/isap.h @@ -0,0 +1,49 @@ +#ifndef ISAP_H +#define ISAP_H + +#include + +// Rate in bits +#define ISAP_rH 64 +#define ISAP_rB 1 + +// Number of rounds +#define ISAP_sH 12 +#define ISAP_sB 1 +#define ISAP_sE 6 +#define ISAP_sK 12 + +// State size in bytes +#define ISAP_STATE_SZ 40 + +// Size of rate in bytes +#define ISAP_rH_SZ ((ISAP_rH + 7) / 8) + +// Size of zero truncated IV in bytes +#define ISAP_IV_SZ 8 + +// Size of tag in bytes +#define ISAP_TAG_SZ 16 + +// Security level +#define ISAP_K 128 + +void isap_mac( + const uint8_t *k, + const uint8_t *npub, + const uint8_t *ad, const uint64_t adlen, + const uint8_t *c, const uint64_t clen, + uint8_t *tag); + +int pvp( + const unsigned char *T, + const unsigned char *T_star); + +void isap_enc( + const uint8_t *k, + const uint8_t *npub, + const uint8_t *m, const uint64_t mlen, + uint8_t *c); + +#endif + diff --git a/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv7m/api.h b/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv7m/api.h new file mode 120000 index 0000000..ee9607d --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv7m/api.h @@ -0,0 +1 @@ +../bi_32/api.h \ No newline at end of file diff --git a/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv7m/asconp.h b/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv7m/asconp.h new file mode 100644 index 0000000..87ab8e8 --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv7m/asconp.h @@ -0,0 +1,203 @@ +#ifndef ASCONP_H_ +#define ASCONP_H_ + +#include +#include "forceinline.h" + +typedef union +{ + uint64_t x; + uint32_t w[2]; + uint8_t b[8]; +} lane_t; + +typedef union +{ + lane_t l[5]; + uint64_t x[5]; + uint32_t w[5][2]; + uint8_t b[5][8]; +} state_t; + +/* ---------------------------------------------------------------- */ + +#define P_sH P12ROUNDS(s) +#define P_sB P1ROUNDS(s) +#define P_sE P6ROUNDS(s) +#define P_sK P12ROUNDS(s) + +/* ---------------------------------------------------------------- */ + +#define U64TOWORD(x) to_bit_interleaving(U64BIG(x)) +#define WORDTOU64(x) U64BIG(from_bit_interleaving(x)) + +/* ---------------------------------------------------------------- */ + +#define TOBI(x) to_bit_interleaving(x) +#define FROMBI(x) from_bit_interleaving(x) + +/* ---------------------------------------------------------------- */ + +forceinline lane_t U64BIG(lane_t x) +{ + x.x = ((((x.x) & 0x00000000000000FFULL) << 56) | (((x.x) & 0x000000000000FF00ULL) << 40) | + (((x.x) & 0x0000000000FF0000ULL) << 24) | (((x.x) & 0x00000000FF000000ULL) << 8) | + (((x.x) & 0x000000FF00000000ULL) >> 8) | (((x.x) & 0x0000FF0000000000ULL) >> 24) | + (((x.x) & 0x00FF000000000000ULL) >> 40) | (((x.x) & 0xFF00000000000000ULL) >> 56)); + return x; +} + +/* ---------------------------------------------------------------- */ + +// Credit to Henry S. Warren, Hacker's Delight, Addison-Wesley, 2002 +forceinline lane_t to_bit_interleaving(lane_t in) +{ + uint32_t lo = in.w[0]; + uint32_t hi = in.w[1]; + uint32_t r0, r1; + r0 = (lo ^ (lo >> 1)) & 0x22222222, lo ^= r0 ^ (r0 << 1); + r0 = (lo ^ (lo >> 2)) & 0x0C0C0C0C, lo ^= r0 ^ (r0 << 2); + r0 = (lo ^ (lo >> 4)) & 0x00F000F0, lo ^= r0 ^ (r0 << 4); + r0 = (lo ^ (lo >> 8)) & 0x0000FF00, lo ^= r0 ^ (r0 << 8); + r1 = (hi ^ (hi >> 1)) & 0x22222222, hi ^= r1 ^ (r1 << 1); + r1 = (hi ^ (hi >> 2)) & 0x0C0C0C0C, hi ^= r1 ^ (r1 << 2); + r1 = (hi ^ (hi >> 4)) & 0x00F000F0, hi ^= r1 ^ (r1 << 4); + r1 = (hi ^ (hi >> 8)) & 0x0000FF00, hi ^= r1 ^ (r1 << 8); + lane_t out; + out.w[0] = (lo & 0x0000FFFF) | (hi << 16); + out.w[1] = (lo >> 16) | (hi & 0xFFFF0000); + return out; +} + +/* ---------------------------------------------------------------- */ + +// Credit to Henry S. Warren, Hacker's Delight, Addison-Wesley, 2002 +forceinline lane_t from_bit_interleaving(lane_t in) +{ + uint32_t lo = ((in).w[0] & 0x0000FFFF) | ((in).w[1] << 16); + uint32_t hi = ((in).w[0] >> 16) | ((in).w[1] & 0xFFFF0000); + uint32_t r0, r1; + r0 = (lo ^ (lo >> 8)) & 0x0000FF00, lo ^= r0 ^ (r0 << 8); + r0 = (lo ^ (lo >> 4)) & 0x00F000F0, lo ^= r0 ^ (r0 << 4); + r0 = (lo ^ (lo >> 2)) & 0x0C0C0C0C, lo ^= r0 ^ (r0 << 2); + r0 = (lo ^ (lo >> 1)) & 0x22222222, lo ^= r0 ^ (r0 << 1); + r1 = (hi ^ (hi >> 8)) & 0x0000FF00, hi ^= r1 ^ (r1 << 8); + r1 = (hi ^ (hi >> 4)) & 0x00F000F0, hi ^= r1 ^ (r1 << 4); + r1 = (hi ^ (hi >> 2)) & 0x0C0C0C0C, hi ^= r1 ^ (r1 << 2); + r1 = (hi ^ (hi >> 1)) & 0x22222222, hi ^= r1 ^ (r1 << 1); + lane_t out; + out.x = (uint64_t)hi << 32 | lo; + return out; +} + +/* ---------------------------------------------------------------- */ + +forceinline void ROUND(state_t *s, uint64_t C) +{ + // Based on the round description of Ascon given in the Bachelor's + // thesis: "Optimizing Ascon on RISC-V" of Lars Jellema + // see https://github.com/Lucus16/ascon-riscv/ + uint32_t tmp0, tmp1, tmp2; + __asm__ __volatile__( + "eor %[x2_e], %[x2_e], %[C_e]\n\t" + "eor %[tmp0], %[x1_e], %[x2_e]\n\t" + "eor %[tmp1], %[x0_e], %[x4_e]\n\t" + "eor %[tmp2], %[x3_e], %[x4_e]\n\t" + "orn %[x4_e], %[x3_e], %[x4_e]\n\t" + "eor %[x4_e], %[x4_e], %[tmp0]\n\t" + "eor %[x3_e], %[x3_e], %[x1_e]\n\t" + "orr %[x3_e], %[x3_e], %[tmp0]\n\t" + "eor %[x3_e], %[x3_e], %[tmp1]\n\t" + "eor %[x2_e], %[x2_e], %[tmp1]\n\t" + "orr %[x2_e], %[x2_e], %[x1_e]\n\t" + "eor %[x2_e], %[x2_e], %[tmp2]\n\t" + "bic %[x1_e], %[x1_e], %[tmp1]\n\t" + "eor %[x1_e], %[x1_e], %[tmp2]\n\t" + "orr %[x0_e], %[x0_e], %[tmp2]\n\t" + "eor %[x0_e], %[x0_e], %[tmp0]\n\t" + "eor %[x2_o], %[x2_o], %[C_o]\n\t" + "eor %[tmp0], %[x1_o], %[x2_o]\n\t" + "eor %[tmp1], %[x0_o], %[x4_o]\n\t" + "eor %[tmp2], %[x3_o], %[x4_o]\n\t" + "orn %[x4_o], %[x3_o], %[x4_o]\n\t" + "eor %[x4_o], %[x4_o], %[tmp0]\n\t" + "eor %[x3_o], %[x3_o], %[x1_o]\n\t" + "orr %[x3_o], %[x3_o], %[tmp0]\n\t" + "eor %[x3_o], %[x3_o], %[tmp1]\n\t" + "eor %[x2_o], %[x2_o], %[tmp1]\n\t" + "orr %[x2_o], %[x2_o], %[x1_o]\n\t" + "eor %[x2_o], %[x2_o], %[tmp2]\n\t" + "bic %[x1_o], %[x1_o], %[tmp1]\n\t" + "eor %[x1_o], %[x1_o], %[tmp2]\n\t" + "orr %[x0_o], %[x0_o], %[tmp2]\n\t" + "eor %[x0_o], %[x0_o], %[tmp0]\n\t" + "eor %[tmp0], %[x2_e], %[x2_o], ror #4\n\t" + "eor %[tmp1], %[x2_o], %[x2_e], ror #5\n\t" + "eor %[x2_o], %[x2_o], %[tmp0], ror #10\n\t" + "eor %[x2_e], %[x2_e], %[tmp1], ror #9\n\t" + "eor %[tmp0], %[x3_e], %[x3_e], ror #11\n\t" + "eor %[tmp1], %[x3_o], %[x3_o], ror #11\n\t" + "eor %[x3_o], %[x3_o], %[tmp0], ror #20\n\t" + "eor %[x3_e], %[x3_e], %[tmp1], ror #19\n\t" + "eor %[tmp0], %[x4_e], %[x4_o], ror #2\n\t" + "eor %[tmp1], %[x4_o], %[x4_e], ror #3\n\t" + "eor %[x4_o], %[x4_o], %[tmp0], ror #1\n\t" + "eor %[x4_e], %[x4_e], %[tmp1]\n\t" + "eor %[tmp0], %[x0_e], %[x0_o], ror #3\n\t" + "eor %[tmp1], %[x0_o], %[x0_e], ror #4\n\t" + "eor %[x0_e], %[x0_e], %[tmp0], ror #5\n\t" + "eor %[x0_o], %[x0_o], %[tmp1], ror #5\n\t" + "eor %[tmp0], %[x1_e], %[x1_e], ror #17\n\t" + "eor %[tmp1], %[x1_o], %[x1_o], ror #17\n\t" + "eor %[x1_o], %[x1_o], %[tmp0], ror #4\n\t" + "eor %[x1_e], %[x1_e], %[tmp1], ror #3\n\t" + : [x0_e] "+r"(s->w[0][0]), [x0_o] "+r"(s->w[0][1]), + [x1_e] "+r"(s->w[1][0]), [x1_o] "+r"(s->w[1][1]), + [x2_e] "+r"(s->w[2][0]), [x2_o] "+r"(s->w[2][1]), + [x3_e] "+r"(s->w[3][0]), [x3_o] "+r"(s->w[3][1]), + [x4_e] "+r"(s->w[4][0]), [x4_o] "+r"(s->w[4][1]), [tmp0] "=r"(tmp0), + [tmp1] "=r"(tmp1), [tmp2] "=r"(tmp2) + : [C_e] "i"((uint32_t)C), [C_o] "i"((uint32_t)(C >> 32)) + :); +} + +/* ---------------------------------------------------------------- */ + +forceinline void P12ROUNDS(state_t *s) +{ + ROUND(s, 0xc0000000c); + ROUND(s, 0xc00000009); + ROUND(s, 0x90000000c); + ROUND(s, 0x900000009); + ROUND(s, 0xc00000006); + ROUND(s, 0xc00000003); + ROUND(s, 0x900000006); + ROUND(s, 0x900000003); + ROUND(s, 0x60000000c); + ROUND(s, 0x600000009); + ROUND(s, 0x30000000c); + ROUND(s, 0x300000009); +} + +/* ---------------------------------------------------------------- */ + +forceinline void P6ROUNDS(state_t *s) +{ + ROUND(s, 0x900000006); + ROUND(s, 0x900000003); + ROUND(s, 0x60000000c); + ROUND(s, 0x600000009); + ROUND(s, 0x30000000c); + ROUND(s, 0x300000009); +} + +/* ---------------------------------------------------------------- */ + +forceinline void P1ROUNDS(state_t *s) +{ + ROUND(s, 0x300000009); +} + +/* ---------------------------------------------------------------- */ + +#endif // ASCONP_H_ diff --git a/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv7m/config.h b/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv7m/config.h new file mode 100644 index 0000000..2e1c76f --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv7m/config.h @@ -0,0 +1,16 @@ +#ifndef CONFIG_H +#define CONFIG_H + +#define ENABLE_HASH 0 + +#include "isap.h" + +// ISAP-A-128a +const uint8_t ISAP_IV_A[] = {0x01, ISAP_K, ISAP_rH, ISAP_rB, ISAP_sH, ISAP_sB, ISAP_sE, ISAP_sK}; +const uint8_t ISAP_IV_KA[] = {0x02, ISAP_K, ISAP_rH, ISAP_rB, ISAP_sH, ISAP_sB, ISAP_sE, ISAP_sK}; +const uint8_t ISAP_IV_KE[] = {0x03, ISAP_K, ISAP_rH, ISAP_rB, ISAP_sH, ISAP_sB, ISAP_sE, ISAP_sK}; + +// Ascon-Hash +const uint8_t ASCON_HASH_IV[] = {0x00, 0x40, 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00}; + +#endif // CONFIG_H diff --git a/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv7m/crypto_aead.c b/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv7m/crypto_aead.c new file mode 120000 index 0000000..e4f019c --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv7m/crypto_aead.c @@ -0,0 +1 @@ +../bi_32/crypto_aead.c \ No newline at end of file diff --git a/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv7m/forceinline.h b/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv7m/forceinline.h new file mode 120000 index 0000000..c156e37 --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv7m/forceinline.h @@ -0,0 +1 @@ +../bi_32/forceinline.h \ No newline at end of file diff --git a/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv7m/isap.c b/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv7m/isap.c new file mode 120000 index 0000000..9b7816c --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv7m/isap.c @@ -0,0 +1 @@ +../bi_32/isap.c \ No newline at end of file diff --git a/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv7m/isap.h b/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv7m/isap.h new file mode 120000 index 0000000..6175b4f --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/bi_32_armv7m/isap.h @@ -0,0 +1 @@ +../bi_32/isap.h \ No newline at end of file diff --git a/isap/Implementations/crypto_aead/isapa128av20/bi_32_compact/api.h b/isap/Implementations/crypto_aead/isapa128av20/bi_32_compact/api.h new file mode 120000 index 0000000..ee9607d --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/bi_32_compact/api.h @@ -0,0 +1 @@ +../bi_32/api.h \ No newline at end of file diff --git a/isap/Implementations/crypto_aead/isapa128av20/bi_32_compact/asconp.h b/isap/Implementations/crypto_aead/isapa128av20/bi_32_compact/asconp.h new file mode 100644 index 0000000..5245d75 --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/bi_32_compact/asconp.h @@ -0,0 +1,170 @@ +#ifndef ASCONP_H_ +#define ASCONP_H_ + +#include +#include "forceinline.h" + +typedef union +{ + uint64_t x; + uint32_t w[2]; + uint8_t b[8]; +} lane_t; + +typedef union +{ + lane_t l[5]; + uint64_t x[5]; + uint32_t w[5][2]; + uint8_t b[5][8]; +} state_t; + +/* ---------------------------------------------------------------- */ + +#define P_sH PROUNDS(s, 12) +#define P_sB PROUNDS(s, 1) +#define P_sE PROUNDS(s, 6) +#define P_sK PROUNDS(s, 12) + +/* ---------------------------------------------------------------- */ + +#define U64TOWORD(x) to_bit_interleaving(U64BIG(x)) +#define WORDTOU64(x) U64BIG(from_bit_interleaving(x)) + +/* ---------------------------------------------------------------- */ + +#define TOBI(x) to_bit_interleaving(x) +#define FROMBI(x) from_bit_interleaving(x) + +/* ---------------------------------------------------------------- */ + +lane_t U64BIG(lane_t x) +{ + x.x = ((((x.x) & 0x00000000000000FFULL) << 56) | (((x.x) & 0x000000000000FF00ULL) << 40) | + (((x.x) & 0x0000000000FF0000ULL) << 24) | (((x.x) & 0x00000000FF000000ULL) << 8) | + (((x.x) & 0x000000FF00000000ULL) >> 8) | (((x.x) & 0x0000FF0000000000ULL) >> 24) | + (((x.x) & 0x00FF000000000000ULL) >> 40) | (((x.x) & 0xFF00000000000000ULL) >> 56)); + return x; +} + +/* ---------------------------------------------------------------- */ + +// Credit to Henry S. Warren, Hacker's Delight, Addison-Wesley, 2002 +lane_t to_bit_interleaving(lane_t in) +{ + uint32_t lo = in.w[0]; + uint32_t hi = in.w[1]; + uint32_t r0, r1; + r0 = (lo ^ (lo >> 1)) & 0x22222222, lo ^= r0 ^ (r0 << 1); + r0 = (lo ^ (lo >> 2)) & 0x0C0C0C0C, lo ^= r0 ^ (r0 << 2); + r0 = (lo ^ (lo >> 4)) & 0x00F000F0, lo ^= r0 ^ (r0 << 4); + r0 = (lo ^ (lo >> 8)) & 0x0000FF00, lo ^= r0 ^ (r0 << 8); + r1 = (hi ^ (hi >> 1)) & 0x22222222, hi ^= r1 ^ (r1 << 1); + r1 = (hi ^ (hi >> 2)) & 0x0C0C0C0C, hi ^= r1 ^ (r1 << 2); + r1 = (hi ^ (hi >> 4)) & 0x00F000F0, hi ^= r1 ^ (r1 << 4); + r1 = (hi ^ (hi >> 8)) & 0x0000FF00, hi ^= r1 ^ (r1 << 8); + lane_t out; + out.w[0] = (lo & 0x0000FFFF) | (hi << 16); + out.w[1] = (lo >> 16) | (hi & 0xFFFF0000); + return out; +} + +/* ---------------------------------------------------------------- */ + +// Credit to Henry S. Warren, Hacker's Delight, Addison-Wesley, 2002 +lane_t from_bit_interleaving(lane_t in) +{ + uint32_t lo = ((in).w[0] & 0x0000FFFF) | ((in).w[1] << 16); + uint32_t hi = ((in).w[0] >> 16) | ((in).w[1] & 0xFFFF0000); + uint32_t r0, r1; + r0 = (lo ^ (lo >> 8)) & 0x0000FF00, lo ^= r0 ^ (r0 << 8); + r0 = (lo ^ (lo >> 4)) & 0x00F000F0, lo ^= r0 ^ (r0 << 4); + r0 = (lo ^ (lo >> 2)) & 0x0C0C0C0C, lo ^= r0 ^ (r0 << 2); + r0 = (lo ^ (lo >> 1)) & 0x22222222, lo ^= r0 ^ (r0 << 1); + r1 = (hi ^ (hi >> 8)) & 0x0000FF00, hi ^= r1 ^ (r1 << 8); + r1 = (hi ^ (hi >> 4)) & 0x00F000F0, hi ^= r1 ^ (r1 << 4); + r1 = (hi ^ (hi >> 2)) & 0x0C0C0C0C, hi ^= r1 ^ (r1 << 2); + r1 = (hi ^ (hi >> 1)) & 0x22222222, hi ^= r1 ^ (r1 << 1); + lane_t out; + out.x = (uint64_t)hi << 32 | lo; + return out; +} + +/* ---------------------------------------------------------------- */ + +forceinline uint32_t ROR32(uint32_t x, int n) +{ + return x >> n | x << (-n & 31); +} + +/* ---------------------------------------------------------------- */ + +forceinline uint64_t ROR(uint64_t x, int n) +{ + lane_t b, a = {.x = x}; + b.w[0] = (n % 2) ? ROR32(a.w[1], (n - 1) / 2) : ROR32(a.w[0], n / 2); + b.w[1] = (n % 2) ? ROR32(a.w[0], (n + 1) / 2) : ROR32(a.w[1], n / 2); + return b.x; +} + +/* ---------------------------------------------------------------- */ + +forceinline void ROUND(state_t *s, uint64_t C) +{ + state_t t; + /* round constant */ + s->x[2] ^= C; + /* s-box layer */ + s->x[0] ^= s->x[4]; + s->x[4] ^= s->x[3]; + s->x[2] ^= s->x[1]; + t.x[0] = s->x[0] ^ (~s->x[1] & s->x[2]); + t.x[2] = s->x[2] ^ (~s->x[3] & s->x[4]); + t.x[4] = s->x[4] ^ (~s->x[0] & s->x[1]); + t.x[1] = s->x[1] ^ (~s->x[2] & s->x[3]); + t.x[3] = s->x[3] ^ (~s->x[4] & s->x[0]); + t.x[1] ^= t.x[0]; + t.x[3] ^= t.x[2]; + t.x[0] ^= t.x[4]; + /* linear layer */ + s->x[2] = t.x[2] ^ ROR(t.x[2], 6 - 1); + s->x[3] = t.x[3] ^ ROR(t.x[3], 17 - 10); + s->x[4] = t.x[4] ^ ROR(t.x[4], 41 - 7); + s->x[0] = t.x[0] ^ ROR(t.x[0], 28 - 19); + s->x[1] = t.x[1] ^ ROR(t.x[1], 61 - 39); + s->x[2] = t.x[2] ^ ROR(s->x[2], 1); + s->x[3] = t.x[3] ^ ROR(s->x[3], 10); + s->x[4] = t.x[4] ^ ROR(s->x[4], 7); + s->x[0] = t.x[0] ^ ROR(s->x[0], 19); + s->x[1] = t.x[1] ^ ROR(s->x[1], 39); + s->x[2] = ~s->x[2]; +} + +/* ---------------------------------------------------------------- */ + +void PROUNDS(state_t *s, uint8_t nr) +{ + switch (nr) + { + case 12: + ROUND(s, 0xc0000000c); + ROUND(s, 0xc00000009); + ROUND(s, 0x90000000c); + ROUND(s, 0x900000009); + ROUND(s, 0xc00000006); + ROUND(s, 0xc00000003); + case 6: + ROUND(s, 0x900000006); + ROUND(s, 0x900000003); + ROUND(s, 0x60000000c); + ROUND(s, 0x600000009); + ROUND(s, 0x30000000c); + default: + ROUND(s, 0x300000009); + ; + } +} + +/* ---------------------------------------------------------------- */ + +#endif // ASCONP_H diff --git a/isap/Implementations/crypto_aead/isapa128av20/bi_32_compact/config.h b/isap/Implementations/crypto_aead/isapa128av20/bi_32_compact/config.h new file mode 100644 index 0000000..2e1c76f --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/bi_32_compact/config.h @@ -0,0 +1,16 @@ +#ifndef CONFIG_H +#define CONFIG_H + +#define ENABLE_HASH 0 + +#include "isap.h" + +// ISAP-A-128a +const uint8_t ISAP_IV_A[] = {0x01, ISAP_K, ISAP_rH, ISAP_rB, ISAP_sH, ISAP_sB, ISAP_sE, ISAP_sK}; +const uint8_t ISAP_IV_KA[] = {0x02, ISAP_K, ISAP_rH, ISAP_rB, ISAP_sH, ISAP_sB, ISAP_sE, ISAP_sK}; +const uint8_t ISAP_IV_KE[] = {0x03, ISAP_K, ISAP_rH, ISAP_rB, ISAP_sH, ISAP_sB, ISAP_sE, ISAP_sK}; + +// Ascon-Hash +const uint8_t ASCON_HASH_IV[] = {0x00, 0x40, 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00}; + +#endif // CONFIG_H diff --git a/isap/Implementations/crypto_aead/isapa128av20/bi_32_compact/crypto_aead.c b/isap/Implementations/crypto_aead/isapa128av20/bi_32_compact/crypto_aead.c new file mode 120000 index 0000000..e4f019c --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/bi_32_compact/crypto_aead.c @@ -0,0 +1 @@ +../bi_32/crypto_aead.c \ No newline at end of file diff --git a/isap/Implementations/crypto_aead/isapa128av20/bi_32_compact/forceinline.h b/isap/Implementations/crypto_aead/isapa128av20/bi_32_compact/forceinline.h new file mode 120000 index 0000000..c156e37 --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/bi_32_compact/forceinline.h @@ -0,0 +1 @@ +../bi_32/forceinline.h \ No newline at end of file diff --git a/isap/Implementations/crypto_aead/isapa128av20/bi_32_compact/isap.c b/isap/Implementations/crypto_aead/isapa128av20/bi_32_compact/isap.c new file mode 120000 index 0000000..9b7816c --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/bi_32_compact/isap.c @@ -0,0 +1 @@ +../bi_32/isap.c \ No newline at end of file diff --git a/isap/Implementations/crypto_aead/isapa128av20/bi_32_compact/isap.h b/isap/Implementations/crypto_aead/isapa128av20/bi_32_compact/isap.h new file mode 120000 index 0000000..6175b4f --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/bi_32_compact/isap.h @@ -0,0 +1 @@ +../bi_32/isap.h \ No newline at end of file diff --git a/isap/Implementations/crypto_aead/isapa128av20/bi_32_stp/api.h b/isap/Implementations/crypto_aead/isapa128av20/bi_32_stp/api.h new file mode 120000 index 0000000..ee9607d --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/bi_32_stp/api.h @@ -0,0 +1 @@ +../bi_32/api.h \ No newline at end of file diff --git a/isap/Implementations/crypto_aead/isapa128av20/bi_32_stp/asconp.h b/isap/Implementations/crypto_aead/isapa128av20/bi_32_stp/asconp.h new file mode 100644 index 0000000..4613a85 --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/bi_32_stp/asconp.h @@ -0,0 +1,172 @@ +#ifndef ASCONP_H_ +#define ASCONP_H_ + +#include +#include "forceinline.h" + +typedef union +{ + uint64_t x; + uint32_t w[2]; + uint8_t b[8]; +} lane_t; + +typedef union +{ + lane_t l[5]; + uint64_t x[5]; + uint32_t w[5][2]; + uint8_t b[5][8]; +} state_t; + +/* ---------------------------------------------------------------- */ + +#define P_sH PROUNDS(s, 12) +#define P_sB PROUNDS(s, 1) +#define P_sE PROUNDS(s, 6) +#define P_sK PROUNDS(s, 12) +#define P_PVP PROUNDS(s, 7) + +/* ---------------------------------------------------------------- */ + +#define U64TOWORD(x) to_bit_interleaving(U64BIG(x)) +#define WORDTOU64(x) U64BIG(from_bit_interleaving(x)) + +/* ---------------------------------------------------------------- */ + +#define TOBI(x) to_bit_interleaving(x) +#define FROMBI(x) from_bit_interleaving(x) + +/* ---------------------------------------------------------------- */ + +lane_t U64BIG(lane_t x) +{ + x.x = ((((x.x) & 0x00000000000000FFULL) << 56) | (((x.x) & 0x000000000000FF00ULL) << 40) | + (((x.x) & 0x0000000000FF0000ULL) << 24) | (((x.x) & 0x00000000FF000000ULL) << 8) | + (((x.x) & 0x000000FF00000000ULL) >> 8) | (((x.x) & 0x0000FF0000000000ULL) >> 24) | + (((x.x) & 0x00FF000000000000ULL) >> 40) | (((x.x) & 0xFF00000000000000ULL) >> 56)); + return x; +} + +/* ---------------------------------------------------------------- */ + +// Credit to Henry S. Warren, Hacker's Delight, Addison-Wesley, 2002 +lane_t to_bit_interleaving(lane_t in) +{ + uint32_t lo = in.w[0]; + uint32_t hi = in.w[1]; + uint32_t r0, r1; + r0 = (lo ^ (lo >> 1)) & 0x22222222, lo ^= r0 ^ (r0 << 1); + r0 = (lo ^ (lo >> 2)) & 0x0C0C0C0C, lo ^= r0 ^ (r0 << 2); + r0 = (lo ^ (lo >> 4)) & 0x00F000F0, lo ^= r0 ^ (r0 << 4); + r0 = (lo ^ (lo >> 8)) & 0x0000FF00, lo ^= r0 ^ (r0 << 8); + r1 = (hi ^ (hi >> 1)) & 0x22222222, hi ^= r1 ^ (r1 << 1); + r1 = (hi ^ (hi >> 2)) & 0x0C0C0C0C, hi ^= r1 ^ (r1 << 2); + r1 = (hi ^ (hi >> 4)) & 0x00F000F0, hi ^= r1 ^ (r1 << 4); + r1 = (hi ^ (hi >> 8)) & 0x0000FF00, hi ^= r1 ^ (r1 << 8); + lane_t out; + out.w[0] = (lo & 0x0000FFFF) | (hi << 16); + out.w[1] = (lo >> 16) | (hi & 0xFFFF0000); + return out; +} + +/* ---------------------------------------------------------------- */ + +// Credit to Henry S. Warren, Hacker's Delight, Addison-Wesley, 2002 +lane_t from_bit_interleaving(lane_t in) +{ + uint32_t lo = ((in).w[0] & 0x0000FFFF) | ((in).w[1] << 16); + uint32_t hi = ((in).w[0] >> 16) | ((in).w[1] & 0xFFFF0000); + uint32_t r0, r1; + r0 = (lo ^ (lo >> 8)) & 0x0000FF00, lo ^= r0 ^ (r0 << 8); + r0 = (lo ^ (lo >> 4)) & 0x00F000F0, lo ^= r0 ^ (r0 << 4); + r0 = (lo ^ (lo >> 2)) & 0x0C0C0C0C, lo ^= r0 ^ (r0 << 2); + r0 = (lo ^ (lo >> 1)) & 0x22222222, lo ^= r0 ^ (r0 << 1); + r1 = (hi ^ (hi >> 8)) & 0x0000FF00, hi ^= r1 ^ (r1 << 8); + r1 = (hi ^ (hi >> 4)) & 0x00F000F0, hi ^= r1 ^ (r1 << 4); + r1 = (hi ^ (hi >> 2)) & 0x0C0C0C0C, hi ^= r1 ^ (r1 << 2); + r1 = (hi ^ (hi >> 1)) & 0x22222222, hi ^= r1 ^ (r1 << 1); + lane_t out; + out.x = (uint64_t)hi << 32 | lo; + return out; +} + +/* ---------------------------------------------------------------- */ + +forceinline uint32_t ROR32(uint32_t x, int n) +{ + return x >> n | x << (-n & 31); +} + +/* ---------------------------------------------------------------- */ + +forceinline uint64_t ROR(uint64_t x, int n) +{ + lane_t b, a = {.x = x}; + b.w[0] = (n % 2) ? ROR32(a.w[1], (n - 1) / 2) : ROR32(a.w[0], n / 2); + b.w[1] = (n % 2) ? ROR32(a.w[0], (n + 1) / 2) : ROR32(a.w[1], n / 2); + return b.x; +} + +/* ---------------------------------------------------------------- */ + +forceinline void ROUND(state_t *s, uint64_t C) +{ + state_t t; + /* round constant */ + s->x[2] ^= C; + /* s-box layer */ + s->x[0] ^= s->x[4]; + s->x[4] ^= s->x[3]; + s->x[2] ^= s->x[1]; + t.x[0] = s->x[0] ^ (~s->x[1] & s->x[2]); + t.x[2] = s->x[2] ^ (~s->x[3] & s->x[4]); + t.x[4] = s->x[4] ^ (~s->x[0] & s->x[1]); + t.x[1] = s->x[1] ^ (~s->x[2] & s->x[3]); + t.x[3] = s->x[3] ^ (~s->x[4] & s->x[0]); + t.x[1] ^= t.x[0]; + t.x[3] ^= t.x[2]; + t.x[0] ^= t.x[4]; + /* linear layer */ + s->x[2] = t.x[2] ^ ROR(t.x[2], 6 - 1); + s->x[3] = t.x[3] ^ ROR(t.x[3], 17 - 10); + s->x[4] = t.x[4] ^ ROR(t.x[4], 41 - 7); + s->x[0] = t.x[0] ^ ROR(t.x[0], 28 - 19); + s->x[1] = t.x[1] ^ ROR(t.x[1], 61 - 39); + s->x[2] = t.x[2] ^ ROR(s->x[2], 1); + s->x[3] = t.x[3] ^ ROR(s->x[3], 10); + s->x[4] = t.x[4] ^ ROR(s->x[4], 7); + s->x[0] = t.x[0] ^ ROR(s->x[0], 19); + s->x[1] = t.x[1] ^ ROR(s->x[1], 39); + s->x[2] = ~s->x[2]; +} + +/* ---------------------------------------------------------------- */ + +void PROUNDS(state_t *s, uint8_t nr) +{ + switch (nr) + { + case 12: + ROUND(s, 0xc0000000c); + ROUND(s, 0xc00000009); + ROUND(s, 0x90000000c); + ROUND(s, 0x900000009); + ROUND(s, 0xc00000006); + case 7: + ROUND(s, 0xc00000003); + case 6: + ROUND(s, 0x900000006); + ROUND(s, 0x900000003); + ROUND(s, 0x60000000c); + ROUND(s, 0x600000009); + ROUND(s, 0x30000000c); + default: + ROUND(s, 0x300000009); + ; + } +} + +/* ---------------------------------------------------------------- */ + +#endif // ASCONP_H diff --git a/isap/Implementations/crypto_aead/isapa128av20/bi_32_stp/config.h b/isap/Implementations/crypto_aead/isapa128av20/bi_32_stp/config.h new file mode 100644 index 0000000..2e1c76f --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/bi_32_stp/config.h @@ -0,0 +1,16 @@ +#ifndef CONFIG_H +#define CONFIG_H + +#define ENABLE_HASH 0 + +#include "isap.h" + +// ISAP-A-128a +const uint8_t ISAP_IV_A[] = {0x01, ISAP_K, ISAP_rH, ISAP_rB, ISAP_sH, ISAP_sB, ISAP_sE, ISAP_sK}; +const uint8_t ISAP_IV_KA[] = {0x02, ISAP_K, ISAP_rH, ISAP_rB, ISAP_sH, ISAP_sB, ISAP_sE, ISAP_sK}; +const uint8_t ISAP_IV_KE[] = {0x03, ISAP_K, ISAP_rH, ISAP_rB, ISAP_sH, ISAP_sB, ISAP_sE, ISAP_sK}; + +// Ascon-Hash +const uint8_t ASCON_HASH_IV[] = {0x00, 0x40, 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00}; + +#endif // CONFIG_H diff --git a/isap/Implementations/crypto_aead/isapa128av20/bi_32_stp/crypto_aead.c b/isap/Implementations/crypto_aead/isapa128av20/bi_32_stp/crypto_aead.c new file mode 100644 index 0000000..e0d533c --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/bi_32_stp/crypto_aead.c @@ -0,0 +1,68 @@ +#include "api.h" +#include "isap.h" +#include "crypto_aead.h" + +int crypto_aead_encrypt( + unsigned char *c, unsigned long long *clen, + const unsigned char *m, unsigned long long mlen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k) +{ + (void)nsec; + + // Ciphertext length is mlen + tag length + *clen = mlen + ISAP_TAG_SZ; + + // Encrypt plaintext + if (mlen > 0) + { + isap_enc(k, npub, m, mlen, c); + } + + // Generate tag + unsigned char *tag = c + mlen; + isap_mac(k, npub, ad, adlen, c, mlen, tag); + return 0; +} + +int crypto_aead_decrypt( + unsigned char *m, unsigned long long *mlen, + unsigned char *nsec, + const unsigned char *c, unsigned long long clen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) +{ + (void)nsec; + + // Plaintext length is clen - tag length + *mlen = clen - ISAP_TAG_SZ; + + // Generate tag + unsigned char T[16]; + isap_mac(k, npub, ad, adlen, c, *mlen, T); + + // Compare tag + unsigned char T_star[16]; + for (int i = 0; i < 16; i++) + { + T_star[i] = *(c + *mlen + i); + } + int eq_cnt = pvp(T, T_star); + + // Perform decryption if tag is correct + if (eq_cnt == ISAP_TAG_SZ) + { + if (*mlen > 0) + { + isap_enc(k, npub, c, *mlen, m); + } + return 0; + } + else + { + return -1; + } +} diff --git a/isap/Implementations/crypto_aead/isapa128av20/bi_32_stp/forceinline.h b/isap/Implementations/crypto_aead/isapa128av20/bi_32_stp/forceinline.h new file mode 120000 index 0000000..c156e37 --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/bi_32_stp/forceinline.h @@ -0,0 +1 @@ +../bi_32/forceinline.h \ No newline at end of file diff --git a/isap/Implementations/crypto_aead/isapa128av20/bi_32_stp/isap.c b/isap/Implementations/crypto_aead/isapa128av20/bi_32_stp/isap.c new file mode 100644 index 0000000..2fa2aed --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/bi_32_stp/isap.c @@ -0,0 +1,276 @@ +#include +#include +#include "api.h" +#include "isap.h" +#include "asconp.h" +#include "config.h" + +// Needed for LR tag comparison +uint64_t s0, s1; + +forceinline void ABSORB_LANES(state_t *s, const uint8_t *src, uint64_t len) +{ + while (len >= 8) + { + // Absorb full lanes + lane_t t0 = U64TOWORD(*(lane_t *)(src + 0)); + s->x[0] ^= t0.x; + len -= ISAP_rH / 8; + src += ISAP_rH / 8; + P_sH; + } + + if (len > 0) + { + // Absorb partial lane and padding + size_t i; + lane_t t0 = {0}; + for (i = 0; i < len; i++) + { + t0.b[7 - i] ^= *src; + src++; + } + t0.b[7 - i] ^= 0x80; + t0 = TOBI(t0); + s->x[0] ^= t0.x; + P_sH; + } + else + { + // Absorb padded empty lane + s->b[0][7] ^= 0x80; + P_sH; + } +} + +/******************************************************************************/ +/* ISAP_RK */ +/******************************************************************************/ + +void isap_rk( + const uint8_t *k, + const uint8_t *iv, + const uint8_t *y, + state_t *out, + const size_t outlen) +{ + state_t state; + state_t *s = &state; + + // Initialize + s->l[0] = U64TOWORD(*(lane_t *)(k + 0)); + s->l[1] = U64TOWORD(*(lane_t *)(k + 8)); + s->l[2] = U64TOWORD(*(lane_t *)(iv + 0)); + s->x[3] = 0; + s->x[4] = 0; + P_sK; + + // Absorb Y, bit by bit + for (size_t i = 0; i < 16; i++) + { + uint8_t y_byte = *y; + s->b[0][7] ^= (y_byte & 0x80) << 0; + P_sB; + s->b[0][7] ^= (y_byte & 0x40) << 1; + P_sB; + s->b[0][7] ^= (y_byte & 0x20) << 2; + P_sB; + s->b[0][7] ^= (y_byte & 0x10) << 3; + P_sB; + s->b[0][7] ^= (y_byte & 0x08) << 4; + P_sB; + s->b[0][7] ^= (y_byte & 0x04) << 5; + P_sB; + s->b[0][7] ^= (y_byte & 0x02) << 6; + P_sB; + s->b[0][7] ^= (y_byte & 0x01) << 7; + if (i != 15) + { + P_sB; + y += 1; + } + } + + // Squeeze K* + P_sK; + out->x[0] = s->x[0]; + out->x[1] = s->x[1]; + if (outlen > 16) + { + out->x[2] = s->x[2]; + } +} + +/******************************************************************************/ +/* ISAP_MAC */ +/******************************************************************************/ + +void isap_mac( + const uint8_t *k, + const uint8_t *npub, + const uint8_t *ad, uint64_t adlen, + const uint8_t *c, uint64_t clen, + uint8_t *tag) +{ + state_t state; + state_t *s = &state; + + // Initialize + s->l[0] = U64TOWORD(*(lane_t *)(npub + 0)); + s->l[1] = U64TOWORD(*(lane_t *)(npub + 8)); + s->l[2] = U64TOWORD(*(lane_t *)(ISAP_IV_A + 0)); + s->x[3] = 0; + s->x[4] = 0; + P_sH; + + // Absorb associated data + ABSORB_LANES(s, ad, adlen); + + // Domain seperation + s->w[4][0] ^= 0x1UL; + + // Absorb ciphertext + ABSORB_LANES(s, c, clen); + + // Needed for LR tag comparison + s0 = s->x[0]; + s1 = s->x[1]; + + // Derive KA* + s->l[0] = WORDTOU64(s->l[0]); + s->l[1] = WORDTOU64(s->l[1]); + isap_rk(k, ISAP_IV_KA, (const uint8_t *)(s->b), s, CRYPTO_KEYBYTES); + + // Squeeze tag + P_sH; + lane_t t0 = WORDTOU64(s->l[0]); + memcpy(tag + 0, t0.b, 8); + t0 = WORDTOU64(s->l[1]); + memcpy(tag + 8, t0.b, 8); +} + +/******************************************************************************/ +/* Leakage resilient tag comparison. */ +/* Similar to Fig.3 of https://eprint.iacr.org/2021/402.pdf. */ +/******************************************************************************/ + +int pvp( + const uint8_t *T, const uint8_t *T_star) +{ + state_t state; + state_t *s = &state; + + // Calculate U + s->l[0] = U64TOWORD(*(lane_t *)(T + 0)); + s->l[1] = U64TOWORD(*(lane_t *)(T + 8)); + s->x[2] = s0; + s->x[3] = s1; + s->x[4] = 0; + P_PVP; + uint64_t u0, u1; + u0 = s->x[0]; + u1 = s->x[1]; + + // Calculate U' + s->l[0] = U64TOWORD(*(lane_t *)(T_star + 0)); + s->l[1] = U64TOWORD(*(lane_t *)(T_star + 8)); + s->x[2] = s0; + s->x[3] = s1; + s->x[4] = 0; + P_PVP; + + // Compare tag + int eq_cnt = 0; + for (size_t i = 0; i < 8; i++) + { + eq_cnt += (s->b[0][i] == ((uint8_t *)&u0)[i]); + } + for (size_t i = 0; i < 8; i++) + { + eq_cnt += (s->b[1][i] == ((uint8_t *)&u1)[i]); + } + return eq_cnt; +} + +/******************************************************************************/ +/* ISAP_ENC */ +/******************************************************************************/ + +void isap_enc( + const uint8_t *k, + const uint8_t *npub, + const uint8_t *m, uint64_t mlen, + uint8_t *c) + +{ + state_t state; + state_t *s = &state; + + // Init state + isap_rk(k, ISAP_IV_KE, npub, s, ISAP_STATE_SZ - CRYPTO_NPUBBYTES); + s->l[3] = U64TOWORD(*(lane_t *)(npub + 0)); + s->l[4] = U64TOWORD(*(lane_t *)(npub + 8)); + + while (mlen >= ISAP_rH / 8) + { + // Encrypt full lanes + P_sE; + lane_t t0 = WORDTOU64(s->l[0]); + *(uint64_t *)c = *(uint64_t *)m ^ t0.x; + mlen -= ISAP_rH / 8; + m += ISAP_rH / 8; + c += ISAP_rH / 8; + } + + if (mlen > 0) + { + // Encrypt partial lanes + P_sE; + lane_t t0 = WORDTOU64(s->l[0]); + for (uint8_t i = 0; i < mlen; i++) + { + *c = *m ^ t0.b[i]; + m += 1; + c += 1; + } + } +} + +/******************************************************************************/ +/* Ascon-Hash */ +/******************************************************************************/ + +#if ENABLE_HASH == 1 + +int crypto_hash(uint8_t *out, const uint8_t *in, unsigned long long inlen) +{ + + state_t state; + state_t *s = &state; + + // Initialize + s->l[0] = U64TOWORD(*(lane_t *)(ASCON_HASH_IV + 0)); + s->x[1] = 0; + s->x[2] = 0; + s->x[3] = 0; + s->x[4] = 0; + P_sH; + + // Absorb input + ABSORB_LANES(s, in, inlen); + + for (size_t i = 0; i < 4; i++) + { + // Squeeze full lanes + lane_t t0 = WORDTOU64(s->l[0]); + *(uint64_t *)(out + 8 * i) = t0.x; + if (i < 3) + { + P_sH; + } + } + + return 0; +} + +#endif diff --git a/isap/Implementations/crypto_aead/isapa128av20/bi_32_stp/isap.h b/isap/Implementations/crypto_aead/isapa128av20/bi_32_stp/isap.h new file mode 100644 index 0000000..ae37dcd --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/bi_32_stp/isap.h @@ -0,0 +1,49 @@ +#ifndef ISAP_H +#define ISAP_H + +#include + +// Rate in bits +#define ISAP_rH 64 +#define ISAP_rB 1 + +// Number of rounds +#define ISAP_sH 12 +#define ISAP_sB 1 +#define ISAP_sE 6 +#define ISAP_sK 12 + +// State size in bytes +#define ISAP_STATE_SZ 40 + +// Size of rate in bytes +#define ISAP_rH_SZ ((ISAP_rH + 7) / 8) + +// Size of zero truncated IV in bytes +#define ISAP_IV_SZ 8 + +// Size of tag in bytes +#define ISAP_TAG_SZ 16 + +// Security level +#define ISAP_K 128 + +void isap_mac( + const uint8_t *k, + const uint8_t *npub, + const uint8_t *ad, const uint64_t adlen, + const uint8_t *c, const uint64_t clen, + uint8_t *tag); + +int pvp( + const unsigned char *T, + const unsigned char *T_star); + +void isap_enc( + const uint8_t *k, + const uint8_t *npub, + const uint8_t *m, const uint64_t mlen, + uint8_t *c); + +#endif + diff --git a/isap/Implementations/crypto_aead/isapa128av20/bi_8/api.h b/isap/Implementations/crypto_aead/isapa128av20/bi_8/api.h new file mode 100644 index 0000000..83ebf98 --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/bi_8/api.h @@ -0,0 +1,16 @@ +#ifndef API_H +#define API_H + +// isapa128a +#define CRYPTO_KEYBYTES 16 +#define CRYPTO_NSECBYTES 0 +#define CRYPTO_NPUBBYTES 16 +#define CRYPTO_ABYTES 16 +#define CRYPTO_NOOVERLAP 1 + +// asconhashv12 +#define CRYPTO_BYTES 32 +#define ASCON_HASH_OUTLEN 32 +#define ASCON_HASH_ROUNDS 12 + +#endif diff --git a/isap/Implementations/crypto_aead/isapa128av20/bi_8/asconp.h b/isap/Implementations/crypto_aead/isapa128av20/bi_8/asconp.h new file mode 100644 index 0000000..fe1c322 --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/bi_8/asconp.h @@ -0,0 +1,144 @@ +#ifndef ASCONP_H +#define ASCONP_H + +#include +#include "forceinline.h" + +typedef union +{ + uint64_t x; + uint32_t w[2]; + uint8_t b[8]; +} lane_t; + +typedef union +{ + lane_t l[5]; + uint64_t x[5]; + uint32_t w[5][2]; + uint8_t b[5][8]; +} state_t; + +/* ---------------------------------------------------------------- */ + +#define P_sH PROUNDS(s, 12) +#define P_sB PROUNDS(s, 1) +#define P_sE PROUNDS(s, 6) +#define P_sK PROUNDS(s, 12) + +/* ---------------------------------------------------------------- */ + +#define U64TOWORD(x) interleave8(U64BIG(x)) +#define WORDTOU64(x) U64BIG(interleave8(x)) + +/* ---------------------------------------------------------------- */ + +#define TOBI(x) interleave8(x) +#define FROMBI(x) interleave8(x) + +/* ---------------------------------------------------------------- */ + +lane_t U64BIG(lane_t x) +{ + x.x = ((((x.x) & 0x00000000000000FFULL) << 56) | (((x.x) & 0x000000000000FF00ULL) << 40) | + (((x.x) & 0x0000000000FF0000ULL) << 24) | (((x.x) & 0x00000000FF000000ULL) << 8) | + (((x.x) & 0x000000FF00000000ULL) >> 8) | (((x.x) & 0x0000FF0000000000ULL) >> 24) | + (((x.x) & 0x00FF000000000000ULL) >> 40) | (((x.x) & 0xFF00000000000000ULL) >> 56)); + return x; +} + +/* ---------------------------------------------------------------- */ + +forceinline uint8_t ROR8(uint8_t a, int n) { return a >> n | a << (8 - n); } + +/* ---------------------------------------------------------------- */ + +forceinline uint64_t ROR(uint64_t x, int n) +{ + lane_t b, a = {.x = x}; + b.b[0] = ROR8(a.b[(n + 0) & 0x7], (n + 0) >> 3); + b.b[1] = ROR8(a.b[(n + 1) & 0x7], (n + 1) >> 3); + b.b[2] = ROR8(a.b[(n + 2) & 0x7], (n + 2) >> 3); + b.b[3] = ROR8(a.b[(n + 3) & 0x7], (n + 3) >> 3); + b.b[4] = ROR8(a.b[(n + 4) & 0x7], (n + 4) >> 3); + b.b[5] = ROR8(a.b[(n + 5) & 0x7], (n + 5) >> 3); + b.b[6] = ROR8(a.b[(n + 6) & 0x7], (n + 6) >> 3); + b.b[7] = ROR8(a.b[(n + 7) & 0x7], (n + 7) >> 3); + return b.x; +} + +/* ---------------------------------------------------------------- */ + +/* credit to Henry S. Warren, Hacker's Delight, Addison-Wesley, 2002 */ +forceinline lane_t interleave8(lane_t x) +{ + x.x = (x.x & 0xaa55aa55aa55aa55ull) | ((x.x & 0x00aa00aa00aa00aaull) << 7) | + ((x.x >> 7) & 0x00aa00aa00aa00aaull); + x.x = (x.x & 0xcccc3333cccc3333ull) | ((x.x & 0x0000cccc0000ccccull) << 14) | + ((x.x >> 14) & 0x0000cccc0000ccccull); + x.x = (x.x & 0xf0f0f0f00f0f0f0full) | ((x.x & 0x00000000f0f0f0f0ull) << 28) | + ((x.x >> 28) & 0x00000000f0f0f0f0ull); + return x; +} + +/* ---------------------------------------------------------------- */ + +forceinline void ROUND(state_t *s, uint64_t C) +{ + uint64_t xtemp; + /* round constant */ + s->x[2] ^= C; + /* s-box layer */ + s->x[0] ^= s->x[4]; + s->x[4] ^= s->x[3]; + s->x[2] ^= s->x[1]; + xtemp = s->x[0] & ~s->x[4]; + s->x[0] ^= s->x[2] & ~s->x[1]; + s->x[2] ^= s->x[4] & ~s->x[3]; + s->x[4] ^= s->x[1] & ~s->x[0]; + s->x[1] ^= s->x[3] & ~s->x[2]; + s->x[3] ^= xtemp; + s->x[1] ^= s->x[0]; + s->x[3] ^= s->x[2]; + s->x[0] ^= s->x[4]; + /* linear layer */ + xtemp = s->x[0] ^ ROR(s->x[0], 28 - 19); + s->x[0] ^= ROR(xtemp, 19); + xtemp = s->x[1] ^ ROR(s->x[1], 61 - 39); + s->x[1] ^= ROR(xtemp, 39); + xtemp = s->x[2] ^ ROR(s->x[2], 6 - 1); + s->x[2] ^= ROR(xtemp, 1); + xtemp = s->x[3] ^ ROR(s->x[3], 17 - 10); + s->x[3] ^= ROR(xtemp, 10); + xtemp = s->x[4] ^ ROR(s->x[4], 41 - 7); + s->x[4] ^= ROR(xtemp, 7); + s->x[2] = ~s->x[2]; +} + +/* ---------------------------------------------------------------- */ + +void PROUNDS(state_t *s, uint8_t nr) +{ + switch (nr) + { + case 12: + ROUND(s, 0x0101010100000000ull); + ROUND(s, 0x0101010000000001ull); + ROUND(s, 0x0101000100000100ull); + ROUND(s, 0x0101000000000101ull); + ROUND(s, 0x0100010100010000ull); + ROUND(s, 0x0100010000010001ull); + case 6: + ROUND(s, 0x0100000100010100ull); + ROUND(s, 0x0100000000010101ull); + ROUND(s, 0x0001010101000000ull); + ROUND(s, 0x0001010001000001ull); + ROUND(s, 0x0001000101000100ull); + default: + ROUND(s, 0x0001000001000101ull); + } +} + +/* ---------------------------------------------------------------- */ + +#endif // ASCONP_H diff --git a/isap/Implementations/crypto_aead/isapa128av20/bi_8/config.h b/isap/Implementations/crypto_aead/isapa128av20/bi_8/config.h new file mode 100644 index 0000000..2e1c76f --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/bi_8/config.h @@ -0,0 +1,16 @@ +#ifndef CONFIG_H +#define CONFIG_H + +#define ENABLE_HASH 0 + +#include "isap.h" + +// ISAP-A-128a +const uint8_t ISAP_IV_A[] = {0x01, ISAP_K, ISAP_rH, ISAP_rB, ISAP_sH, ISAP_sB, ISAP_sE, ISAP_sK}; +const uint8_t ISAP_IV_KA[] = {0x02, ISAP_K, ISAP_rH, ISAP_rB, ISAP_sH, ISAP_sB, ISAP_sE, ISAP_sK}; +const uint8_t ISAP_IV_KE[] = {0x03, ISAP_K, ISAP_rH, ISAP_rB, ISAP_sH, ISAP_sB, ISAP_sE, ISAP_sK}; + +// Ascon-Hash +const uint8_t ASCON_HASH_IV[] = {0x00, 0x40, 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00}; + +#endif // CONFIG_H diff --git a/isap/Implementations/crypto_aead/isapa128av20/bi_8/crypto_aead.c b/isap/Implementations/crypto_aead/isapa128av20/bi_8/crypto_aead.c new file mode 100644 index 0000000..4a9bd29 --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/bi_8/crypto_aead.c @@ -0,0 +1,61 @@ +#include "api.h" +#include "isap.h" +#include "crypto_aead.h" + +int crypto_aead_encrypt( + unsigned char *c, unsigned long long *clen, + const unsigned char *m, unsigned long long mlen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k +){ + (void)nsec; + + // Ciphertext length is mlen + tag length + *clen = mlen+ISAP_TAG_SZ; + + // Encrypt plaintext + if (mlen > 0) { + isap_enc(k,npub,m,mlen,c); + } + + // Generate tag + unsigned char *tag = c+mlen; + isap_mac(k,npub,ad,adlen,c,mlen,tag); + return 0; +} + +int crypto_aead_decrypt( + unsigned char *m, unsigned long long *mlen, + unsigned char *nsec, + const unsigned char *c, unsigned long long clen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k +){ + (void)nsec; + + // Plaintext length is clen - tag length + *mlen = clen-ISAP_TAG_SZ; + + // Generate tag + unsigned char tag[ISAP_TAG_SZ]; + isap_mac(k,npub,ad,adlen,c,*mlen,tag); + + // Compare tag + unsigned long eq_cnt = 0; + for(unsigned int i = 0; i < ISAP_TAG_SZ; i++) { + eq_cnt += (tag[i] == c[(*mlen)+i]); + } + + // Perform decryption if tag is correct + if(eq_cnt == (unsigned long)ISAP_TAG_SZ){ + if (*mlen > 0) { + isap_enc(k,npub,c,*mlen,m); + } + return 0; + } else { + return -1; + } +} diff --git a/isap/Implementations/crypto_aead/isapa128av20/bi_8/forceinline.h b/isap/Implementations/crypto_aead/isapa128av20/bi_8/forceinline.h new file mode 100644 index 0000000..ba695cb --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/bi_8/forceinline.h @@ -0,0 +1,19 @@ +#ifndef FORCEINLINE_H_ +#define FORCEINLINE_H_ + +/* define forceinline macro */ +#ifdef _MSC_VER +#define forceinline __forceinline +#elif defined(__GNUC__) +#define forceinline inline __attribute__((__always_inline__)) +#elif defined(__CLANG__) +#if __has_attribute(__always_inline__) +#define forceinline inline __attribute__((__always_inline__)) +#else +#define forceinline inline +#endif +#else +#define forceinline inline +#endif + +#endif /* FORCEINLINE_H_ */ diff --git a/isap/Implementations/crypto_aead/isapa128av20/bi_8/isap.c b/isap/Implementations/crypto_aead/isapa128av20/bi_8/isap.c new file mode 100644 index 0000000..d4009e0 --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/bi_8/isap.c @@ -0,0 +1,226 @@ +#include +#include +#include "api.h" +#include "isap.h" +#include "asconp.h" +#include "config.h" + +forceinline void ABSORB_LANES(state_t *s, const uint8_t *src, uint64_t len) +{ + while (len >= 8) + { + // Absorb full lanes + lane_t t0 = U64TOWORD(*(lane_t *)(src + 0)); + s->x[0] ^= t0.x; + len -= ISAP_rH / 8; + src += ISAP_rH / 8; + P_sH; + } + + if (len > 0) + { + // Absorb partial lane and padding + size_t i; + lane_t t0 = {0}; + for (i = 0; i < len; i++) + { + t0.b[7 - i] ^= *src; + src++; + } + t0.b[7 - i] ^= 0x80; + t0 = TOBI(t0); + s->x[0] ^= t0.x; + P_sH; + } + else + { + // Absorb padded empty lane + s->b[0][7] ^= 0x80; + P_sH; + } +} + +/******************************************************************************/ +/* ISAP_RK */ +/******************************************************************************/ + +void isap_rk( + const uint8_t *k, + const uint8_t *iv, + const uint8_t *y, + state_t *out, + const size_t outlen) +{ + state_t state; + state_t *s = &state; + + // Initialize + s->l[0] = U64TOWORD(*(lane_t *)(k + 0)); + s->l[1] = U64TOWORD(*(lane_t *)(k + 8)); + s->l[2] = U64TOWORD(*(lane_t *)(iv + 0)); + s->x[3] = 0; + s->x[4] = 0; + P_sK; + + // Absorb Y, bit by bit + for (size_t i = 0; i < 16; i++) + { + uint8_t y_byte = *y; + s->b[0][7] ^= (y_byte & 0x80) << 0; + P_sB; + s->b[0][7] ^= (y_byte & 0x40) << 1; + P_sB; + s->b[0][7] ^= (y_byte & 0x20) << 2; + P_sB; + s->b[0][7] ^= (y_byte & 0x10) << 3; + P_sB; + s->b[0][7] ^= (y_byte & 0x08) << 4; + P_sB; + s->b[0][7] ^= (y_byte & 0x04) << 5; + P_sB; + s->b[0][7] ^= (y_byte & 0x02) << 6; + P_sB; + s->b[0][7] ^= (y_byte & 0x01) << 7; + if (i != 15) + { + P_sB; + y += 1; + } + } + + // Squeeze K* + P_sK; + out->x[0] = s->x[0]; + out->x[1] = s->x[1]; + if (outlen > 16) + { + out->x[2] = s->x[2]; + } +} + +/******************************************************************************/ +/* ISAP_MAC */ +/******************************************************************************/ + +void isap_mac( + const uint8_t *k, + const uint8_t *npub, + const uint8_t *ad, uint64_t adlen, + const uint8_t *c, uint64_t clen, + uint8_t *tag) +{ + state_t state; + state_t *s = &state; + + // Initialize + s->l[0] = U64TOWORD(*(lane_t *)(npub + 0)); + s->l[1] = U64TOWORD(*(lane_t *)(npub + 8)); + s->l[2] = U64TOWORD(*(lane_t *)(ISAP_IV_A + 0)); + s->x[3] = 0; + s->x[4] = 0; + P_sH; + + // Absorb associated data + ABSORB_LANES(s, ad, adlen); + + // Domain seperation + s->w[4][0] ^= 0x1UL; + + // Absorb ciphertext + ABSORB_LANES(s, c, clen); + + // Derive KA* + s->l[0] = WORDTOU64(s->l[0]); + s->l[1] = WORDTOU64(s->l[1]); + isap_rk(k, ISAP_IV_KA, (const uint8_t *)(s->b), s, CRYPTO_KEYBYTES); + + // Squeeze tag + P_sH; + lane_t t0 = WORDTOU64(s->l[0]); + memcpy(tag + 0, t0.b, 8); + t0 = WORDTOU64(s->l[1]); + memcpy(tag + 8, t0.b, 8); +} + +/******************************************************************************/ +/* ISAP_ENC */ +/******************************************************************************/ + +void isap_enc( + const uint8_t *k, + const uint8_t *npub, + const uint8_t *m, uint64_t mlen, + uint8_t *c) + +{ + state_t state; + state_t *s = &state; + + // Init state + isap_rk(k, ISAP_IV_KE, npub, s, ISAP_STATE_SZ - CRYPTO_NPUBBYTES); + s->l[3] = U64TOWORD(*(lane_t *)(npub + 0)); + s->l[4] = U64TOWORD(*(lane_t *)(npub + 8)); + + while (mlen >= ISAP_rH / 8) + { + // Encrypt full lanes + P_sE; + lane_t t0 = WORDTOU64(s->l[0]); + *(uint64_t *)c = *(uint64_t *)m ^ t0.x; + mlen -= ISAP_rH / 8; + m += ISAP_rH / 8; + c += ISAP_rH / 8; + } + + if (mlen > 0) + { + // Encrypt partial lanes + P_sE; + lane_t t0 = WORDTOU64(s->l[0]); + for (uint8_t i = 0; i < mlen; i++) + { + *c = *m ^ t0.b[i]; + m += 1; + c += 1; + } + } +} + +/******************************************************************************/ +/* Ascon-Hash */ +/******************************************************************************/ + +#if ENABLE_HASH == 1 + +int crypto_hash(uint8_t *out, const uint8_t *in, unsigned long long inlen) +{ + + state_t state; + state_t *s = &state; + + // Initialize + s->l[0] = U64TOWORD(*(lane_t *)(ASCON_HASH_IV + 0)); + s->x[1] = 0; + s->x[2] = 0; + s->x[3] = 0; + s->x[4] = 0; + P_sH; + + // Absorb input + ABSORB_LANES(s, in, inlen); + + for (size_t i = 0; i < 4; i++) + { + // Squeeze full lanes + lane_t t0 = WORDTOU64(s->l[0]); + *(uint64_t *)(out + 8 * i) = t0.x; + if (i < 3) + { + P_sH; + } + } + + return 0; +} + +#endif diff --git a/isap/Implementations/crypto_aead/isapa128av20/bi_8/isap.h b/isap/Implementations/crypto_aead/isapa128av20/bi_8/isap.h new file mode 100644 index 0000000..abec1ca --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/bi_8/isap.h @@ -0,0 +1,44 @@ +#ifndef ISAP_H +#define ISAP_H + +#include + +// Rate in bits +#define ISAP_rH 64 +#define ISAP_rB 1 + +// Number of rounds +#define ISAP_sH 12 +#define ISAP_sB 1 +#define ISAP_sE 6 +#define ISAP_sK 12 + +// State size in bytes +#define ISAP_STATE_SZ 40 + +// Size of rate in bytes +#define ISAP_rH_SZ ((ISAP_rH + 7) / 8) + +// Size of zero truncated IV in bytes +#define ISAP_IV_SZ 8 + +// Size of tag in bytes +#define ISAP_TAG_SZ 16 + +// Security level +#define ISAP_K 128 + +void isap_mac( + const uint8_t *k, + const uint8_t *npub, + const uint8_t *ad, const uint64_t adlen, + const uint8_t *c, const uint64_t clen, + uint8_t *tag); + +void isap_enc( + const uint8_t *k, + const uint8_t *npub, + const uint8_t *m, const uint64_t mlen, + uint8_t *c); + +#endif diff --git a/isap/Implementations/crypto_aead/isapa128av20/opt_32/api.h b/isap/Implementations/crypto_aead/isapa128av20/opt_32/api.h index 13792e9..83ebf98 100644 --- a/isap/Implementations/crypto_aead/isapa128av20/opt_32/api.h +++ b/isap/Implementations/crypto_aead/isapa128av20/opt_32/api.h @@ -1,11 +1,16 @@ #ifndef API_H #define API_H -#define CRYPTO_VERSION "2.0.1" +// isapa128a #define CRYPTO_KEYBYTES 16 #define CRYPTO_NSECBYTES 0 #define CRYPTO_NPUBBYTES 16 #define CRYPTO_ABYTES 16 #define CRYPTO_NOOVERLAP 1 +// asconhashv12 +#define CRYPTO_BYTES 32 +#define ASCON_HASH_OUTLEN 32 +#define ASCON_HASH_ROUNDS 12 + #endif diff --git a/isap/Implementations/crypto_aead/isapa128av20/opt_32/asconp.h b/isap/Implementations/crypto_aead/isapa128av20/opt_32/asconp.h index 655f469..72d3149 100644 --- a/isap/Implementations/crypto_aead/isapa128av20/opt_32/asconp.h +++ b/isap/Implementations/crypto_aead/isapa128av20/opt_32/asconp.h @@ -2,139 +2,122 @@ #define ASCONP_H_ #include +#include "forceinline.h" -typedef unsigned char u8; -typedef uint32_t u32; -typedef unsigned long long u64; +typedef union +{ + uint64_t x; + uint32_t w[2]; + uint8_t b[8]; +} lane_t; -typedef struct +typedef union { - u32 e; - u32 o; -} u32_2; + lane_t l[5]; + uint64_t x[5]; + uint32_t w[5][2]; + uint8_t b[5][8]; +} state_t; + +/* ---------------------------------------------------------------- */ + +#define P_sH P12ROUNDS(s) +#define P_sB P1ROUNDS(s) +#define P_sE P6ROUNDS(s) +#define P_sK P12ROUNDS(s) + +/* ---------------------------------------------------------------- */ + +#define U64TOWORD(x) U64BIG(x) +#define WORDTOU64(x) U64BIG(x) -// Round constants, bit-interleaved -u32 rc_o[12] = {0xc, 0xc, 0x9, 0x9, 0xc, 0xc, 0x9, 0x9, 0x6, 0x6, 0x3, 0x3}; -u32 rc_e[12] = {0xc, 0x9, 0xc, 0x9, 0x6, 0x3, 0x6, 0x3, 0xc, 0x9, 0xc, 0x9}; +/* ---------------------------------------------------------------- */ + +#define TOBI(x) (x) +#define FROMBI(x) (x) /* ---------------------------------------------------------------- */ -u64 U64BIG(u64 x) +forceinline lane_t U64BIG(lane_t x) { - return ((((x)&0x00000000000000FFULL) << 56) | (((x)&0x000000000000FF00ULL) << 40) | - (((x)&0x0000000000FF0000ULL) << 24) | (((x)&0x00000000FF000000ULL) << 8) | - (((x)&0x000000FF00000000ULL) >> 8) | (((x)&0x0000FF0000000000ULL) >> 24) | - (((x)&0x00FF000000000000ULL) >> 40) | (((x)&0xFF00000000000000ULL) >> 56)); + x.x = ((((x.x) & 0x00000000000000FFULL) << 56) | (((x.x) & 0x000000000000FF00ULL) << 40) | + (((x.x) & 0x0000000000FF0000ULL) << 24) | (((x.x) & 0x00000000FF000000ULL) << 8) | + (((x.x) & 0x000000FF00000000ULL) >> 8) | (((x.x) & 0x0000FF0000000000ULL) >> 24) | + (((x.x) & 0x00FF000000000000ULL) >> 40) | (((x.x) & 0xFF00000000000000ULL) >> 56)); + return x; } /* ---------------------------------------------------------------- */ -// Credit to Henry S. Warren, Hacker's Delight, Addison-Wesley, 2002 -void to_bit_interleaving(u32_2 *out, u64 in) +forceinline void ROUND(state_t *s, uint8_t C) { - u32 hi = (in) >> 32; - u32 lo = (u32)(in); - u32 r0, r1; - r0 = (lo ^ (lo >> 1)) & 0x22222222, lo ^= r0 ^ (r0 << 1); - r0 = (lo ^ (lo >> 2)) & 0x0C0C0C0C, lo ^= r0 ^ (r0 << 2); - r0 = (lo ^ (lo >> 4)) & 0x00F000F0, lo ^= r0 ^ (r0 << 4); - r0 = (lo ^ (lo >> 8)) & 0x0000FF00, lo ^= r0 ^ (r0 << 8); - r1 = (hi ^ (hi >> 1)) & 0x22222222, hi ^= r1 ^ (r1 << 1); - r1 = (hi ^ (hi >> 2)) & 0x0C0C0C0C, hi ^= r1 ^ (r1 << 2); - r1 = (hi ^ (hi >> 4)) & 0x00F000F0, hi ^= r1 ^ (r1 << 4); - r1 = (hi ^ (hi >> 8)) & 0x0000FF00, hi ^= r1 ^ (r1 << 8); - (*out).e = (lo & 0x0000FFFF) | (hi << 16); - (*out).o = (lo >> 16) | (hi & 0xFFFF0000); + uint64_t xtemp; + /* round constant */ + s->x[2] ^= C; + /* s-box layer */ + s->x[0] ^= s->x[4]; + s->x[4] ^= s->x[3]; + s->x[2] ^= s->x[1]; + xtemp = s->x[0] & ~s->x[4]; + s->x[0] ^= s->x[2] & ~s->x[1]; + s->x[2] ^= s->x[4] & ~s->x[3]; + s->x[4] ^= s->x[1] & ~s->x[0]; + s->x[1] ^= s->x[3] & ~s->x[2]; + s->x[3] ^= xtemp; + s->x[1] ^= s->x[0]; + s->x[3] ^= s->x[2]; + s->x[0] ^= s->x[4]; + s->x[2] = ~s->x[2]; + /* linear layer */ + s->x[0] ^= + (s->x[0] >> 19) ^ (s->x[0] << 45) ^ (s->x[0] >> 28) ^ (s->x[0] << 36); + s->x[1] ^= + (s->x[1] >> 61) ^ (s->x[1] << 3) ^ (s->x[1] >> 39) ^ (s->x[1] << 25); + s->x[2] ^= + (s->x[2] >> 1) ^ (s->x[2] << 63) ^ (s->x[2] >> 6) ^ (s->x[2] << 58); + s->x[3] ^= + (s->x[3] >> 10) ^ (s->x[3] << 54) ^ (s->x[3] >> 17) ^ (s->x[3] << 47); + s->x[4] ^= + (s->x[4] >> 7) ^ (s->x[4] << 57) ^ (s->x[4] >> 41) ^ (s->x[4] << 23); } /* ---------------------------------------------------------------- */ -// Credit to Henry S. Warren, Hacker's Delight, Addison-Wesley, 2002 -void from_bit_interleaving(u64 *out, u32_2 in) +forceinline void P12ROUNDS(state_t *s) { - u32 lo = ((in).e & 0x0000FFFF) | ((in).o << 16); - u32 hi = ((in).e >> 16) | ((in).o & 0xFFFF0000); - u32 r0, r1; - r0 = (lo ^ (lo >> 8)) & 0x0000FF00, lo ^= r0 ^ (r0 << 8); - r0 = (lo ^ (lo >> 4)) & 0x00F000F0, lo ^= r0 ^ (r0 << 4); - r0 = (lo ^ (lo >> 2)) & 0x0C0C0C0C, lo ^= r0 ^ (r0 << 2); - r0 = (lo ^ (lo >> 1)) & 0x22222222, lo ^= r0 ^ (r0 << 1); - r1 = (hi ^ (hi >> 8)) & 0x0000FF00, hi ^= r1 ^ (r1 << 8); - r1 = (hi ^ (hi >> 4)) & 0x00F000F0, hi ^= r1 ^ (r1 << 4); - r1 = (hi ^ (hi >> 2)) & 0x0C0C0C0C, hi ^= r1 ^ (r1 << 2); - r1 = (hi ^ (hi >> 1)) & 0x22222222, hi ^= r1 ^ (r1 << 1); - *out = (u64)hi << 32 | lo; + ROUND(s, 0xf0); + ROUND(s, 0xe1); + ROUND(s, 0xd2); + ROUND(s, 0xc3); + ROUND(s, 0xb4); + ROUND(s, 0xa5); + ROUND(s, 0x96); + ROUND(s, 0x87); + ROUND(s, 0x78); + ROUND(s, 0x69); + ROUND(s, 0x5a); + ROUND(s, 0x4b); } /* ---------------------------------------------------------------- */ -#define ROTR32(x, n) (((x) >> (n)) | ((x) << (32 - (n)))) +forceinline void P6ROUNDS(state_t *s) +{ + ROUND(s, 0x96); + ROUND(s, 0x87); + ROUND(s, 0x78); + ROUND(s, 0x69); + ROUND(s, 0x5a); + ROUND(s, 0x4b); +} /* ---------------------------------------------------------------- */ -void static inline PX(u32 rounds, u32_2* x0, u32_2* x1, u32_2* x2, u32_2* x3, u32_2* x4) { - u32_2 t0, t1, t2, t3, t4; - for (u32 r = 12 - rounds; r < 12; r++){ - /* rcon */ - (*x2).e ^= rc_e[r]; - (*x2).o ^= rc_o[r]; - /* non-linear layer */ - (*x0).e ^= (*x4).e; - (*x0).o ^= (*x4).o; - (*x4).e ^= (*x3).e; - (*x4).o ^= (*x3).o; - (*x2).e ^= (*x1).e; - (*x2).o ^= (*x1).o; - (t0).e = (*x0).e; - (t0).o = (*x0).o; - (t4).e = (*x4).e; - (t4).o = (*x4).o; - (t3).e = (*x3).e; - (t3).o = (*x3).o; - (t1).e = (*x1).e; - (t1).o = (*x1).o; - (t2).e = (*x2).e; - (t2).o = (*x2).o; - (*x0).e = t0.e ^ (~t1.e & t2.e); - (*x0).o = t0.o ^ (~t1.o & t2.o); - (*x2).e = t2.e ^ (~t3.e & t4.e); - (*x2).o = t2.o ^ (~t3.o & t4.o); - (*x4).e = t4.e ^ (~t0.e & t1.e); - (*x4).o = t4.o ^ (~t0.o & t1.o); - (*x1).e = t1.e ^ (~t2.e & t3.e); - (*x1).o = t1.o ^ (~t2.o & t3.o); - (*x3).e = t3.e ^ (~t4.e & t0.e); - (*x3).o = t3.o ^ (~t4.o & t0.o); - (*x1).e ^= (*x0).e; - (*x1).o ^= (*x0).o; - (*x3).e ^= (*x2).e; - (*x3).o ^= (*x2).o; - (*x0).e ^= (*x4).e; - (*x0).o ^= (*x4).o; - /* linear layer */ - t0.e = (*x0).e ^ ROTR32((*x0).o, 4); - t0.o = (*x0).o ^ ROTR32((*x0).e, 5); - t1.e = (*x1).e ^ ROTR32((*x1).e, 11); - t1.o = (*x1).o ^ ROTR32((*x1).o, 11); - t2.e = (*x2).e ^ ROTR32((*x2).o, 2); - t2.o = (*x2).o ^ ROTR32((*x2).e, 3); - t3.e = (*x3).e ^ ROTR32((*x3).o, 3); - t3.o = (*x3).o ^ ROTR32((*x3).e, 4); - t4.e = (*x4).e ^ ROTR32((*x4).e, 17); - t4.o = (*x4).o ^ ROTR32((*x4).o, 17); - (*x0).e ^= ROTR32(t0.o, 9); - (*x0).o ^= ROTR32(t0.e, 10); - (*x1).e ^= ROTR32(t1.o, 19); - (*x1).o ^= ROTR32(t1.e, 20); - (*x2).e ^= t2.o; - (*x2).o ^= ROTR32(t2.e, 1); - (*x3).e ^= ROTR32(t3.e, 5); - (*x3).o ^= ROTR32(t3.o, 5); - (*x4).e ^= ROTR32(t4.o, 3); - (*x4).o ^= ROTR32(t4.e, 4); - (*x2).e = ~(*x2).e; - (*x2).o = ~(*x2).o; - } +forceinline void P1ROUNDS(state_t *s) +{ + ROUND(s, 0x4b); } +/* ---------------------------------------------------------------- */ + #endif // ASCONP_H_ diff --git a/isap/Implementations/crypto_aead/isapa128av20/opt_32/config.h b/isap/Implementations/crypto_aead/isapa128av20/opt_32/config.h new file mode 100644 index 0000000..2e1c76f --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/opt_32/config.h @@ -0,0 +1,16 @@ +#ifndef CONFIG_H +#define CONFIG_H + +#define ENABLE_HASH 0 + +#include "isap.h" + +// ISAP-A-128a +const uint8_t ISAP_IV_A[] = {0x01, ISAP_K, ISAP_rH, ISAP_rB, ISAP_sH, ISAP_sB, ISAP_sE, ISAP_sK}; +const uint8_t ISAP_IV_KA[] = {0x02, ISAP_K, ISAP_rH, ISAP_rB, ISAP_sH, ISAP_sB, ISAP_sE, ISAP_sK}; +const uint8_t ISAP_IV_KE[] = {0x03, ISAP_K, ISAP_rH, ISAP_rB, ISAP_sH, ISAP_sB, ISAP_sE, ISAP_sK}; + +// Ascon-Hash +const uint8_t ASCON_HASH_IV[] = {0x00, 0x40, 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00}; + +#endif // CONFIG_H diff --git a/isap/Implementations/crypto_aead/isapa128av20/opt_32/forceinline.h b/isap/Implementations/crypto_aead/isapa128av20/opt_32/forceinline.h new file mode 100644 index 0000000..ba695cb --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/opt_32/forceinline.h @@ -0,0 +1,19 @@ +#ifndef FORCEINLINE_H_ +#define FORCEINLINE_H_ + +/* define forceinline macro */ +#ifdef _MSC_VER +#define forceinline __forceinline +#elif defined(__GNUC__) +#define forceinline inline __attribute__((__always_inline__)) +#elif defined(__CLANG__) +#if __has_attribute(__always_inline__) +#define forceinline inline __attribute__((__always_inline__)) +#else +#define forceinline inline +#endif +#else +#define forceinline inline +#endif + +#endif /* FORCEINLINE_H_ */ diff --git a/isap/Implementations/crypto_aead/isapa128av20/opt_32/isap.c b/isap/Implementations/crypto_aead/isapa128av20/opt_32/isap.c index 56182ab..d4009e0 100644 --- a/isap/Implementations/crypto_aead/isapa128av20/opt_32/isap.c +++ b/isap/Implementations/crypto_aead/isapa128av20/opt_32/isap.c @@ -1,60 +1,100 @@ +#include +#include #include "api.h" #include "isap.h" #include "asconp.h" +#include "config.h" -const u8 ISAP_IV_A[] = {0x01, ISAP_K, ISAP_rH, ISAP_rB, ISAP_sH, ISAP_sB, ISAP_sE, ISAP_sK}; -const u8 ISAP_IV_KA[] = {0x02, ISAP_K, ISAP_rH, ISAP_rB, ISAP_sH, ISAP_sB, ISAP_sE, ISAP_sK}; -const u8 ISAP_IV_KE[] = {0x03, ISAP_K, ISAP_rH, ISAP_rB, ISAP_sH, ISAP_sB, ISAP_sE, ISAP_sK}; +forceinline void ABSORB_LANES(state_t *s, const uint8_t *src, uint64_t len) +{ + while (len >= 8) + { + // Absorb full lanes + lane_t t0 = U64TOWORD(*(lane_t *)(src + 0)); + s->x[0] ^= t0.x; + len -= ISAP_rH / 8; + src += ISAP_rH / 8; + P_sH; + } -#define P_sB PX(1,&x0,&x1,&x2,&x3,&x4) -#define P_sE PX(6,&x0,&x1,&x2,&x3,&x4) -#define P_sH PX(12,&x0,&x1,&x2,&x3,&x4) -#define P_sK PX(12,&x0,&x1,&x2,&x3,&x4) + if (len > 0) + { + // Absorb partial lane and padding + size_t i; + lane_t t0 = {0}; + for (i = 0; i < len; i++) + { + t0.b[7 - i] ^= *src; + src++; + } + t0.b[7 - i] ^= 0x80; + t0 = TOBI(t0); + s->x[0] ^= t0.x; + P_sH; + } + else + { + // Absorb padded empty lane + s->b[0][7] ^= 0x80; + P_sH; + } +} /******************************************************************************/ /* ISAP_RK */ /******************************************************************************/ void isap_rk( - const u8 *k, - const u8 *iv, - const u8 *y, - u8 *out, - const u8 outlen) + const uint8_t *k, + const uint8_t *iv, + const uint8_t *y, + state_t *out, + const size_t outlen) { - // State variables - u32_2 x0, x1, x2, x3, x4; + state_t state; + state_t *s = &state; // Initialize - to_bit_interleaving(&x0, U64BIG(*(u64 *)(k + 0))); - to_bit_interleaving(&x1, U64BIG(*(u64 *)(k + 8))); - to_bit_interleaving(&x2, U64BIG(*(u64 *)(iv + 0))); - x3.o = 0; - x3.e = 0; - x4.o = 0; - x4.e = 0; + s->l[0] = U64TOWORD(*(lane_t *)(k + 0)); + s->l[1] = U64TOWORD(*(lane_t *)(k + 8)); + s->l[2] = U64TOWORD(*(lane_t *)(iv + 0)); + s->x[3] = 0; + s->x[4] = 0; P_sK; // Absorb Y, bit by bit - for (u8 i = 0; i < 127; i++) { - u8 cur_byte_pos = i / 8; - u8 cur_bit_pos = 7 - (i % 8); - u32 cur_bit = ((y[cur_byte_pos] >> (cur_bit_pos)) & 0x01) << 7; - x0.o ^= ((u32)cur_bit) << 24; + for (size_t i = 0; i < 16; i++) + { + uint8_t y_byte = *y; + s->b[0][7] ^= (y_byte & 0x80) << 0; + P_sB; + s->b[0][7] ^= (y_byte & 0x40) << 1; + P_sB; + s->b[0][7] ^= (y_byte & 0x20) << 2; + P_sB; + s->b[0][7] ^= (y_byte & 0x10) << 3; + P_sB; + s->b[0][7] ^= (y_byte & 0x08) << 4; P_sB; + s->b[0][7] ^= (y_byte & 0x04) << 5; + P_sB; + s->b[0][7] ^= (y_byte & 0x02) << 6; + P_sB; + s->b[0][7] ^= (y_byte & 0x01) << 7; + if (i != 15) + { + P_sB; + y += 1; + } } - u8 cur_bit = ((y[15]) & 0x01) << 7; - x0.o ^= ((u32)cur_bit) << (24); - // Squeeze - Derive K* + // Squeeze K* P_sK; - *(u32 *)(out + 0) = x0.o; - *(u32 *)(out + 4) = x0.e; - *(u32 *)(out + 8) = x1.o; - *(u32 *)(out + 12) = x1.e; - if (outlen > 16) { - *(u32 *)(out + 16) = x2.o; - *(u32 *)(out + 20) = x2.e; + out->x[0] = s->x[0]; + out->x[1] = s->x[1]; + if (outlen > 16) + { + out->x[2] = s->x[2]; } } @@ -63,121 +103,43 @@ void isap_rk( /******************************************************************************/ void isap_mac( - const u8 *k, - const u8 *npub, - const u8 *ad, u64 adlen, - const u8 *c, u64 clen, - u8 *tag) + const uint8_t *k, + const uint8_t *npub, + const uint8_t *ad, uint64_t adlen, + const uint8_t *c, uint64_t clen, + uint8_t *tag) { - // State and temporary variables - u32_2 x0, x1, x2, x3, x4; - u32_2 t0; - u64 tmp0; + state_t state; + state_t *s = &state; // Initialize - to_bit_interleaving(&x0, U64BIG(*(u64 *)npub + 0)); - to_bit_interleaving(&x1, U64BIG(*(u64 *)(npub + 8))); - to_bit_interleaving(&x2, U64BIG(*(u64 *)(ISAP_IV_A))); - x3.o = 0; - x3.e = 0; - x4.o = 0; - x4.e = 0; + s->l[0] = U64TOWORD(*(lane_t *)(npub + 0)); + s->l[1] = U64TOWORD(*(lane_t *)(npub + 8)); + s->l[2] = U64TOWORD(*(lane_t *)(ISAP_IV_A + 0)); + s->x[3] = 0; + s->x[4] = 0; P_sH; - // Absorb full lanes of AD - while (adlen >= 8) - { - to_bit_interleaving(&t0, U64BIG(*(u64 *)ad)); - x0.e ^= t0.e; - x0.o ^= t0.o; - adlen -= ISAP_rH / 8; - ad += ISAP_rH / 8; - P_sH; - } - - // Absorb partial lane of AD and add padding - if (adlen > 0) - { - tmp0 = 0; - u8 *tmp0_bytes = (u8 *)&tmp0; - u8 i; - for (i = 0; i < adlen; i++) - { - tmp0_bytes[i] = *ad; - ad += 1; - } - tmp0_bytes[i] = 0x80; - to_bit_interleaving(&t0, U64BIG(tmp0)); - x0.e ^= t0.e; - x0.o ^= t0.o; - P_sH; - } - - // Absorb AD padding if not already done before - if (adlen == 0) - { - x0.o ^= 0x80000000; - P_sH; - } - - // Domain Seperation - x4.e ^= ((u32)0x01); + // Absorb associated data + ABSORB_LANES(s, ad, adlen); - // Absorb full lanes of C - while (clen >= 8) - { - to_bit_interleaving(&t0, U64BIG(*(u64 *)c)); - x0.e ^= t0.e; - x0.o ^= t0.o; - P_sH; - clen -= ISAP_rH / 8; - c += ISAP_rH / 8; - } + // Domain seperation + s->w[4][0] ^= 0x1UL; - // Absorb partial lane of C and add padding - if (clen > 0) - { - tmp0 = 0; - u8 *tmp0_bytes = (u8 *)&tmp0; - u8 i; - for (i = 0; i < clen; i++) - { - tmp0_bytes[i] = *c; - c += 1; - } - tmp0_bytes[i] = 0x80; - to_bit_interleaving(&t0, U64BIG(tmp0)); - x0.e ^= t0.e; - x0.o ^= t0.o; - P_sH; - } + // Absorb ciphertext + ABSORB_LANES(s, c, clen); - // Absorb C padding if not already done before - if (clen == 0) - { - x0.o ^= 0x80000000; - P_sH; - } + // Derive KA* + s->l[0] = WORDTOU64(s->l[0]); + s->l[1] = WORDTOU64(s->l[1]); + isap_rk(k, ISAP_IV_KA, (const uint8_t *)(s->b), s, CRYPTO_KEYBYTES); - // Finalize - Derive Ka* - u64 y64[CRYPTO_KEYBYTES / 8]; - from_bit_interleaving(&tmp0, x0); - y64[0] = U64BIG(tmp0); - from_bit_interleaving(&tmp0, x1); - y64[1] = U64BIG(tmp0); - u32 ka_star32[CRYPTO_KEYBYTES / 4]; - isap_rk(k, ISAP_IV_KA, (u8 *)y64, (u8 *)ka_star32, CRYPTO_KEYBYTES); - - // Finalize - Squeeze T - x0.o = ka_star32[0]; - x0.e = ka_star32[1]; - x1.o = ka_star32[2]; - x1.e = ka_star32[3]; + // Squeeze tag P_sH; - from_bit_interleaving(&tmp0, x0); - *(u64 *)(tag + 0) = U64BIG(tmp0); - from_bit_interleaving(&tmp0, x1); - *(u64 *)(tag + 8) = U64BIG(tmp0); + lane_t t0 = WORDTOU64(s->l[0]); + memcpy(tag + 0, t0.b, 8); + t0 = WORDTOU64(s->l[1]); + memcpy(tag + 8, t0.b, 8); } /******************************************************************************/ @@ -185,52 +147,80 @@ void isap_mac( /******************************************************************************/ void isap_enc( - const u8 *k, - const u8 *npub, - const u8 *m, u64 mlen, - u8 *c) + const uint8_t *k, + const uint8_t *npub, + const uint8_t *m, uint64_t mlen, + uint8_t *c) + { - // Derive Ke - u8 ke[ISAP_STATE_SZ - CRYPTO_NPUBBYTES]; - isap_rk(k, ISAP_IV_KE, npub, ke, ISAP_STATE_SZ - CRYPTO_NPUBBYTES); - - // State and temporary variables - u32_2 x0, x1, x2, x3, x4; - u64 tmp0; - - // Init State - x0.o = *(u32 *)(ke + 0); - x0.e = *(u32 *)(ke + 4); - x1.o = *(u32 *)(ke + 8); - x1.e = *(u32 *)(ke + 12); - x2.o = *(u32 *)(ke + 16); - x2.e = *(u32 *)(ke + 20); - to_bit_interleaving(&x3, U64BIG(*(u64 *)npub)); - to_bit_interleaving(&x4, U64BIG(*(u64 *)(npub + 8))); - - // Squeeze full lanes - while (mlen >= 8) + state_t state; + state_t *s = &state; + + // Init state + isap_rk(k, ISAP_IV_KE, npub, s, ISAP_STATE_SZ - CRYPTO_NPUBBYTES); + s->l[3] = U64TOWORD(*(lane_t *)(npub + 0)); + s->l[4] = U64TOWORD(*(lane_t *)(npub + 8)); + + while (mlen >= ISAP_rH / 8) { + // Encrypt full lanes P_sE; - from_bit_interleaving(&tmp0, x0); - *(u64 *)c = *(u64 *)m ^ U64BIG(tmp0); - mlen -= 8; + lane_t t0 = WORDTOU64(s->l[0]); + *(uint64_t *)c = *(uint64_t *)m ^ t0.x; + mlen -= ISAP_rH / 8; m += ISAP_rH / 8; c += ISAP_rH / 8; } - // Squeeze partial lane if (mlen > 0) { + // Encrypt partial lanes P_sE; - from_bit_interleaving(&tmp0, x0); - tmp0 = U64BIG(tmp0); - u8 *tmp0_bytes = (u8 *)&tmp0; - for (u8 i = 0; i < mlen; i++) + lane_t t0 = WORDTOU64(s->l[0]); + for (uint8_t i = 0; i < mlen; i++) { - *c = *m ^ tmp0_bytes[i]; + *c = *m ^ t0.b[i]; m += 1; c += 1; } } } + +/******************************************************************************/ +/* Ascon-Hash */ +/******************************************************************************/ + +#if ENABLE_HASH == 1 + +int crypto_hash(uint8_t *out, const uint8_t *in, unsigned long long inlen) +{ + + state_t state; + state_t *s = &state; + + // Initialize + s->l[0] = U64TOWORD(*(lane_t *)(ASCON_HASH_IV + 0)); + s->x[1] = 0; + s->x[2] = 0; + s->x[3] = 0; + s->x[4] = 0; + P_sH; + + // Absorb input + ABSORB_LANES(s, in, inlen); + + for (size_t i = 0; i < 4; i++) + { + // Squeeze full lanes + lane_t t0 = WORDTOU64(s->l[0]); + *(uint64_t *)(out + 8 * i) = t0.x; + if (i < 3) + { + P_sH; + } + } + + return 0; +} + +#endif diff --git a/isap/Implementations/crypto_aead/isapa128av20/opt_32/isap.h b/isap/Implementations/crypto_aead/isapa128av20/opt_32/isap.h index 95bafb0..12dfaa8 100644 --- a/isap/Implementations/crypto_aead/isapa128av20/opt_32/isap.h +++ b/isap/Implementations/crypto_aead/isapa128av20/opt_32/isap.h @@ -1,5 +1,7 @@ -#ifndef ISAP_H -#define ISAP_H +#ifndef ISAP_H_ +#define ISAP_H_ + +#include // Rate in bits #define ISAP_rH 64 @@ -27,23 +29,16 @@ #define ISAP_K 128 void isap_mac( - const unsigned char *k, - const unsigned char *npub, - const unsigned char *ad, unsigned long long adlen, - const unsigned char *c, unsigned long long clen, - unsigned char *tag); - -void isap_rk( - const unsigned char *k, - const unsigned char *iv, - const unsigned char *in, - unsigned char *out, - const unsigned char outlen); + const uint8_t *k, + const uint8_t *npub, + const uint8_t *ad, const uint64_t adlen, + const uint8_t *c, const uint64_t clen, + uint8_t *tag); void isap_enc( - const unsigned char *k, - const unsigned char *npub, - const unsigned char *m, unsigned long long mlen, - unsigned char *c); + const uint8_t *k, + const uint8_t *npub, + const uint8_t *m, const uint64_t mlen, + uint8_t *c); -#endif +#endif // ISAP_H_ diff --git a/isap/Implementations/crypto_aead/isapa128av20/opt_32_compact/api.h b/isap/Implementations/crypto_aead/isapa128av20/opt_32_compact/api.h new file mode 120000 index 0000000..248197f --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/opt_32_compact/api.h @@ -0,0 +1 @@ +../opt_32/api.h \ No newline at end of file diff --git a/isap/Implementations/crypto_aead/isapa128av20/opt_32_compact/asconp.h b/isap/Implementations/crypto_aead/isapa128av20/opt_32_compact/asconp.h new file mode 100644 index 0000000..fc54b11 --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/opt_32_compact/asconp.h @@ -0,0 +1,110 @@ +#ifndef ASCONP_H_ +#define ASCONP_H_ + +#include +#include "forceinline.h" + +typedef union +{ + uint64_t x; + uint32_t w[2]; + uint8_t b[8]; +} lane_t; + +typedef union +{ + lane_t l[5]; + uint64_t x[5]; + uint32_t w[5][2]; + uint8_t b[5][8]; +} state_t; + +/* ---------------------------------------------------------------- */ + +#define P_sH PROUNDS(s, 12) +#define P_sB PROUNDS(s, 1) +#define P_sE PROUNDS(s, 6) +#define P_sK PROUNDS(s, 12) + +/* ---------------------------------------------------------------- */ + +#define U64TOWORD(x) U64BIG(x) +#define WORDTOU64(x) U64BIG(x) + +/* ---------------------------------------------------------------- */ + +#define TOBI(x) (x) +#define FROMBI(x) (x) + +/* ---------------------------------------------------------------- */ + +lane_t U64BIG(lane_t x) +{ + x.x = ((((x.x) & 0x00000000000000FFULL) << 56) | (((x.x) & 0x000000000000FF00ULL) << 40) | + (((x.x) & 0x0000000000FF0000ULL) << 24) | (((x.x) & 0x00000000FF000000ULL) << 8) | + (((x.x) & 0x000000FF00000000ULL) >> 8) | (((x.x) & 0x0000FF0000000000ULL) >> 24) | + (((x.x) & 0x00FF000000000000ULL) >> 40) | (((x.x) & 0xFF00000000000000ULL) >> 56)); + return x; +} + +/* ---------------------------------------------------------------- */ + +forceinline void ROUND(state_t *s, uint8_t C) +{ + uint64_t xtemp; + /* round constant */ + s->x[2] ^= C; + /* s-box layer */ + s->x[0] ^= s->x[4]; + s->x[4] ^= s->x[3]; + s->x[2] ^= s->x[1]; + xtemp = s->x[0] & ~s->x[4]; + s->x[0] ^= s->x[2] & ~s->x[1]; + s->x[2] ^= s->x[4] & ~s->x[3]; + s->x[4] ^= s->x[1] & ~s->x[0]; + s->x[1] ^= s->x[3] & ~s->x[2]; + s->x[3] ^= xtemp; + s->x[1] ^= s->x[0]; + s->x[3] ^= s->x[2]; + s->x[0] ^= s->x[4]; + s->x[2] = ~s->x[2]; + /* linear layer */ + s->x[0] ^= + (s->x[0] >> 19) ^ (s->x[0] << 45) ^ (s->x[0] >> 28) ^ (s->x[0] << 36); + s->x[1] ^= + (s->x[1] >> 61) ^ (s->x[1] << 3) ^ (s->x[1] >> 39) ^ (s->x[1] << 25); + s->x[2] ^= + (s->x[2] >> 1) ^ (s->x[2] << 63) ^ (s->x[2] >> 6) ^ (s->x[2] << 58); + s->x[3] ^= + (s->x[3] >> 10) ^ (s->x[3] << 54) ^ (s->x[3] >> 17) ^ (s->x[3] << 47); + s->x[4] ^= + (s->x[4] >> 7) ^ (s->x[4] << 57) ^ (s->x[4] >> 41) ^ (s->x[4] << 23); +} + +/* ---------------------------------------------------------------- */ + +void PROUNDS(state_t *s, uint8_t nr) +{ + switch (nr) + { + case 12: + ROUND(s, 0xf0); + ROUND(s, 0xe1); + ROUND(s, 0xd2); + ROUND(s, 0xc3); + ROUND(s, 0xb4); + ROUND(s, 0xa5); + case 6: + ROUND(s, 0x96); + ROUND(s, 0x87); + ROUND(s, 0x78); + ROUND(s, 0x69); + ROUND(s, 0x5a); + default: + ROUND(s, 0x4b); + } +} + +/* ---------------------------------------------------------------- */ + +#endif // ASCONP_H_ diff --git a/isap/Implementations/crypto_aead/isapa128av20/opt_32_compact/config.h b/isap/Implementations/crypto_aead/isapa128av20/opt_32_compact/config.h new file mode 100644 index 0000000..2e1c76f --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/opt_32_compact/config.h @@ -0,0 +1,16 @@ +#ifndef CONFIG_H +#define CONFIG_H + +#define ENABLE_HASH 0 + +#include "isap.h" + +// ISAP-A-128a +const uint8_t ISAP_IV_A[] = {0x01, ISAP_K, ISAP_rH, ISAP_rB, ISAP_sH, ISAP_sB, ISAP_sE, ISAP_sK}; +const uint8_t ISAP_IV_KA[] = {0x02, ISAP_K, ISAP_rH, ISAP_rB, ISAP_sH, ISAP_sB, ISAP_sE, ISAP_sK}; +const uint8_t ISAP_IV_KE[] = {0x03, ISAP_K, ISAP_rH, ISAP_rB, ISAP_sH, ISAP_sB, ISAP_sE, ISAP_sK}; + +// Ascon-Hash +const uint8_t ASCON_HASH_IV[] = {0x00, 0x40, 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00}; + +#endif // CONFIG_H diff --git a/isap/Implementations/crypto_aead/isapa128av20/opt_32_compact/crypto_aead.c b/isap/Implementations/crypto_aead/isapa128av20/opt_32_compact/crypto_aead.c new file mode 120000 index 0000000..89bbb06 --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/opt_32_compact/crypto_aead.c @@ -0,0 +1 @@ +../opt_32/crypto_aead.c \ No newline at end of file diff --git a/isap/Implementations/crypto_aead/isapa128av20/opt_32_compact/forceinline.h b/isap/Implementations/crypto_aead/isapa128av20/opt_32_compact/forceinline.h new file mode 120000 index 0000000..40fac5f --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/opt_32_compact/forceinline.h @@ -0,0 +1 @@ +../opt_32/forceinline.h \ No newline at end of file diff --git a/isap/Implementations/crypto_aead/isapa128av20/opt_32_compact/isap.c b/isap/Implementations/crypto_aead/isapa128av20/opt_32_compact/isap.c new file mode 120000 index 0000000..ef78763 --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/opt_32_compact/isap.c @@ -0,0 +1 @@ +../opt_32/isap.c \ No newline at end of file diff --git a/isap/Implementations/crypto_aead/isapa128av20/opt_32_compact/isap.h b/isap/Implementations/crypto_aead/isapa128av20/opt_32_compact/isap.h new file mode 120000 index 0000000..772faa3 --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/opt_32_compact/isap.h @@ -0,0 +1 @@ +../opt_32/isap.h \ No newline at end of file diff --git a/isap/Implementations/crypto_aead/isapa128av20/opt_32_stp/api.h b/isap/Implementations/crypto_aead/isapa128av20/opt_32_stp/api.h new file mode 120000 index 0000000..248197f --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/opt_32_stp/api.h @@ -0,0 +1 @@ +../opt_32/api.h \ No newline at end of file diff --git a/isap/Implementations/crypto_aead/isapa128av20/opt_32_stp/asconp.h b/isap/Implementations/crypto_aead/isapa128av20/opt_32_stp/asconp.h new file mode 100644 index 0000000..0f5aeee --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/opt_32_stp/asconp.h @@ -0,0 +1,112 @@ +#ifndef ASCONP_H_ +#define ASCONP_H_ + +#include +#include "forceinline.h" + +typedef union +{ + uint64_t x; + uint32_t w[2]; + uint8_t b[8]; +} lane_t; + +typedef union +{ + lane_t l[5]; + uint64_t x[5]; + uint32_t w[5][2]; + uint8_t b[5][8]; +} state_t; + +/* ---------------------------------------------------------------- */ + +#define P_sH PROUNDS(s, 12) +#define P_sB PROUNDS(s, 1) +#define P_sE PROUNDS(s, 6) +#define P_sK PROUNDS(s, 12) +#define P_PVP PROUNDS(s, 7) + +/* ---------------------------------------------------------------- */ + +#define U64TOWORD(x) U64BIG(x) +#define WORDTOU64(x) U64BIG(x) + +/* ---------------------------------------------------------------- */ + +#define TOBI(x) (x) +#define FROMBI(x) (x) + +/* ---------------------------------------------------------------- */ + +lane_t U64BIG(lane_t x) +{ + x.x = ((((x.x) & 0x00000000000000FFULL) << 56) | (((x.x) & 0x000000000000FF00ULL) << 40) | + (((x.x) & 0x0000000000FF0000ULL) << 24) | (((x.x) & 0x00000000FF000000ULL) << 8) | + (((x.x) & 0x000000FF00000000ULL) >> 8) | (((x.x) & 0x0000FF0000000000ULL) >> 24) | + (((x.x) & 0x00FF000000000000ULL) >> 40) | (((x.x) & 0xFF00000000000000ULL) >> 56)); + return x; +} + +/* ---------------------------------------------------------------- */ + +forceinline void ROUND(state_t *s, uint8_t C) +{ + uint64_t xtemp; + /* round constant */ + s->x[2] ^= C; + /* s-box layer */ + s->x[0] ^= s->x[4]; + s->x[4] ^= s->x[3]; + s->x[2] ^= s->x[1]; + xtemp = s->x[0] & ~s->x[4]; + s->x[0] ^= s->x[2] & ~s->x[1]; + s->x[2] ^= s->x[4] & ~s->x[3]; + s->x[4] ^= s->x[1] & ~s->x[0]; + s->x[1] ^= s->x[3] & ~s->x[2]; + s->x[3] ^= xtemp; + s->x[1] ^= s->x[0]; + s->x[3] ^= s->x[2]; + s->x[0] ^= s->x[4]; + s->x[2] = ~s->x[2]; + /* linear layer */ + s->x[0] ^= + (s->x[0] >> 19) ^ (s->x[0] << 45) ^ (s->x[0] >> 28) ^ (s->x[0] << 36); + s->x[1] ^= + (s->x[1] >> 61) ^ (s->x[1] << 3) ^ (s->x[1] >> 39) ^ (s->x[1] << 25); + s->x[2] ^= + (s->x[2] >> 1) ^ (s->x[2] << 63) ^ (s->x[2] >> 6) ^ (s->x[2] << 58); + s->x[3] ^= + (s->x[3] >> 10) ^ (s->x[3] << 54) ^ (s->x[3] >> 17) ^ (s->x[3] << 47); + s->x[4] ^= + (s->x[4] >> 7) ^ (s->x[4] << 57) ^ (s->x[4] >> 41) ^ (s->x[4] << 23); +} + +/* ---------------------------------------------------------------- */ + +void PROUNDS(state_t *s, uint8_t nr) +{ + switch (nr) + { + case 12: + ROUND(s, 0xf0); + ROUND(s, 0xe1); + ROUND(s, 0xd2); + ROUND(s, 0xc3); + ROUND(s, 0xb4); + case 7: + ROUND(s, 0xa5); + case 6: + ROUND(s, 0x96); + ROUND(s, 0x87); + ROUND(s, 0x78); + ROUND(s, 0x69); + ROUND(s, 0x5a); + default: + ROUND(s, 0x4b); + } +} + +/* ---------------------------------------------------------------- */ + +#endif // ASCONP_H_ diff --git a/isap/Implementations/crypto_aead/isapa128av20/opt_32_stp/config.h b/isap/Implementations/crypto_aead/isapa128av20/opt_32_stp/config.h new file mode 100644 index 0000000..2e1c76f --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/opt_32_stp/config.h @@ -0,0 +1,16 @@ +#ifndef CONFIG_H +#define CONFIG_H + +#define ENABLE_HASH 0 + +#include "isap.h" + +// ISAP-A-128a +const uint8_t ISAP_IV_A[] = {0x01, ISAP_K, ISAP_rH, ISAP_rB, ISAP_sH, ISAP_sB, ISAP_sE, ISAP_sK}; +const uint8_t ISAP_IV_KA[] = {0x02, ISAP_K, ISAP_rH, ISAP_rB, ISAP_sH, ISAP_sB, ISAP_sE, ISAP_sK}; +const uint8_t ISAP_IV_KE[] = {0x03, ISAP_K, ISAP_rH, ISAP_rB, ISAP_sH, ISAP_sB, ISAP_sE, ISAP_sK}; + +// Ascon-Hash +const uint8_t ASCON_HASH_IV[] = {0x00, 0x40, 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00}; + +#endif // CONFIG_H diff --git a/isap/Implementations/crypto_aead/isapa128av20/opt_32_stp/crypto_aead.c b/isap/Implementations/crypto_aead/isapa128av20/opt_32_stp/crypto_aead.c new file mode 100644 index 0000000..e0d533c --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/opt_32_stp/crypto_aead.c @@ -0,0 +1,68 @@ +#include "api.h" +#include "isap.h" +#include "crypto_aead.h" + +int crypto_aead_encrypt( + unsigned char *c, unsigned long long *clen, + const unsigned char *m, unsigned long long mlen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k) +{ + (void)nsec; + + // Ciphertext length is mlen + tag length + *clen = mlen + ISAP_TAG_SZ; + + // Encrypt plaintext + if (mlen > 0) + { + isap_enc(k, npub, m, mlen, c); + } + + // Generate tag + unsigned char *tag = c + mlen; + isap_mac(k, npub, ad, adlen, c, mlen, tag); + return 0; +} + +int crypto_aead_decrypt( + unsigned char *m, unsigned long long *mlen, + unsigned char *nsec, + const unsigned char *c, unsigned long long clen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) +{ + (void)nsec; + + // Plaintext length is clen - tag length + *mlen = clen - ISAP_TAG_SZ; + + // Generate tag + unsigned char T[16]; + isap_mac(k, npub, ad, adlen, c, *mlen, T); + + // Compare tag + unsigned char T_star[16]; + for (int i = 0; i < 16; i++) + { + T_star[i] = *(c + *mlen + i); + } + int eq_cnt = pvp(T, T_star); + + // Perform decryption if tag is correct + if (eq_cnt == ISAP_TAG_SZ) + { + if (*mlen > 0) + { + isap_enc(k, npub, c, *mlen, m); + } + return 0; + } + else + { + return -1; + } +} diff --git a/isap/Implementations/crypto_aead/isapa128av20/opt_32_stp/forceinline.h b/isap/Implementations/crypto_aead/isapa128av20/opt_32_stp/forceinline.h new file mode 120000 index 0000000..40fac5f --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/opt_32_stp/forceinline.h @@ -0,0 +1 @@ +../opt_32/forceinline.h \ No newline at end of file diff --git a/isap/Implementations/crypto_aead/isapa128av20/opt_32_stp/isap.c b/isap/Implementations/crypto_aead/isapa128av20/opt_32_stp/isap.c new file mode 100644 index 0000000..2fa2aed --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/opt_32_stp/isap.c @@ -0,0 +1,276 @@ +#include +#include +#include "api.h" +#include "isap.h" +#include "asconp.h" +#include "config.h" + +// Needed for LR tag comparison +uint64_t s0, s1; + +forceinline void ABSORB_LANES(state_t *s, const uint8_t *src, uint64_t len) +{ + while (len >= 8) + { + // Absorb full lanes + lane_t t0 = U64TOWORD(*(lane_t *)(src + 0)); + s->x[0] ^= t0.x; + len -= ISAP_rH / 8; + src += ISAP_rH / 8; + P_sH; + } + + if (len > 0) + { + // Absorb partial lane and padding + size_t i; + lane_t t0 = {0}; + for (i = 0; i < len; i++) + { + t0.b[7 - i] ^= *src; + src++; + } + t0.b[7 - i] ^= 0x80; + t0 = TOBI(t0); + s->x[0] ^= t0.x; + P_sH; + } + else + { + // Absorb padded empty lane + s->b[0][7] ^= 0x80; + P_sH; + } +} + +/******************************************************************************/ +/* ISAP_RK */ +/******************************************************************************/ + +void isap_rk( + const uint8_t *k, + const uint8_t *iv, + const uint8_t *y, + state_t *out, + const size_t outlen) +{ + state_t state; + state_t *s = &state; + + // Initialize + s->l[0] = U64TOWORD(*(lane_t *)(k + 0)); + s->l[1] = U64TOWORD(*(lane_t *)(k + 8)); + s->l[2] = U64TOWORD(*(lane_t *)(iv + 0)); + s->x[3] = 0; + s->x[4] = 0; + P_sK; + + // Absorb Y, bit by bit + for (size_t i = 0; i < 16; i++) + { + uint8_t y_byte = *y; + s->b[0][7] ^= (y_byte & 0x80) << 0; + P_sB; + s->b[0][7] ^= (y_byte & 0x40) << 1; + P_sB; + s->b[0][7] ^= (y_byte & 0x20) << 2; + P_sB; + s->b[0][7] ^= (y_byte & 0x10) << 3; + P_sB; + s->b[0][7] ^= (y_byte & 0x08) << 4; + P_sB; + s->b[0][7] ^= (y_byte & 0x04) << 5; + P_sB; + s->b[0][7] ^= (y_byte & 0x02) << 6; + P_sB; + s->b[0][7] ^= (y_byte & 0x01) << 7; + if (i != 15) + { + P_sB; + y += 1; + } + } + + // Squeeze K* + P_sK; + out->x[0] = s->x[0]; + out->x[1] = s->x[1]; + if (outlen > 16) + { + out->x[2] = s->x[2]; + } +} + +/******************************************************************************/ +/* ISAP_MAC */ +/******************************************************************************/ + +void isap_mac( + const uint8_t *k, + const uint8_t *npub, + const uint8_t *ad, uint64_t adlen, + const uint8_t *c, uint64_t clen, + uint8_t *tag) +{ + state_t state; + state_t *s = &state; + + // Initialize + s->l[0] = U64TOWORD(*(lane_t *)(npub + 0)); + s->l[1] = U64TOWORD(*(lane_t *)(npub + 8)); + s->l[2] = U64TOWORD(*(lane_t *)(ISAP_IV_A + 0)); + s->x[3] = 0; + s->x[4] = 0; + P_sH; + + // Absorb associated data + ABSORB_LANES(s, ad, adlen); + + // Domain seperation + s->w[4][0] ^= 0x1UL; + + // Absorb ciphertext + ABSORB_LANES(s, c, clen); + + // Needed for LR tag comparison + s0 = s->x[0]; + s1 = s->x[1]; + + // Derive KA* + s->l[0] = WORDTOU64(s->l[0]); + s->l[1] = WORDTOU64(s->l[1]); + isap_rk(k, ISAP_IV_KA, (const uint8_t *)(s->b), s, CRYPTO_KEYBYTES); + + // Squeeze tag + P_sH; + lane_t t0 = WORDTOU64(s->l[0]); + memcpy(tag + 0, t0.b, 8); + t0 = WORDTOU64(s->l[1]); + memcpy(tag + 8, t0.b, 8); +} + +/******************************************************************************/ +/* Leakage resilient tag comparison. */ +/* Similar to Fig.3 of https://eprint.iacr.org/2021/402.pdf. */ +/******************************************************************************/ + +int pvp( + const uint8_t *T, const uint8_t *T_star) +{ + state_t state; + state_t *s = &state; + + // Calculate U + s->l[0] = U64TOWORD(*(lane_t *)(T + 0)); + s->l[1] = U64TOWORD(*(lane_t *)(T + 8)); + s->x[2] = s0; + s->x[3] = s1; + s->x[4] = 0; + P_PVP; + uint64_t u0, u1; + u0 = s->x[0]; + u1 = s->x[1]; + + // Calculate U' + s->l[0] = U64TOWORD(*(lane_t *)(T_star + 0)); + s->l[1] = U64TOWORD(*(lane_t *)(T_star + 8)); + s->x[2] = s0; + s->x[3] = s1; + s->x[4] = 0; + P_PVP; + + // Compare tag + int eq_cnt = 0; + for (size_t i = 0; i < 8; i++) + { + eq_cnt += (s->b[0][i] == ((uint8_t *)&u0)[i]); + } + for (size_t i = 0; i < 8; i++) + { + eq_cnt += (s->b[1][i] == ((uint8_t *)&u1)[i]); + } + return eq_cnt; +} + +/******************************************************************************/ +/* ISAP_ENC */ +/******************************************************************************/ + +void isap_enc( + const uint8_t *k, + const uint8_t *npub, + const uint8_t *m, uint64_t mlen, + uint8_t *c) + +{ + state_t state; + state_t *s = &state; + + // Init state + isap_rk(k, ISAP_IV_KE, npub, s, ISAP_STATE_SZ - CRYPTO_NPUBBYTES); + s->l[3] = U64TOWORD(*(lane_t *)(npub + 0)); + s->l[4] = U64TOWORD(*(lane_t *)(npub + 8)); + + while (mlen >= ISAP_rH / 8) + { + // Encrypt full lanes + P_sE; + lane_t t0 = WORDTOU64(s->l[0]); + *(uint64_t *)c = *(uint64_t *)m ^ t0.x; + mlen -= ISAP_rH / 8; + m += ISAP_rH / 8; + c += ISAP_rH / 8; + } + + if (mlen > 0) + { + // Encrypt partial lanes + P_sE; + lane_t t0 = WORDTOU64(s->l[0]); + for (uint8_t i = 0; i < mlen; i++) + { + *c = *m ^ t0.b[i]; + m += 1; + c += 1; + } + } +} + +/******************************************************************************/ +/* Ascon-Hash */ +/******************************************************************************/ + +#if ENABLE_HASH == 1 + +int crypto_hash(uint8_t *out, const uint8_t *in, unsigned long long inlen) +{ + + state_t state; + state_t *s = &state; + + // Initialize + s->l[0] = U64TOWORD(*(lane_t *)(ASCON_HASH_IV + 0)); + s->x[1] = 0; + s->x[2] = 0; + s->x[3] = 0; + s->x[4] = 0; + P_sH; + + // Absorb input + ABSORB_LANES(s, in, inlen); + + for (size_t i = 0; i < 4; i++) + { + // Squeeze full lanes + lane_t t0 = WORDTOU64(s->l[0]); + *(uint64_t *)(out + 8 * i) = t0.x; + if (i < 3) + { + P_sH; + } + } + + return 0; +} + +#endif diff --git a/isap/Implementations/crypto_aead/isapa128av20/opt_32_stp/isap.h b/isap/Implementations/crypto_aead/isapa128av20/opt_32_stp/isap.h new file mode 100644 index 0000000..55464cb --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/opt_32_stp/isap.h @@ -0,0 +1,48 @@ +#ifndef ISAP_H +#define ISAP_H + +#include + +// Rate in bits +#define ISAP_rH 64 +#define ISAP_rB 1 + +// Number of rounds +#define ISAP_sH 12 +#define ISAP_sB 1 +#define ISAP_sE 6 +#define ISAP_sK 12 + +// State size in bytes +#define ISAP_STATE_SZ 40 + +// Size of rate in bytes +#define ISAP_rH_SZ ((ISAP_rH + 7) / 8) + +// Size of zero truncated IV in bytes +#define ISAP_IV_SZ 8 + +// Size of tag in bytes +#define ISAP_TAG_SZ 16 + +// Security level +#define ISAP_K 128 + +void isap_mac( + const uint8_t *k, + const uint8_t *npub, + const uint8_t *ad, const uint64_t adlen, + const uint8_t *c, const uint64_t clen, + uint8_t *tag); + +int pvp( + const uint8_t *T, + const uint8_t *T_star); + +void isap_enc( + const uint8_t *k, + const uint8_t *npub, + const uint8_t *m, uint64_t mlen, + uint8_t *c); + +#endif diff --git a/isap/Implementations/crypto_aead/isapa128av20/opt_32_tiny/api.h b/isap/Implementations/crypto_aead/isapa128av20/opt_32_tiny/api.h new file mode 120000 index 0000000..248197f --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/opt_32_tiny/api.h @@ -0,0 +1 @@ +../opt_32/api.h \ No newline at end of file diff --git a/isap/Implementations/crypto_aead/isapa128av20/opt_32_tiny/asconp.h b/isap/Implementations/crypto_aead/isapa128av20/opt_32_tiny/asconp.h new file mode 100644 index 0000000..7d4419c --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/opt_32_tiny/asconp.h @@ -0,0 +1,103 @@ +#ifndef ASCONP_H_ +#define ASCONP_H_ + +#include +#include "forceinline.h" + +typedef union +{ + uint64_t x; + uint32_t w[2]; + uint8_t b[8]; +} lane_t; + +typedef union +{ + lane_t l[5]; + uint64_t x[5]; + uint32_t w[5][2]; + uint8_t b[5][8]; +} state_t; + +/* ---------------------------------------------------------------- */ + +#define P_sH PROUNDS(s, 12) +#define P_sB PROUNDS(s, 1) +#define P_sE PROUNDS(s, 6) +#define P_sK PROUNDS(s, 12) + +/* ---------------------------------------------------------------- */ + +#define U64TOWORD(x) U64BIG(x) +#define WORDTOU64(x) U64BIG(x) + +/* ---------------------------------------------------------------- */ + +#define TOBI(x) (x) +#define FROMBI(x) (x) + +/* ---------------------------------------------------------------- */ + +lane_t U64BIG(lane_t x) +{ + x.x = ((((x.x) & 0x00000000000000FFULL) << 56) | (((x.x) & 0x000000000000FF00ULL) << 40) | + (((x.x) & 0x0000000000FF0000ULL) << 24) | (((x.x) & 0x00000000FF000000ULL) << 8) | + (((x.x) & 0x000000FF00000000ULL) >> 8) | (((x.x) & 0x0000FF0000000000ULL) >> 24) | + (((x.x) & 0x00FF000000000000ULL) >> 40) | (((x.x) & 0xFF00000000000000ULL) >> 56)); + return x; +} + +/* ---------------------------------------------------------------- */ + +void ROUND(state_t *s, uint8_t C) +{ + uint64_t xtemp; + /* round constant */ + s->x[2] ^= C; + /* s-box layer */ + s->x[0] ^= s->x[4]; + s->x[4] ^= s->x[3]; + s->x[2] ^= s->x[1]; + xtemp = s->x[0] & ~s->x[4]; + s->x[0] ^= s->x[2] & ~s->x[1]; + s->x[2] ^= s->x[4] & ~s->x[3]; + s->x[4] ^= s->x[1] & ~s->x[0]; + s->x[1] ^= s->x[3] & ~s->x[2]; + s->x[3] ^= xtemp; + s->x[1] ^= s->x[0]; + s->x[3] ^= s->x[2]; + s->x[0] ^= s->x[4]; + s->x[2] = ~s->x[2]; + /* linear layer */ + s->x[0] ^= + (s->x[0] >> 19) ^ (s->x[0] << 45) ^ (s->x[0] >> 28) ^ (s->x[0] << 36); + s->x[1] ^= + (s->x[1] >> 61) ^ (s->x[1] << 3) ^ (s->x[1] >> 39) ^ (s->x[1] << 25); + s->x[2] ^= + (s->x[2] >> 1) ^ (s->x[2] << 63) ^ (s->x[2] >> 6) ^ (s->x[2] << 58); + s->x[3] ^= + (s->x[3] >> 10) ^ (s->x[3] << 54) ^ (s->x[3] >> 17) ^ (s->x[3] << 47); + s->x[4] ^= + (s->x[4] >> 7) ^ (s->x[4] << 57) ^ (s->x[4] >> 41) ^ (s->x[4] << 23); +} + +/* ---------------------------------------------------------------- */ + +#define RC(i) (i) +#define START(n) ((3 + (n)) << 4 | (12 - (n))) +#define INC -0x0f +#define END 0x3c + +void PROUNDS(state_t *s, uint8_t nr) +{ + int i = START(nr); + do + { + ROUND(s, RC(i)); + i += INC; + } while (i != END); +} + +/* ---------------------------------------------------------------- */ + +#endif // ASCONP_H_ diff --git a/isap/Implementations/crypto_aead/isapa128av20/opt_32_tiny/config.h b/isap/Implementations/crypto_aead/isapa128av20/opt_32_tiny/config.h new file mode 100644 index 0000000..2e1c76f --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/opt_32_tiny/config.h @@ -0,0 +1,16 @@ +#ifndef CONFIG_H +#define CONFIG_H + +#define ENABLE_HASH 0 + +#include "isap.h" + +// ISAP-A-128a +const uint8_t ISAP_IV_A[] = {0x01, ISAP_K, ISAP_rH, ISAP_rB, ISAP_sH, ISAP_sB, ISAP_sE, ISAP_sK}; +const uint8_t ISAP_IV_KA[] = {0x02, ISAP_K, ISAP_rH, ISAP_rB, ISAP_sH, ISAP_sB, ISAP_sE, ISAP_sK}; +const uint8_t ISAP_IV_KE[] = {0x03, ISAP_K, ISAP_rH, ISAP_rB, ISAP_sH, ISAP_sB, ISAP_sE, ISAP_sK}; + +// Ascon-Hash +const uint8_t ASCON_HASH_IV[] = {0x00, 0x40, 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00}; + +#endif // CONFIG_H diff --git a/isap/Implementations/crypto_aead/isapa128av20/opt_32_tiny/crypto_aead.c b/isap/Implementations/crypto_aead/isapa128av20/opt_32_tiny/crypto_aead.c new file mode 120000 index 0000000..89bbb06 --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/opt_32_tiny/crypto_aead.c @@ -0,0 +1 @@ +../opt_32/crypto_aead.c \ No newline at end of file diff --git a/isap/Implementations/crypto_aead/isapa128av20/opt_32_tiny/forceinline.h b/isap/Implementations/crypto_aead/isapa128av20/opt_32_tiny/forceinline.h new file mode 120000 index 0000000..40fac5f --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/opt_32_tiny/forceinline.h @@ -0,0 +1 @@ +../opt_32/forceinline.h \ No newline at end of file diff --git a/isap/Implementations/crypto_aead/isapa128av20/opt_32_tiny/isap.c b/isap/Implementations/crypto_aead/isapa128av20/opt_32_tiny/isap.c new file mode 100644 index 0000000..18bcc4a --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/opt_32_tiny/isap.c @@ -0,0 +1,226 @@ +#include +#include +#include "api.h" +#include "isap.h" +#include "asconp.h" +#include "config.h" + +void ABSORB_LANES(state_t *s, const uint8_t *src, uint64_t len) +{ + while (len >= 8) + { + // Absorb full lanes + lane_t t0 = U64TOWORD(*(lane_t *)(src + 0)); + s->x[0] ^= t0.x; + len -= ISAP_rH / 8; + src += ISAP_rH / 8; + P_sH; + } + + if (len > 0) + { + // Absorb partial lane and padding + size_t i; + lane_t t0 = {0}; + for (i = 0; i < len; i++) + { + t0.b[7 - i] ^= *src; + src++; + } + t0.b[7 - i] ^= 0x80; + t0 = TOBI(t0); + s->x[0] ^= t0.x; + P_sH; + } + else + { + // Absorb padded empty lane + s->b[0][7] ^= 0x80; + P_sH; + } +} + +/******************************************************************************/ +/* ISAP_RK */ +/******************************************************************************/ + +void isap_rk( + const uint8_t *k, + const uint8_t *iv, + const uint8_t *y, + state_t *out, + const size_t outlen) +{ + state_t state; + state_t *s = &state; + + // Initialize + s->l[0] = U64TOWORD(*(lane_t *)(k + 0)); + s->l[1] = U64TOWORD(*(lane_t *)(k + 8)); + s->l[2] = U64TOWORD(*(lane_t *)(iv + 0)); + s->x[3] = 0; + s->x[4] = 0; + P_sK; + + // Absorb Y, bit by bit + for (size_t i = 0; i < 16; i++) + { + uint8_t y_byte = *y; + s->b[0][7] ^= (y_byte & 0x80) << 0; + P_sB; + s->b[0][7] ^= (y_byte & 0x40) << 1; + P_sB; + s->b[0][7] ^= (y_byte & 0x20) << 2; + P_sB; + s->b[0][7] ^= (y_byte & 0x10) << 3; + P_sB; + s->b[0][7] ^= (y_byte & 0x08) << 4; + P_sB; + s->b[0][7] ^= (y_byte & 0x04) << 5; + P_sB; + s->b[0][7] ^= (y_byte & 0x02) << 6; + P_sB; + s->b[0][7] ^= (y_byte & 0x01) << 7; + if (i != 15) + { + P_sB; + y += 1; + } + } + + // Squeeze K* + P_sK; + out->x[0] = s->x[0]; + out->x[1] = s->x[1]; + if (outlen > 16) + { + out->x[2] = s->x[2]; + } +} + +/******************************************************************************/ +/* ISAP_MAC */ +/******************************************************************************/ + +void isap_mac( + const uint8_t *k, + const uint8_t *npub, + const uint8_t *ad, uint64_t adlen, + const uint8_t *c, uint64_t clen, + uint8_t *tag) +{ + state_t state; + state_t *s = &state; + + // Initialize + s->l[0] = U64TOWORD(*(lane_t *)(npub + 0)); + s->l[1] = U64TOWORD(*(lane_t *)(npub + 8)); + s->l[2] = U64TOWORD(*(lane_t *)(ISAP_IV_A + 0)); + s->x[3] = 0; + s->x[4] = 0; + P_sH; + + // Absorb associated data + ABSORB_LANES(s, ad, adlen); + + // Domain seperation + s->w[4][0] ^= 0x1UL; + + // Absorb ciphertext + ABSORB_LANES(s, c, clen); + + // Derive KA* + s->l[0] = WORDTOU64(s->l[0]); + s->l[1] = WORDTOU64(s->l[1]); + isap_rk(k, ISAP_IV_KA, (const uint8_t *)(s->b), s, CRYPTO_KEYBYTES); + + // Squeeze tag + P_sH; + lane_t t0 = WORDTOU64(s->l[0]); + memcpy(tag + 0, t0.b, 8); + t0 = WORDTOU64(s->l[1]); + memcpy(tag + 8, t0.b, 8); +} + +/******************************************************************************/ +/* ISAP_ENC */ +/******************************************************************************/ + +void isap_enc( + const uint8_t *k, + const uint8_t *npub, + const uint8_t *m, uint64_t mlen, + uint8_t *c) + +{ + state_t state; + state_t *s = &state; + + // Init state + isap_rk(k, ISAP_IV_KE, npub, s, ISAP_STATE_SZ - CRYPTO_NPUBBYTES); + s->l[3] = U64TOWORD(*(lane_t *)(npub + 0)); + s->l[4] = U64TOWORD(*(lane_t *)(npub + 8)); + + while (mlen >= ISAP_rH / 8) + { + // Encrypt full lanes + P_sE; + lane_t t0 = WORDTOU64(s->l[0]); + *(uint64_t *)c = *(uint64_t *)m ^ t0.x; + mlen -= ISAP_rH / 8; + m += ISAP_rH / 8; + c += ISAP_rH / 8; + } + + if (mlen > 0) + { + // Encrypt partial lanes + P_sE; + lane_t t0 = WORDTOU64(s->l[0]); + for (uint8_t i = 0; i < mlen; i++) + { + *c = *m ^ t0.b[i]; + m += 1; + c += 1; + } + } +} + +/******************************************************************************/ +/* Ascon-Hash */ +/******************************************************************************/ + +#if ENABLE_HASH == 1 + +int crypto_hash(uint8_t *out, const uint8_t *in, unsigned long long inlen) +{ + + state_t state; + state_t *s = &state; + + // Initialize + s->l[0] = U64TOWORD(*(lane_t *)(ASCON_HASH_IV + 0)); + s->x[1] = 0; + s->x[2] = 0; + s->x[3] = 0; + s->x[4] = 0; + P_sH; + + // Absorb input + ABSORB_LANES(s, in, inlen); + + for (size_t i = 0; i < 4; i++) + { + // Squeeze full lanes + lane_t t0 = WORDTOU64(s->l[0]); + *(uint64_t *)(out + 8 * i) = t0.x; + if (i < 3) + { + P_sH; + } + } + + return 0; +} + +#endif diff --git a/isap/Implementations/crypto_aead/isapa128av20/opt_32_tiny/isap.h b/isap/Implementations/crypto_aead/isapa128av20/opt_32_tiny/isap.h new file mode 120000 index 0000000..772faa3 --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/opt_32_tiny/isap.h @@ -0,0 +1 @@ +../opt_32/isap.h \ No newline at end of file diff --git a/isap/Implementations/crypto_aead/isapa128av20/opt_64/api.h b/isap/Implementations/crypto_aead/isapa128av20/opt_64/api.h index 1ec1f0f..83ebf98 100644 --- a/isap/Implementations/crypto_aead/isapa128av20/opt_64/api.h +++ b/isap/Implementations/crypto_aead/isapa128av20/opt_64/api.h @@ -1,13 +1,16 @@ #ifndef API_H #define API_H -#define CRYPTO_VERSION "2.0.1" +// isapa128a #define CRYPTO_KEYBYTES 16 #define CRYPTO_NSECBYTES 0 #define CRYPTO_NPUBBYTES 16 #define CRYPTO_ABYTES 16 #define CRYPTO_NOOVERLAP 1 + +// asconhashv12 #define CRYPTO_BYTES 32 +#define ASCON_HASH_OUTLEN 32 +#define ASCON_HASH_ROUNDS 12 #endif - diff --git a/isap/Implementations/crypto_aead/isapa128av20/opt_64/asconp.h b/isap/Implementations/crypto_aead/isapa128av20/opt_64/asconp.h index 41cf25b..36d8cce 100644 --- a/isap/Implementations/crypto_aead/isapa128av20/opt_64/asconp.h +++ b/isap/Implementations/crypto_aead/isapa128av20/opt_64/asconp.h @@ -1,100 +1,126 @@ -typedef unsigned char u8; -typedef unsigned long u32; -typedef unsigned long long u64; - -#define ASCON_128_RATE 8 -#define ASCON_128_PA_ROUNDS 12 -#define ASCON_128_STATE_SZ 40 - -#define ASCON_HASH_IV \ - (((u64)(ASCON_128_RATE * 8) << 48) | \ - ((u64)(ASCON_128_PA_ROUNDS) << 40) | \ - ((u64)(CRYPTO_BYTES * 8) << 0)) - -#define ROTR(x,n) (((x)>>(n))|((x)<<(64-(n)))) -#define EXT_BYTE(x,n) ((u8)((u64)(x)>>(8*(7-(n))))) -#define INS_BYTE(x,n) ((u64)(x)<<(8*(7-(n)))) - -#define U64BIG(x) \ - ((ROTR(x, 8) & (0xFF000000FF000000ULL)) | \ - (ROTR(x,24) & (0x00FF000000FF0000ULL)) | \ - (ROTR(x,40) & (0x0000FF000000FF00ULL)) | \ - (ROTR(x,56) & (0x000000FF000000FFULL))) - -#define ROUND(C) ({\ - x2 ^= C;\ - x0 ^= x4;\ - x4 ^= x3;\ - x2 ^= x1;\ - t0 = x0;\ - t4 = x4;\ - t3 = x3;\ - t1 = x1;\ - t2 = x2;\ - x0 = t0 ^ ((~t1) & t2);\ - x2 = t2 ^ ((~t3) & t4);\ - x4 = t4 ^ ((~t0) & t1);\ - x1 = t1 ^ ((~t2) & t3);\ - x3 = t3 ^ ((~t4) & t0);\ - x1 ^= x0;\ - t1 = x1;\ - x1 = ROTR(x1, R[1][0]);\ - x3 ^= x2;\ - t2 = x2;\ - x2 = ROTR(x2, R[2][0]);\ - t4 = x4;\ - t2 ^= x2;\ - x2 = ROTR(x2, R[2][1] - R[2][0]);\ - t3 = x3;\ - t1 ^= x1;\ - x3 = ROTR(x3, R[3][0]);\ - x0 ^= x4;\ - x4 = ROTR(x4, R[4][0]);\ - t3 ^= x3;\ - x2 ^= t2;\ - x1 = ROTR(x1, R[1][1] - R[1][0]);\ - t0 = x0;\ - x2 = ~x2;\ - x3 = ROTR(x3, R[3][1] - R[3][0]);\ - t4 ^= x4;\ - x4 = ROTR(x4, R[4][1] - R[4][0]);\ - x3 ^= t3;\ - x1 ^= t1;\ - x0 = ROTR(x0, R[0][0]);\ - x4 ^= t4;\ - t0 ^= x0;\ - x0 = ROTR(x0, R[0][1] - R[0][0]);\ - x0 ^= t0;\ -}) - -#define P12 ({\ - ROUND(0xf0);\ - ROUND(0xe1);\ - ROUND(0xd2);\ - ROUND(0xc3);\ - ROUND(0xb4);\ - ROUND(0xa5);\ - ROUND(0x96);\ - ROUND(0x87);\ - ROUND(0x78);\ - ROUND(0x69);\ - ROUND(0x5a);\ - ROUND(0x4b);\ -}) - -#define P6 ({\ - ROUND(0x96);\ - ROUND(0x87);\ - ROUND(0x78);\ - ROUND(0x69);\ - ROUND(0x5a);\ - ROUND(0x4b);\ -}) - -#define P1 ({\ - ROUND(0x4b);\ -}) - -static const int R[5][2] = { - {19, 28}, {39, 61}, {1, 6}, {10, 17}, {7, 41} -}; +#ifndef ASCONP_H_ +#define ASCONP_H_ + +#include +#include "forceinline.h" + +typedef union +{ + uint64_t x; + uint32_t w[2]; + uint8_t b[8]; +} lane_t; + +typedef union +{ + lane_t l[5]; + uint64_t x[5]; + uint32_t w[5][2]; + uint8_t b[5][8]; +} state_t; + +/* ---------------------------------------------------------------- */ + +#define P_sH P12ROUNDS(s) +#define P_sB P1ROUNDS(s) +#define P_sE P6ROUNDS(s) +#define P_sK P12ROUNDS(s) + +/* ---------------------------------------------------------------- */ + +#define U64TOWORD(x) U64BIG(x) +#define WORDTOU64(x) U64BIG(x) + +/* ---------------------------------------------------------------- */ + +#define TOBI(x) (x) +#define FROMBI(x) (x) + +/* ---------------------------------------------------------------- */ + +forceinline lane_t U64BIG(lane_t x) +{ + x.x = ((((x.x) & 0x00000000000000FFULL) << 56) | (((x.x) & 0x000000000000FF00ULL) << 40) | + (((x.x) & 0x0000000000FF0000ULL) << 24) | (((x.x) & 0x00000000FF000000ULL) << 8) | + (((x.x) & 0x000000FF00000000ULL) >> 8) | (((x.x) & 0x0000FF0000000000ULL) >> 24) | + (((x.x) & 0x00FF000000000000ULL) >> 40) | (((x.x) & 0xFF00000000000000ULL) >> 56)); + return x; +} + +/* ---------------------------------------------------------------- */ + +forceinline uint64_t ROR(uint64_t x, int n) { return x >> n | x << (-n & 63); } + +/* ---------------------------------------------------------------- */ + +forceinline void ROUND(state_t *s, uint8_t C) +{ + state_t t; + /* round constant */ + s->x[2] ^= C; + /* s-box layer */ + s->x[0] ^= s->x[4]; + s->x[4] ^= s->x[3]; + s->x[2] ^= s->x[1]; + t.x[0] = s->x[0] ^ (~s->x[1] & s->x[2]); + t.x[2] = s->x[2] ^ (~s->x[3] & s->x[4]); + t.x[4] = s->x[4] ^ (~s->x[0] & s->x[1]); + t.x[1] = s->x[1] ^ (~s->x[2] & s->x[3]); + t.x[3] = s->x[3] ^ (~s->x[4] & s->x[0]); + t.x[1] ^= t.x[0]; + t.x[3] ^= t.x[2]; + t.x[0] ^= t.x[4]; + /* linear layer */ + s->x[2] = t.x[2] ^ ROR(t.x[2], 6 - 1); + s->x[3] = t.x[3] ^ ROR(t.x[3], 17 - 10); + s->x[4] = t.x[4] ^ ROR(t.x[4], 41 - 7); + s->x[0] = t.x[0] ^ ROR(t.x[0], 28 - 19); + s->x[1] = t.x[1] ^ ROR(t.x[1], 61 - 39); + s->x[2] = t.x[2] ^ ROR(s->x[2], 1); + s->x[3] = t.x[3] ^ ROR(s->x[3], 10); + s->x[4] = t.x[4] ^ ROR(s->x[4], 7); + s->x[0] = t.x[0] ^ ROR(s->x[0], 19); + s->x[1] = t.x[1] ^ ROR(s->x[1], 39); + s->x[2] = ~s->x[2]; +} + +/* ---------------------------------------------------------------- */ + +forceinline void P12ROUNDS(state_t *s) +{ + ROUND(s, 0xf0); + ROUND(s, 0xe1); + ROUND(s, 0xd2); + ROUND(s, 0xc3); + ROUND(s, 0xb4); + ROUND(s, 0xa5); + ROUND(s, 0x96); + ROUND(s, 0x87); + ROUND(s, 0x78); + ROUND(s, 0x69); + ROUND(s, 0x5a); + ROUND(s, 0x4b); +} + +/* ---------------------------------------------------------------- */ + +forceinline void P6ROUNDS(state_t *s) +{ + ROUND(s, 0x96); + ROUND(s, 0x87); + ROUND(s, 0x78); + ROUND(s, 0x69); + ROUND(s, 0x5a); + ROUND(s, 0x4b); +} + +/* ---------------------------------------------------------------- */ + +forceinline void P1ROUNDS(state_t *s) +{ + ROUND(s, 0x4b); +} + +/* ---------------------------------------------------------------- */ + +#endif // ASCONP_H_ diff --git a/isap/Implementations/crypto_aead/isapa128av20/opt_64/config.h b/isap/Implementations/crypto_aead/isapa128av20/opt_64/config.h new file mode 100644 index 0000000..2e1c76f --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/opt_64/config.h @@ -0,0 +1,16 @@ +#ifndef CONFIG_H +#define CONFIG_H + +#define ENABLE_HASH 0 + +#include "isap.h" + +// ISAP-A-128a +const uint8_t ISAP_IV_A[] = {0x01, ISAP_K, ISAP_rH, ISAP_rB, ISAP_sH, ISAP_sB, ISAP_sE, ISAP_sK}; +const uint8_t ISAP_IV_KA[] = {0x02, ISAP_K, ISAP_rH, ISAP_rB, ISAP_sH, ISAP_sB, ISAP_sE, ISAP_sK}; +const uint8_t ISAP_IV_KE[] = {0x03, ISAP_K, ISAP_rH, ISAP_rB, ISAP_sH, ISAP_sB, ISAP_sE, ISAP_sK}; + +// Ascon-Hash +const uint8_t ASCON_HASH_IV[] = {0x00, 0x40, 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00}; + +#endif // CONFIG_H diff --git a/isap/Implementations/crypto_aead/isapa128av20/opt_64/forceinline.h b/isap/Implementations/crypto_aead/isapa128av20/opt_64/forceinline.h new file mode 100644 index 0000000..ba695cb --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/opt_64/forceinline.h @@ -0,0 +1,19 @@ +#ifndef FORCEINLINE_H_ +#define FORCEINLINE_H_ + +/* define forceinline macro */ +#ifdef _MSC_VER +#define forceinline __forceinline +#elif defined(__GNUC__) +#define forceinline inline __attribute__((__always_inline__)) +#elif defined(__CLANG__) +#if __has_attribute(__always_inline__) +#define forceinline inline __attribute__((__always_inline__)) +#else +#define forceinline inline +#endif +#else +#define forceinline inline +#endif + +#endif /* FORCEINLINE_H_ */ diff --git a/isap/Implementations/crypto_aead/isapa128av20/opt_64/isap.c b/isap/Implementations/crypto_aead/isapa128av20/opt_64/isap.c index 905510d..d4009e0 100644 --- a/isap/Implementations/crypto_aead/isapa128av20/opt_64/isap.c +++ b/isap/Implementations/crypto_aead/isapa128av20/opt_64/isap.c @@ -1,184 +1,226 @@ -#include #include +#include #include "api.h" #include "isap.h" #include "asconp.h" +#include "config.h" + +forceinline void ABSORB_LANES(state_t *s, const uint8_t *src, uint64_t len) +{ + while (len >= 8) + { + // Absorb full lanes + lane_t t0 = U64TOWORD(*(lane_t *)(src + 0)); + s->x[0] ^= t0.x; + len -= ISAP_rH / 8; + src += ISAP_rH / 8; + P_sH; + } -const u8 ISAP_IV1[] = {0x01,ISAP_K,ISAP_rH,ISAP_rB,ISAP_sH,ISAP_sB,ISAP_sE,ISAP_sK}; -const u8 ISAP_IV2[] = {0x02,ISAP_K,ISAP_rH,ISAP_rB,ISAP_sH,ISAP_sB,ISAP_sE,ISAP_sK}; -const u8 ISAP_IV3[] = {0x03,ISAP_K,ISAP_rH,ISAP_rB,ISAP_sH,ISAP_sB,ISAP_sE,ISAP_sK}; + if (len > 0) + { + // Absorb partial lane and padding + size_t i; + lane_t t0 = {0}; + for (i = 0; i < len; i++) + { + t0.b[7 - i] ^= *src; + src++; + } + t0.b[7 - i] ^= 0x80; + t0 = TOBI(t0); + s->x[0] ^= t0.x; + P_sH; + } + else + { + // Absorb padded empty lane + s->b[0][7] ^= 0x80; + P_sH; + } +} /******************************************************************************/ -/* IsapRk */ +/* ISAP_RK */ /******************************************************************************/ void isap_rk( - const u8 *k, - const u8 *iv, - const u8 *y, - const u64 ylen, - u8 *out, - const u64 outlen -){ - const u64 *k64 = (u64 *)k; - const u64 *iv64 = (u64 *)iv; - u64 *out64 = (u64 *)out; - u64 x0, x1, x2, x3, x4; - u64 t0, t1, t2, t3, t4; - - // Init state - t0 = t1 = t2 = t3 = t4 = 0; - x0 = U64BIG(k64[0]); - x1 = U64BIG(k64[1]); - x2 = U64BIG(iv64[0]); - x3 = x4 = 0; - P12; - - // Absorb Y - for (size_t i = 0; i < ylen*8-1; i++){ - size_t cur_byte_pos = i/8; - size_t cur_bit_pos = 7-(i%8); - u8 cur_bit = ((y[cur_byte_pos] >> (cur_bit_pos)) & 0x01) << 7; - x0 ^= ((u64)cur_bit) << 56; - P1; + const uint8_t *k, + const uint8_t *iv, + const uint8_t *y, + state_t *out, + const size_t outlen) +{ + state_t state; + state_t *s = &state; + + // Initialize + s->l[0] = U64TOWORD(*(lane_t *)(k + 0)); + s->l[1] = U64TOWORD(*(lane_t *)(k + 8)); + s->l[2] = U64TOWORD(*(lane_t *)(iv + 0)); + s->x[3] = 0; + s->x[4] = 0; + P_sK; + + // Absorb Y, bit by bit + for (size_t i = 0; i < 16; i++) + { + uint8_t y_byte = *y; + s->b[0][7] ^= (y_byte & 0x80) << 0; + P_sB; + s->b[0][7] ^= (y_byte & 0x40) << 1; + P_sB; + s->b[0][7] ^= (y_byte & 0x20) << 2; + P_sB; + s->b[0][7] ^= (y_byte & 0x10) << 3; + P_sB; + s->b[0][7] ^= (y_byte & 0x08) << 4; + P_sB; + s->b[0][7] ^= (y_byte & 0x04) << 5; + P_sB; + s->b[0][7] ^= (y_byte & 0x02) << 6; + P_sB; + s->b[0][7] ^= (y_byte & 0x01) << 7; + if (i != 15) + { + P_sB; + y += 1; + } } - u8 cur_bit = ((y[ylen-1]) & 0x01) << 7; - x0 ^= ((u64)cur_bit) << 56; - P12; - - // Extract K* - out64[0] = U64BIG(x0); - out64[1] = U64BIG(x1); - if(outlen == 24){ - out64[2] = U64BIG(x2); + + // Squeeze K* + P_sK; + out->x[0] = s->x[0]; + out->x[1] = s->x[1]; + if (outlen > 16) + { + out->x[2] = s->x[2]; } } /******************************************************************************/ -/* IsapMac */ +/* ISAP_MAC */ /******************************************************************************/ void isap_mac( - const u8 *k, - const u8 *npub, - const u8 *ad, u64 adlen, - const u8 *c, u64 clen, - u8 *tag -){ - u8 state[ISAP_STATE_SZ]; - const u64 *npub64 = (u64 *)npub; - u64 *state64 = (u64 *)state; - u64 x0, x1, x2, x3, x4; - u64 t0, t1, t2, t3, t4; - t0 = t1 = t2 = t3 = t4 = 0; - - // Init state - x0 = U64BIG(npub64[0]); - x1 = U64BIG(npub64[1]); - x2 = U64BIG(((u64 *)ISAP_IV1)[0]); - x3 = x4 = 0; - P12; - - /* Absorb ad */ - u64 *ad64 = (u64*)ad; - while(adlen >= ISAP_rH_SZ){ - x0 ^= U64BIG(*ad64); - P12; - ad64++; - adlen -= ISAP_rH_SZ; - } - - /* Absorb final ad block */ - u8 *xo = (u8*)&x0; - xo[ISAP_rH_SZ-1-adlen] ^= 0x80; - while(adlen > 0) { - xo[ISAP_rH_SZ-adlen] ^= ((u8*)ad64)[adlen-1]; - adlen--; - } - P12; + const uint8_t *k, + const uint8_t *npub, + const uint8_t *ad, uint64_t adlen, + const uint8_t *c, uint64_t clen, + uint8_t *tag) +{ + state_t state; + state_t *s = &state; + + // Initialize + s->l[0] = U64TOWORD(*(lane_t *)(npub + 0)); + s->l[1] = U64TOWORD(*(lane_t *)(npub + 8)); + s->l[2] = U64TOWORD(*(lane_t *)(ISAP_IV_A + 0)); + s->x[3] = 0; + s->x[4] = 0; + P_sH; + + // Absorb associated data + ABSORB_LANES(s, ad, adlen); // Domain seperation - x4 ^= 0x0000000000000001ULL; - - /* Absorb c */ - u64 *c64 = (u64*)c; - while(clen >= ISAP_rH_SZ){ - x0 ^= U64BIG(*c64); - P12; - c64++; - clen -= ISAP_rH_SZ; - } + s->w[4][0] ^= 0x1UL; - /* Absorb final c block */ - xo[ISAP_rH_SZ-1-clen] ^= 0x80; - while(clen > 0) { - xo[ISAP_rH_SZ-clen] ^= ((u8*)c64)[clen-1]; - clen--; - } - P12; - - // Derive K* - state64[0] = U64BIG(x0); - state64[1] = U64BIG(x1); - state64[2] = U64BIG(x2); - state64[3] = U64BIG(x3); - state64[4] = U64BIG(x4); - isap_rk(k,ISAP_IV2,(u8 *)state64,CRYPTO_KEYBYTES,(u8 *)state64,CRYPTO_KEYBYTES); - x0 = U64BIG(state64[0]); - x1 = U64BIG(state64[1]); - x2 = U64BIG(state64[2]); - x3 = U64BIG(state64[3]); - x4 = U64BIG(state64[4]); + // Absorb ciphertext + ABSORB_LANES(s, c, clen); + + // Derive KA* + s->l[0] = WORDTOU64(s->l[0]); + s->l[1] = WORDTOU64(s->l[1]); + isap_rk(k, ISAP_IV_KA, (const uint8_t *)(s->b), s, CRYPTO_KEYBYTES); // Squeeze tag - P12; - unsigned long long *tag64 = (u64 *)tag; - tag64[0] = U64BIG(x0); - tag64[1] = U64BIG(x1); + P_sH; + lane_t t0 = WORDTOU64(s->l[0]); + memcpy(tag + 0, t0.b, 8); + t0 = WORDTOU64(s->l[1]); + memcpy(tag + 8, t0.b, 8); } /******************************************************************************/ -/* IsapEnc */ +/* ISAP_ENC */ /******************************************************************************/ void isap_enc( - const u8 *k, - const u8 *npub, - const u8 *m, - u64 mlen, - u8 *c -){ - u8 state[ISAP_STATE_SZ]; + const uint8_t *k, + const uint8_t *npub, + const uint8_t *m, uint64_t mlen, + uint8_t *c) + +{ + state_t state; + state_t *s = &state; // Init state - u64 *state64 = (u64 *)state; - u64 *npub64 = (u64 *)npub; - isap_rk(k,ISAP_IV3,npub,CRYPTO_NPUBBYTES,state,ISAP_STATE_SZ-CRYPTO_NPUBBYTES); - u64 x0, x1, x2, x3, x4; - u64 t0, t1, t2, t3, t4; - t0 = t1 = t2 = t3 = t4 = 0; - x0 = U64BIG(state64[0]); - x1 = U64BIG(state64[1]); - x2 = U64BIG(state64[2]); - x3 = U64BIG(npub64[0]); - x4 = U64BIG(npub64[1]); - P6; - - /* Encrypt m */ - u64 *m64 = (u64 *)m; - u64 *c64 = (u64 *)c; - while(mlen >= ISAP_rH_SZ){ - *c64 = U64BIG(x0) ^ *m64; - P6; - m64++; - c64++; - mlen -= ISAP_rH_SZ; + isap_rk(k, ISAP_IV_KE, npub, s, ISAP_STATE_SZ - CRYPTO_NPUBBYTES); + s->l[3] = U64TOWORD(*(lane_t *)(npub + 0)); + s->l[4] = U64TOWORD(*(lane_t *)(npub + 8)); + + while (mlen >= ISAP_rH / 8) + { + // Encrypt full lanes + P_sE; + lane_t t0 = WORDTOU64(s->l[0]); + *(uint64_t *)c = *(uint64_t *)m ^ t0.x; + mlen -= ISAP_rH / 8; + m += ISAP_rH / 8; + c += ISAP_rH / 8; + } + + if (mlen > 0) + { + // Encrypt partial lanes + P_sE; + lane_t t0 = WORDTOU64(s->l[0]); + for (uint8_t i = 0; i < mlen; i++) + { + *c = *m ^ t0.b[i]; + m += 1; + c += 1; + } } +} + +/******************************************************************************/ +/* Ascon-Hash */ +/******************************************************************************/ - /* Encrypt final m block */ - u8 *xo = (u8*)&x0; - while(mlen > 0) { - ((u8*)c64)[mlen-1] = xo[ISAP_rH_SZ-mlen] ^ ((u8*)m64)[mlen-1]; - mlen--; +#if ENABLE_HASH == 1 + +int crypto_hash(uint8_t *out, const uint8_t *in, unsigned long long inlen) +{ + + state_t state; + state_t *s = &state; + + // Initialize + s->l[0] = U64TOWORD(*(lane_t *)(ASCON_HASH_IV + 0)); + s->x[1] = 0; + s->x[2] = 0; + s->x[3] = 0; + s->x[4] = 0; + P_sH; + + // Absorb input + ABSORB_LANES(s, in, inlen); + + for (size_t i = 0; i < 4; i++) + { + // Squeeze full lanes + lane_t t0 = WORDTOU64(s->l[0]); + *(uint64_t *)(out + 8 * i) = t0.x; + if (i < 3) + { + P_sH; + } } + + return 0; } + +#endif diff --git a/isap/Implementations/crypto_aead/isapa128av20/opt_64/isap.h b/isap/Implementations/crypto_aead/isapa128av20/opt_64/isap.h index a90bf32..12dfaa8 100644 --- a/isap/Implementations/crypto_aead/isapa128av20/opt_64/isap.h +++ b/isap/Implementations/crypto_aead/isapa128av20/opt_64/isap.h @@ -1,5 +1,7 @@ -#ifndef ISAP_H -#define ISAP_H +#ifndef ISAP_H_ +#define ISAP_H_ + +#include // Rate in bits #define ISAP_rH 64 @@ -15,7 +17,7 @@ #define ISAP_STATE_SZ 40 // Size of rate in bytes -#define ISAP_rH_SZ ((ISAP_rH+7)/8) +#define ISAP_rH_SZ ((ISAP_rH + 7) / 8) // Size of zero truncated IV in bytes #define ISAP_IV_SZ 8 @@ -27,27 +29,16 @@ #define ISAP_K 128 void isap_mac( - const unsigned char *k, - const unsigned char *npub, - const unsigned char *ad, unsigned long long adlen, - const unsigned char *c, unsigned long long clen, - unsigned char *tag -); - -void isap_rk( - const unsigned char *k, - const unsigned char *iv, - const unsigned char *in, - const unsigned long long inlen, - unsigned char *out, - const unsigned long long outlen -); + const uint8_t *k, + const uint8_t *npub, + const uint8_t *ad, const uint64_t adlen, + const uint8_t *c, const uint64_t clen, + uint8_t *tag); void isap_enc( - const unsigned char *k, - const unsigned char *npub, - const unsigned char *m, unsigned long long mlen, - unsigned char *c -); + const uint8_t *k, + const uint8_t *npub, + const uint8_t *m, const uint64_t mlen, + uint8_t *c); -#endif +#endif // ISAP_H_ diff --git a/isap/Implementations/crypto_aead/isapa128av20/opt_8/api.h b/isap/Implementations/crypto_aead/isapa128av20/opt_8/api.h new file mode 100644 index 0000000..83ebf98 --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/opt_8/api.h @@ -0,0 +1,16 @@ +#ifndef API_H +#define API_H + +// isapa128a +#define CRYPTO_KEYBYTES 16 +#define CRYPTO_NSECBYTES 0 +#define CRYPTO_NPUBBYTES 16 +#define CRYPTO_ABYTES 16 +#define CRYPTO_NOOVERLAP 1 + +// asconhashv12 +#define CRYPTO_BYTES 32 +#define ASCON_HASH_OUTLEN 32 +#define ASCON_HASH_ROUNDS 12 + +#endif diff --git a/isap/Implementations/crypto_aead/isapa128av20/opt_8/asconp.h b/isap/Implementations/crypto_aead/isapa128av20/opt_8/asconp.h new file mode 100644 index 0000000..2d8517c --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/opt_8/asconp.h @@ -0,0 +1,171 @@ +#ifndef ASCONP_H +#define ASCONP_H + +#include +#include "forceinline.h" + +typedef union +{ + uint64_t x; + uint32_t w[2]; + uint8_t b[8]; +} lane_t; + +typedef union +{ + lane_t l[5]; + uint64_t x[5]; + uint32_t w[5][2]; + uint8_t b[5][8]; +} state_t; + +/* ---------------------------------------------------------------- */ + +#define P_sH PROUNDS(s, 12) +#define P_sB PROUNDS(s, 1) +#define P_sE PROUNDS(s, 6) +#define P_sK PROUNDS(s, 12) + +/* ---------------------------------------------------------------- */ + +#define U64TOWORD(x) U64BIG(x) +#define WORDTOU64(x) U64BIG(x) + +/* ---------------------------------------------------------------- */ + +#define TOBI(x) (x) +#define FROMBI(x) (x) + +/* ---------------------------------------------------------------- */ + +lane_t U64BIG(lane_t x) +{ + x.x = ((((x.x) & 0x00000000000000FFULL) << 56) | (((x.x) & 0x000000000000FF00ULL) << 40) | + (((x.x) & 0x0000000000FF0000ULL) << 24) | (((x.x) & 0x00000000FF000000ULL) << 8) | + (((x.x) & 0x000000FF00000000ULL) >> 8) | (((x.x) & 0x0000FF0000000000ULL) >> 24) | + (((x.x) & 0x00FF000000000000ULL) >> 40) | (((x.x) & 0xFF00000000000000ULL) >> 56)); + return x; +} + +/* ---------------------------------------------------------------- */ + +#define XMUL(i, x) \ + do \ + { \ + tmp = (uint16_t)a.b[i] * (1 << (x)); \ + b.b[(byte_rol + (i)) & 0x7] ^= (uint8_t)tmp; \ + b.b[(byte_rol + (i) + 1) & 0x7] ^= tmp >> 8; \ + } while (0) + +forceinline uint64_t ROR(uint64_t x, int n) +{ + lane_t a = {.x = x}, b = {.x = 0ull}; + int bit_rol = (64 - n) & 0x7; + int byte_rol = (64 - n) >> 3; + uint16_t tmp; + XMUL(0, bit_rol); + XMUL(1, bit_rol); + XMUL(2, bit_rol); + XMUL(3, bit_rol); + XMUL(4, bit_rol); + XMUL(5, bit_rol); + XMUL(6, bit_rol); + XMUL(7, bit_rol); + return b.x; +} + +/* ---------------------------------------------------------------- */ + +forceinline uint8_t NOT8(uint8_t a) { return ~a; } + +forceinline uint8_t XOR8(uint8_t a, uint8_t b) { return a ^ b; } + +forceinline uint8_t AND8(uint8_t a, uint8_t b) { return a & b; } + +forceinline uint8_t OR8(uint8_t a, uint8_t b) { return a | b; } + +/* ---------------------------------------------------------------- */ + +forceinline void LINEAR_LAYER(state_t *s, uint64_t xtemp) +{ + uint64_t temp; + temp = s->x[2] ^ ROR(s->x[2], 28 - 19); + s->x[0] = s->x[2] ^ ROR(temp, 19); + temp = s->x[4] ^ ROR(s->x[4], 6 - 1); + s->x[2] = s->x[4] ^ ROR(temp, 1); + temp = s->x[1] ^ ROR(s->x[1], 41 - 7); + s->x[4] = s->x[1] ^ ROR(temp, 7); + temp = s->x[3] ^ ROR(s->x[3], 61 - 39); + s->x[1] = s->x[3] ^ ROR(temp, 39); + temp = xtemp ^ ROR(xtemp, 17 - 10); + s->x[3] = xtemp ^ ROR(temp, 10); +} + +/* ---------------------------------------------------------------- */ + +forceinline void NONLINEAR_LAYER(state_t *s, lane_t *xtemp, uint8_t pos) +{ + uint8_t t0; + uint8_t t1; + uint8_t t2; + // Based on the round description of Ascon given in the Bachelor's thesis: + //"Optimizing Ascon on RISC-V" of Lars Jellema + // see https://github.com/Lucus16/ascon-riscv/ + t0 = XOR8(s->b[1][pos], s->b[2][pos]); + t1 = XOR8(s->b[0][pos], s->b[4][pos]); + t2 = XOR8(s->b[3][pos], s->b[4][pos]); + s->b[4][pos] = OR8(s->b[3][pos], NOT8(s->b[4][pos])); + s->b[4][pos] = XOR8(s->b[4][pos], t0); + s->b[3][pos] = XOR8(s->b[3][pos], s->b[1][pos]); + s->b[3][pos] = OR8(s->b[3][pos], t0); + s->b[3][pos] = XOR8(s->b[3][pos], t1); + s->b[2][pos] = XOR8(s->b[2][pos], t1); + s->b[2][pos] = OR8(s->b[2][pos], s->b[1][pos]); + s->b[2][pos] = XOR8(s->b[2][pos], t2); + s->b[1][pos] = AND8(s->b[1][pos], NOT8(t1)); + s->b[1][pos] = XOR8(s->b[1][pos], t2); + s->b[0][pos] = OR8(s->b[0][pos], t2); + (*xtemp).b[pos] = XOR8(s->b[0][pos], t0); +} + +/* ---------------------------------------------------------------- */ + +forceinline void ROUND(state_t *s, uint8_t C) +{ + lane_t xtemp; + /* round constant */ + s->b[2][0] = XOR8(s->b[2][0], C); + /* s-box layer */ + for (uint8_t i = 0; i < 8; i++) + NONLINEAR_LAYER(s, &xtemp, i); + /* linear layer */ + LINEAR_LAYER(s, xtemp.x); +} + +/* ---------------------------------------------------------------- */ + +void PROUNDS(state_t *s, uint8_t nr) +{ + switch (nr) + { + case 12: + ROUND(s, 0xf0); + ROUND(s, 0xe1); + ROUND(s, 0xd2); + ROUND(s, 0xc3); + ROUND(s, 0xb4); + ROUND(s, 0xa5); + case 6: + ROUND(s, 0x96); + ROUND(s, 0x87); + ROUND(s, 0x78); + ROUND(s, 0x69); + ROUND(s, 0x5a); + default: + ROUND(s, 0x4b); + } +} + +/* ---------------------------------------------------------------- */ + +#endif // ASCONP_H diff --git a/isap/Implementations/crypto_aead/isapa128av20/opt_8/config.h b/isap/Implementations/crypto_aead/isapa128av20/opt_8/config.h new file mode 100644 index 0000000..2e1c76f --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/opt_8/config.h @@ -0,0 +1,16 @@ +#ifndef CONFIG_H +#define CONFIG_H + +#define ENABLE_HASH 0 + +#include "isap.h" + +// ISAP-A-128a +const uint8_t ISAP_IV_A[] = {0x01, ISAP_K, ISAP_rH, ISAP_rB, ISAP_sH, ISAP_sB, ISAP_sE, ISAP_sK}; +const uint8_t ISAP_IV_KA[] = {0x02, ISAP_K, ISAP_rH, ISAP_rB, ISAP_sH, ISAP_sB, ISAP_sE, ISAP_sK}; +const uint8_t ISAP_IV_KE[] = {0x03, ISAP_K, ISAP_rH, ISAP_rB, ISAP_sH, ISAP_sB, ISAP_sE, ISAP_sK}; + +// Ascon-Hash +const uint8_t ASCON_HASH_IV[] = {0x00, 0x40, 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00}; + +#endif // CONFIG_H diff --git a/isap/Implementations/crypto_aead/isapa128av20/opt_8/crypto_aead.c b/isap/Implementations/crypto_aead/isapa128av20/opt_8/crypto_aead.c new file mode 100644 index 0000000..4a9bd29 --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/opt_8/crypto_aead.c @@ -0,0 +1,61 @@ +#include "api.h" +#include "isap.h" +#include "crypto_aead.h" + +int crypto_aead_encrypt( + unsigned char *c, unsigned long long *clen, + const unsigned char *m, unsigned long long mlen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k +){ + (void)nsec; + + // Ciphertext length is mlen + tag length + *clen = mlen+ISAP_TAG_SZ; + + // Encrypt plaintext + if (mlen > 0) { + isap_enc(k,npub,m,mlen,c); + } + + // Generate tag + unsigned char *tag = c+mlen; + isap_mac(k,npub,ad,adlen,c,mlen,tag); + return 0; +} + +int crypto_aead_decrypt( + unsigned char *m, unsigned long long *mlen, + unsigned char *nsec, + const unsigned char *c, unsigned long long clen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k +){ + (void)nsec; + + // Plaintext length is clen - tag length + *mlen = clen-ISAP_TAG_SZ; + + // Generate tag + unsigned char tag[ISAP_TAG_SZ]; + isap_mac(k,npub,ad,adlen,c,*mlen,tag); + + // Compare tag + unsigned long eq_cnt = 0; + for(unsigned int i = 0; i < ISAP_TAG_SZ; i++) { + eq_cnt += (tag[i] == c[(*mlen)+i]); + } + + // Perform decryption if tag is correct + if(eq_cnt == (unsigned long)ISAP_TAG_SZ){ + if (*mlen > 0) { + isap_enc(k,npub,c,*mlen,m); + } + return 0; + } else { + return -1; + } +} diff --git a/isap/Implementations/crypto_aead/isapa128av20/opt_8/forceinline.h b/isap/Implementations/crypto_aead/isapa128av20/opt_8/forceinline.h new file mode 100644 index 0000000..ba695cb --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/opt_8/forceinline.h @@ -0,0 +1,19 @@ +#ifndef FORCEINLINE_H_ +#define FORCEINLINE_H_ + +/* define forceinline macro */ +#ifdef _MSC_VER +#define forceinline __forceinline +#elif defined(__GNUC__) +#define forceinline inline __attribute__((__always_inline__)) +#elif defined(__CLANG__) +#if __has_attribute(__always_inline__) +#define forceinline inline __attribute__((__always_inline__)) +#else +#define forceinline inline +#endif +#else +#define forceinline inline +#endif + +#endif /* FORCEINLINE_H_ */ diff --git a/isap/Implementations/crypto_aead/isapa128av20/opt_8/isap.c b/isap/Implementations/crypto_aead/isapa128av20/opt_8/isap.c new file mode 100644 index 0000000..d4009e0 --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/opt_8/isap.c @@ -0,0 +1,226 @@ +#include +#include +#include "api.h" +#include "isap.h" +#include "asconp.h" +#include "config.h" + +forceinline void ABSORB_LANES(state_t *s, const uint8_t *src, uint64_t len) +{ + while (len >= 8) + { + // Absorb full lanes + lane_t t0 = U64TOWORD(*(lane_t *)(src + 0)); + s->x[0] ^= t0.x; + len -= ISAP_rH / 8; + src += ISAP_rH / 8; + P_sH; + } + + if (len > 0) + { + // Absorb partial lane and padding + size_t i; + lane_t t0 = {0}; + for (i = 0; i < len; i++) + { + t0.b[7 - i] ^= *src; + src++; + } + t0.b[7 - i] ^= 0x80; + t0 = TOBI(t0); + s->x[0] ^= t0.x; + P_sH; + } + else + { + // Absorb padded empty lane + s->b[0][7] ^= 0x80; + P_sH; + } +} + +/******************************************************************************/ +/* ISAP_RK */ +/******************************************************************************/ + +void isap_rk( + const uint8_t *k, + const uint8_t *iv, + const uint8_t *y, + state_t *out, + const size_t outlen) +{ + state_t state; + state_t *s = &state; + + // Initialize + s->l[0] = U64TOWORD(*(lane_t *)(k + 0)); + s->l[1] = U64TOWORD(*(lane_t *)(k + 8)); + s->l[2] = U64TOWORD(*(lane_t *)(iv + 0)); + s->x[3] = 0; + s->x[4] = 0; + P_sK; + + // Absorb Y, bit by bit + for (size_t i = 0; i < 16; i++) + { + uint8_t y_byte = *y; + s->b[0][7] ^= (y_byte & 0x80) << 0; + P_sB; + s->b[0][7] ^= (y_byte & 0x40) << 1; + P_sB; + s->b[0][7] ^= (y_byte & 0x20) << 2; + P_sB; + s->b[0][7] ^= (y_byte & 0x10) << 3; + P_sB; + s->b[0][7] ^= (y_byte & 0x08) << 4; + P_sB; + s->b[0][7] ^= (y_byte & 0x04) << 5; + P_sB; + s->b[0][7] ^= (y_byte & 0x02) << 6; + P_sB; + s->b[0][7] ^= (y_byte & 0x01) << 7; + if (i != 15) + { + P_sB; + y += 1; + } + } + + // Squeeze K* + P_sK; + out->x[0] = s->x[0]; + out->x[1] = s->x[1]; + if (outlen > 16) + { + out->x[2] = s->x[2]; + } +} + +/******************************************************************************/ +/* ISAP_MAC */ +/******************************************************************************/ + +void isap_mac( + const uint8_t *k, + const uint8_t *npub, + const uint8_t *ad, uint64_t adlen, + const uint8_t *c, uint64_t clen, + uint8_t *tag) +{ + state_t state; + state_t *s = &state; + + // Initialize + s->l[0] = U64TOWORD(*(lane_t *)(npub + 0)); + s->l[1] = U64TOWORD(*(lane_t *)(npub + 8)); + s->l[2] = U64TOWORD(*(lane_t *)(ISAP_IV_A + 0)); + s->x[3] = 0; + s->x[4] = 0; + P_sH; + + // Absorb associated data + ABSORB_LANES(s, ad, adlen); + + // Domain seperation + s->w[4][0] ^= 0x1UL; + + // Absorb ciphertext + ABSORB_LANES(s, c, clen); + + // Derive KA* + s->l[0] = WORDTOU64(s->l[0]); + s->l[1] = WORDTOU64(s->l[1]); + isap_rk(k, ISAP_IV_KA, (const uint8_t *)(s->b), s, CRYPTO_KEYBYTES); + + // Squeeze tag + P_sH; + lane_t t0 = WORDTOU64(s->l[0]); + memcpy(tag + 0, t0.b, 8); + t0 = WORDTOU64(s->l[1]); + memcpy(tag + 8, t0.b, 8); +} + +/******************************************************************************/ +/* ISAP_ENC */ +/******************************************************************************/ + +void isap_enc( + const uint8_t *k, + const uint8_t *npub, + const uint8_t *m, uint64_t mlen, + uint8_t *c) + +{ + state_t state; + state_t *s = &state; + + // Init state + isap_rk(k, ISAP_IV_KE, npub, s, ISAP_STATE_SZ - CRYPTO_NPUBBYTES); + s->l[3] = U64TOWORD(*(lane_t *)(npub + 0)); + s->l[4] = U64TOWORD(*(lane_t *)(npub + 8)); + + while (mlen >= ISAP_rH / 8) + { + // Encrypt full lanes + P_sE; + lane_t t0 = WORDTOU64(s->l[0]); + *(uint64_t *)c = *(uint64_t *)m ^ t0.x; + mlen -= ISAP_rH / 8; + m += ISAP_rH / 8; + c += ISAP_rH / 8; + } + + if (mlen > 0) + { + // Encrypt partial lanes + P_sE; + lane_t t0 = WORDTOU64(s->l[0]); + for (uint8_t i = 0; i < mlen; i++) + { + *c = *m ^ t0.b[i]; + m += 1; + c += 1; + } + } +} + +/******************************************************************************/ +/* Ascon-Hash */ +/******************************************************************************/ + +#if ENABLE_HASH == 1 + +int crypto_hash(uint8_t *out, const uint8_t *in, unsigned long long inlen) +{ + + state_t state; + state_t *s = &state; + + // Initialize + s->l[0] = U64TOWORD(*(lane_t *)(ASCON_HASH_IV + 0)); + s->x[1] = 0; + s->x[2] = 0; + s->x[3] = 0; + s->x[4] = 0; + P_sH; + + // Absorb input + ABSORB_LANES(s, in, inlen); + + for (size_t i = 0; i < 4; i++) + { + // Squeeze full lanes + lane_t t0 = WORDTOU64(s->l[0]); + *(uint64_t *)(out + 8 * i) = t0.x; + if (i < 3) + { + P_sH; + } + } + + return 0; +} + +#endif diff --git a/isap/Implementations/crypto_aead/isapa128av20/opt_8/isap.h b/isap/Implementations/crypto_aead/isapa128av20/opt_8/isap.h new file mode 100644 index 0000000..abec1ca --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/opt_8/isap.h @@ -0,0 +1,44 @@ +#ifndef ISAP_H +#define ISAP_H + +#include + +// Rate in bits +#define ISAP_rH 64 +#define ISAP_rB 1 + +// Number of rounds +#define ISAP_sH 12 +#define ISAP_sB 1 +#define ISAP_sE 6 +#define ISAP_sK 12 + +// State size in bytes +#define ISAP_STATE_SZ 40 + +// Size of rate in bytes +#define ISAP_rH_SZ ((ISAP_rH + 7) / 8) + +// Size of zero truncated IV in bytes +#define ISAP_IV_SZ 8 + +// Size of tag in bytes +#define ISAP_TAG_SZ 16 + +// Security level +#define ISAP_K 128 + +void isap_mac( + const uint8_t *k, + const uint8_t *npub, + const uint8_t *ad, const uint64_t adlen, + const uint8_t *c, const uint64_t clen, + uint8_t *tag); + +void isap_enc( + const uint8_t *k, + const uint8_t *npub, + const uint8_t *m, const uint64_t mlen, + uint8_t *c); + +#endif diff --git a/isap/Implementations/crypto_aead/isapa128av20/opt_8_tiny/api.h b/isap/Implementations/crypto_aead/isapa128av20/opt_8_tiny/api.h new file mode 120000 index 0000000..3d553ba --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/opt_8_tiny/api.h @@ -0,0 +1 @@ +../opt_8/api.h \ No newline at end of file diff --git a/isap/Implementations/crypto_aead/isapa128av20/opt_8_tiny/asconp.h b/isap/Implementations/crypto_aead/isapa128av20/opt_8_tiny/asconp.h new file mode 100644 index 0000000..4c6f9a6 --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/opt_8_tiny/asconp.h @@ -0,0 +1,164 @@ +#ifndef ASCONP_H +#define ASCONP_H + +#include +#include "forceinline.h" + +typedef union +{ + uint64_t x; + uint32_t w[2]; + uint8_t b[8]; +} lane_t; + +typedef union +{ + lane_t l[5]; + uint64_t x[5]; + uint32_t w[5][2]; + uint8_t b[5][8]; +} state_t; + +/* ---------------------------------------------------------------- */ + +#define P_sH PROUNDS(s, 12) +#define P_sB PROUNDS(s, 1) +#define P_sE PROUNDS(s, 6) +#define P_sK PROUNDS(s, 12) + +/* ---------------------------------------------------------------- */ + +#define U64TOWORD(x) U64BIG(x) +#define WORDTOU64(x) U64BIG(x) + +/* ---------------------------------------------------------------- */ + +#define TOBI(x) (x) +#define FROMBI(x) (x) + +/* ---------------------------------------------------------------- */ + +lane_t U64BIG(lane_t x) +{ + x.x = ((((x.x) & 0x00000000000000FFULL) << 56) | (((x.x) & 0x000000000000FF00ULL) << 40) | + (((x.x) & 0x0000000000FF0000ULL) << 24) | (((x.x) & 0x00000000FF000000ULL) << 8) | + (((x.x) & 0x000000FF00000000ULL) >> 8) | (((x.x) & 0x0000FF0000000000ULL) >> 24) | + (((x.x) & 0x00FF000000000000ULL) >> 40) | (((x.x) & 0xFF00000000000000ULL) >> 56)); + return x; +} + +/* ---------------------------------------------------------------- */ + +#define XMUL(i, x) \ + do \ + { \ + tmp = (uint16_t)a.b[i] * (1 << (x)); \ + b.b[(byte_rol + (i)) & 0x7] ^= (uint8_t)tmp; \ + b.b[(byte_rol + (i) + 1) & 0x7] ^= tmp >> 8; \ + } while (0) + +uint64_t ROR(uint64_t x, int n) +{ + lane_t a = {.x = x}, b = {.x = 0ull}; + int bit_rol = (64 - n) & 0x7; + int byte_rol = (64 - n) >> 3; + uint16_t tmp; + XMUL(0, bit_rol); + XMUL(1, bit_rol); + XMUL(2, bit_rol); + XMUL(3, bit_rol); + XMUL(4, bit_rol); + XMUL(5, bit_rol); + XMUL(6, bit_rol); + XMUL(7, bit_rol); + return b.x; +} + +/* ---------------------------------------------------------------- */ + +forceinline uint8_t NOT8(uint8_t a) { return ~a; } + +forceinline uint8_t XOR8(uint8_t a, uint8_t b) { return a ^ b; } + +forceinline uint8_t AND8(uint8_t a, uint8_t b) { return a & b; } + +forceinline uint8_t OR8(uint8_t a, uint8_t b) { return a | b; } + +/* ---------------------------------------------------------------- */ + +forceinline void LINEAR_LAYER(state_t *s, uint64_t xtemp) +{ + uint64_t temp; + temp = s->x[2] ^ ROR(s->x[2], 28 - 19); + s->x[0] = s->x[2] ^ ROR(temp, 19); + temp = s->x[4] ^ ROR(s->x[4], 6 - 1); + s->x[2] = s->x[4] ^ ROR(temp, 1); + temp = s->x[1] ^ ROR(s->x[1], 41 - 7); + s->x[4] = s->x[1] ^ ROR(temp, 7); + temp = s->x[3] ^ ROR(s->x[3], 61 - 39); + s->x[1] = s->x[3] ^ ROR(temp, 39); + temp = xtemp ^ ROR(xtemp, 17 - 10); + s->x[3] = xtemp ^ ROR(temp, 10); +} + +/* ---------------------------------------------------------------- */ + +forceinline void NONLINEAR_LAYER(state_t *s, lane_t *xtemp, uint8_t pos) +{ + uint8_t t0; + uint8_t t1; + uint8_t t2; + // Based on the round description of Ascon given in the Bachelor's thesis: + //"Optimizing Ascon on RISC-V" of Lars Jellema + // see https://github.com/Lucus16/ascon-riscv/ + t0 = XOR8(s->b[1][pos], s->b[2][pos]); + t1 = XOR8(s->b[0][pos], s->b[4][pos]); + t2 = XOR8(s->b[3][pos], s->b[4][pos]); + s->b[4][pos] = OR8(s->b[3][pos], NOT8(s->b[4][pos])); + s->b[4][pos] = XOR8(s->b[4][pos], t0); + s->b[3][pos] = XOR8(s->b[3][pos], s->b[1][pos]); + s->b[3][pos] = OR8(s->b[3][pos], t0); + s->b[3][pos] = XOR8(s->b[3][pos], t1); + s->b[2][pos] = XOR8(s->b[2][pos], t1); + s->b[2][pos] = OR8(s->b[2][pos], s->b[1][pos]); + s->b[2][pos] = XOR8(s->b[2][pos], t2); + s->b[1][pos] = AND8(s->b[1][pos], NOT8(t1)); + s->b[1][pos] = XOR8(s->b[1][pos], t2); + s->b[0][pos] = OR8(s->b[0][pos], t2); + (*xtemp).b[pos] = XOR8(s->b[0][pos], t0); +} + +/* ---------------------------------------------------------------- */ + +forceinline void ROUND(state_t *s, uint8_t C) +{ + lane_t xtemp; + /* round constant */ + s->b[2][0] = XOR8(s->b[2][0], C); + /* s-box layer */ + for (uint8_t i = 0; i < 8; i++) + NONLINEAR_LAYER(s, &xtemp, i); + /* linear layer */ + LINEAR_LAYER(s, xtemp.x); +} + +/* ---------------------------------------------------------------- */ + +#define RC(i) (i) +#define START(n) ((3 + (n)) << 4 | (12 - (n))) +#define INC -0x0f +#define END 0x3c + +void PROUNDS(state_t *s, uint8_t nr) +{ + int i = START(nr); + do + { + ROUND(s, RC(i)); + i += INC; + } while (i != END); +} + +/* ---------------------------------------------------------------- */ + +#endif // ASCONP_H diff --git a/isap/Implementations/crypto_aead/isapa128av20/opt_8_tiny/config.h b/isap/Implementations/crypto_aead/isapa128av20/opt_8_tiny/config.h new file mode 100644 index 0000000..2e1c76f --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/opt_8_tiny/config.h @@ -0,0 +1,16 @@ +#ifndef CONFIG_H +#define CONFIG_H + +#define ENABLE_HASH 0 + +#include "isap.h" + +// ISAP-A-128a +const uint8_t ISAP_IV_A[] = {0x01, ISAP_K, ISAP_rH, ISAP_rB, ISAP_sH, ISAP_sB, ISAP_sE, ISAP_sK}; +const uint8_t ISAP_IV_KA[] = {0x02, ISAP_K, ISAP_rH, ISAP_rB, ISAP_sH, ISAP_sB, ISAP_sE, ISAP_sK}; +const uint8_t ISAP_IV_KE[] = {0x03, ISAP_K, ISAP_rH, ISAP_rB, ISAP_sH, ISAP_sB, ISAP_sE, ISAP_sK}; + +// Ascon-Hash +const uint8_t ASCON_HASH_IV[] = {0x00, 0x40, 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00}; + +#endif // CONFIG_H diff --git a/isap/Implementations/crypto_aead/isapa128av20/opt_8_tiny/crypto_aead.c b/isap/Implementations/crypto_aead/isapa128av20/opt_8_tiny/crypto_aead.c new file mode 120000 index 0000000..c2ca0b7 --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/opt_8_tiny/crypto_aead.c @@ -0,0 +1 @@ +../opt_8/crypto_aead.c \ No newline at end of file diff --git a/isap/Implementations/crypto_aead/isapa128av20/opt_8_tiny/forceinline.h b/isap/Implementations/crypto_aead/isapa128av20/opt_8_tiny/forceinline.h new file mode 120000 index 0000000..14e90e7 --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/opt_8_tiny/forceinline.h @@ -0,0 +1 @@ +../opt_8/forceinline.h \ No newline at end of file diff --git a/isap/Implementations/crypto_aead/isapa128av20/opt_8_tiny/isap.c b/isap/Implementations/crypto_aead/isapa128av20/opt_8_tiny/isap.c new file mode 100644 index 0000000..18bcc4a --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/opt_8_tiny/isap.c @@ -0,0 +1,226 @@ +#include +#include +#include "api.h" +#include "isap.h" +#include "asconp.h" +#include "config.h" + +void ABSORB_LANES(state_t *s, const uint8_t *src, uint64_t len) +{ + while (len >= 8) + { + // Absorb full lanes + lane_t t0 = U64TOWORD(*(lane_t *)(src + 0)); + s->x[0] ^= t0.x; + len -= ISAP_rH / 8; + src += ISAP_rH / 8; + P_sH; + } + + if (len > 0) + { + // Absorb partial lane and padding + size_t i; + lane_t t0 = {0}; + for (i = 0; i < len; i++) + { + t0.b[7 - i] ^= *src; + src++; + } + t0.b[7 - i] ^= 0x80; + t0 = TOBI(t0); + s->x[0] ^= t0.x; + P_sH; + } + else + { + // Absorb padded empty lane + s->b[0][7] ^= 0x80; + P_sH; + } +} + +/******************************************************************************/ +/* ISAP_RK */ +/******************************************************************************/ + +void isap_rk( + const uint8_t *k, + const uint8_t *iv, + const uint8_t *y, + state_t *out, + const size_t outlen) +{ + state_t state; + state_t *s = &state; + + // Initialize + s->l[0] = U64TOWORD(*(lane_t *)(k + 0)); + s->l[1] = U64TOWORD(*(lane_t *)(k + 8)); + s->l[2] = U64TOWORD(*(lane_t *)(iv + 0)); + s->x[3] = 0; + s->x[4] = 0; + P_sK; + + // Absorb Y, bit by bit + for (size_t i = 0; i < 16; i++) + { + uint8_t y_byte = *y; + s->b[0][7] ^= (y_byte & 0x80) << 0; + P_sB; + s->b[0][7] ^= (y_byte & 0x40) << 1; + P_sB; + s->b[0][7] ^= (y_byte & 0x20) << 2; + P_sB; + s->b[0][7] ^= (y_byte & 0x10) << 3; + P_sB; + s->b[0][7] ^= (y_byte & 0x08) << 4; + P_sB; + s->b[0][7] ^= (y_byte & 0x04) << 5; + P_sB; + s->b[0][7] ^= (y_byte & 0x02) << 6; + P_sB; + s->b[0][7] ^= (y_byte & 0x01) << 7; + if (i != 15) + { + P_sB; + y += 1; + } + } + + // Squeeze K* + P_sK; + out->x[0] = s->x[0]; + out->x[1] = s->x[1]; + if (outlen > 16) + { + out->x[2] = s->x[2]; + } +} + +/******************************************************************************/ +/* ISAP_MAC */ +/******************************************************************************/ + +void isap_mac( + const uint8_t *k, + const uint8_t *npub, + const uint8_t *ad, uint64_t adlen, + const uint8_t *c, uint64_t clen, + uint8_t *tag) +{ + state_t state; + state_t *s = &state; + + // Initialize + s->l[0] = U64TOWORD(*(lane_t *)(npub + 0)); + s->l[1] = U64TOWORD(*(lane_t *)(npub + 8)); + s->l[2] = U64TOWORD(*(lane_t *)(ISAP_IV_A + 0)); + s->x[3] = 0; + s->x[4] = 0; + P_sH; + + // Absorb associated data + ABSORB_LANES(s, ad, adlen); + + // Domain seperation + s->w[4][0] ^= 0x1UL; + + // Absorb ciphertext + ABSORB_LANES(s, c, clen); + + // Derive KA* + s->l[0] = WORDTOU64(s->l[0]); + s->l[1] = WORDTOU64(s->l[1]); + isap_rk(k, ISAP_IV_KA, (const uint8_t *)(s->b), s, CRYPTO_KEYBYTES); + + // Squeeze tag + P_sH; + lane_t t0 = WORDTOU64(s->l[0]); + memcpy(tag + 0, t0.b, 8); + t0 = WORDTOU64(s->l[1]); + memcpy(tag + 8, t0.b, 8); +} + +/******************************************************************************/ +/* ISAP_ENC */ +/******************************************************************************/ + +void isap_enc( + const uint8_t *k, + const uint8_t *npub, + const uint8_t *m, uint64_t mlen, + uint8_t *c) + +{ + state_t state; + state_t *s = &state; + + // Init state + isap_rk(k, ISAP_IV_KE, npub, s, ISAP_STATE_SZ - CRYPTO_NPUBBYTES); + s->l[3] = U64TOWORD(*(lane_t *)(npub + 0)); + s->l[4] = U64TOWORD(*(lane_t *)(npub + 8)); + + while (mlen >= ISAP_rH / 8) + { + // Encrypt full lanes + P_sE; + lane_t t0 = WORDTOU64(s->l[0]); + *(uint64_t *)c = *(uint64_t *)m ^ t0.x; + mlen -= ISAP_rH / 8; + m += ISAP_rH / 8; + c += ISAP_rH / 8; + } + + if (mlen > 0) + { + // Encrypt partial lanes + P_sE; + lane_t t0 = WORDTOU64(s->l[0]); + for (uint8_t i = 0; i < mlen; i++) + { + *c = *m ^ t0.b[i]; + m += 1; + c += 1; + } + } +} + +/******************************************************************************/ +/* Ascon-Hash */ +/******************************************************************************/ + +#if ENABLE_HASH == 1 + +int crypto_hash(uint8_t *out, const uint8_t *in, unsigned long long inlen) +{ + + state_t state; + state_t *s = &state; + + // Initialize + s->l[0] = U64TOWORD(*(lane_t *)(ASCON_HASH_IV + 0)); + s->x[1] = 0; + s->x[2] = 0; + s->x[3] = 0; + s->x[4] = 0; + P_sH; + + // Absorb input + ABSORB_LANES(s, in, inlen); + + for (size_t i = 0; i < 4; i++) + { + // Squeeze full lanes + lane_t t0 = WORDTOU64(s->l[0]); + *(uint64_t *)(out + 8 * i) = t0.x; + if (i < 3) + { + P_sH; + } + } + + return 0; +} + +#endif diff --git a/isap/Implementations/crypto_aead/isapa128av20/opt_8_tiny/isap.h b/isap/Implementations/crypto_aead/isapa128av20/opt_8_tiny/isap.h new file mode 120000 index 0000000..0122ac7 --- /dev/null +++ b/isap/Implementations/crypto_aead/isapa128av20/opt_8_tiny/isap.h @@ -0,0 +1 @@ +../opt_8/isap.h \ No newline at end of file diff --git a/isap/Implementations/crypto_aead/isapxv20/ref/.gitignore b/isap/Implementations/crypto_aead/isapxv20/ref/.gitignore new file mode 100644 index 0000000..153b550 --- /dev/null +++ b/isap/Implementations/crypto_aead/isapxv20/ref/.gitignore @@ -0,0 +1,2 @@ +build/ +LWC_AEAD_KAT_128_128.txt -- libgit2 0.26.0