├── .github └── workflows │ └── main.yml ├── .gitignore ├── CHANGELOG.md ├── LICENSE.md ├── Makefile ├── README.md ├── build.config ├── c_deps └── ed448goldilocks │ ├── .gitignore │ ├── CMakeLists.txt │ ├── Doxyfile.in │ ├── HISTORY.txt │ ├── LICENSE.txt │ ├── README.md │ ├── TODO.txt │ ├── cmake │ └── DecafConfig.cmake.in │ ├── python │ ├── .gitignore │ ├── edgold │ │ └── ed448.py │ └── setup.py │ ├── src │ ├── CMakeLists.txt │ ├── curve25519 │ │ ├── CMakeLists.txt │ │ └── decaf_tables.c │ ├── ed448goldilocks │ │ ├── CMakeLists.txt │ │ └── decaf_tables.c │ ├── generator │ │ ├── CMakeLists.txt │ │ ├── curve25519 │ │ │ └── CMakeLists.txt │ │ ├── curve_data.py │ │ ├── ed448goldilocks │ │ │ └── CMakeLists.txt │ │ └── template.py │ ├── include │ │ ├── arch_32 │ │ │ └── arch_intrinsics.h │ │ ├── arch_arm_32 │ │ │ └── arch_intrinsics.h │ │ ├── arch_neon │ │ │ └── arch_intrinsics.h │ │ ├── arch_ref64 │ │ │ └── arch_intrinsics.h │ │ ├── arch_x86_64 │ │ │ └── arch_intrinsics.h │ │ ├── constant_time.h │ │ ├── decaf │ │ │ └── crypto.tmpl.hxx │ │ ├── field.h │ │ ├── keccak_internal.h │ │ ├── portable_endian.h │ │ └── word.h │ ├── p25519 │ │ ├── CMakeLists.txt │ │ ├── arch_32 │ │ │ ├── f_impl.c │ │ │ └── f_impl.h │ │ ├── arch_ref64 │ │ │ ├── f_impl.c │ │ │ └── f_impl.h │ │ ├── arch_x86_64 │ │ │ ├── f_impl.c │ │ │ └── f_impl.h │ │ └── f_arithmetic.c │ ├── p448 │ │ ├── CMakeLists.txt │ │ ├── arch_32 │ │ │ ├── f_impl.c │ │ │ └── f_impl.h │ │ ├── arch_arm_32 │ │ │ ├── f_impl.c │ │ │ └── f_impl.h │ │ ├── arch_neon │ │ │ ├── f_impl.c │ │ │ └── f_impl.h │ │ ├── arch_ref64 │ │ │ ├── f_impl.c │ │ │ └── f_impl.h │ │ ├── arch_x86_64 │ │ │ ├── f_impl.c │ │ │ └── f_impl.h │ │ └── f_arithmetic.c │ ├── per_curve │ │ ├── decaf.tmpl.c │ │ ├── decaf_gen_tables.tmpl.c │ │ ├── eddsa.tmpl.c │ │ ├── eddsa.tmpl.h │ │ ├── eddsa.tmpl.hxx │ │ ├── elligator.tmpl.c │ │ ├── point.tmpl.h │ │ ├── point.tmpl.hxx │ │ └── scalar.tmpl.c │ ├── per_field │ │ ├── f_field.tmpl.h │ │ └── f_generic.tmpl.c │ ├── public_include │ │ ├── decaf.tmpl.h │ │ ├── decaf.tmpl.hxx │ │ └── decaf │ │ │ ├── common.h │ │ │ ├── eddsa.tmpl.hxx │ │ │ ├── secure_buffer.hxx │ │ │ ├── sha512.h │ │ │ ├── sha512.hxx │ │ │ ├── shake.h │ │ │ ├── shake.hxx │ │ │ ├── spongerng.h │ │ │ └── spongerng.hxx │ ├── sha512.c │ ├── shake.c │ ├── spongerng.c │ └── utils.c │ └── test │ ├── CMakeLists.txt │ ├── batarch.map │ ├── bench_decaf.cxx │ ├── ristretto.cxx │ ├── ristretto_vectors.inc.cxx │ ├── shakesum.c │ ├── test_ct.cxx │ ├── test_decaf.cxx │ ├── test_decaf.sage │ ├── test_templates.cxx │ └── vectors.inc.cxx ├── c_src ├── .clang-format ├── Makefile └── nif │ ├── csprng.c │ ├── csprng.h │ ├── ed25519.c │ ├── ed25519.h │ ├── ed448.c │ ├── ed448.h │ ├── hash.c │ ├── hash.h │ ├── impl │ ├── ed255.c.h │ ├── ed448.c.h │ ├── point_255.c.h │ └── point_448.c.h │ ├── libdecaf_nif.c │ ├── libdecaf_nif.h │ ├── xnif_trace.h │ ├── xof.c │ └── xof.h ├── erlang.mk ├── priv └── .keep ├── rebar.config ├── rebar.lock ├── src ├── libdecaf.app.src ├── libdecaf.erl ├── libdecaf_curve25519.erl ├── libdecaf_curve448.erl ├── libdecaf_keccak_sha3.erl ├── libdecaf_nif.erl ├── libdecaf_sha2.erl ├── libdecaf_sha3.erl └── libdecaf_spongerng.erl └── test ├── Dockerfile ├── cfrg_SUITE.erl ├── fetch.erl ├── fips180_4_SUITE.erl ├── fips180_4_SUITE_data └── .keep ├── fips202_SUITE.erl ├── fips202_SUITE_data └── .keep ├── fips_testvector.erl ├── hex.erl ├── legacy_keccak_SUITE.erl ├── legacy_keccak_SUITE_data └── .keep ├── libdecaf_ct.erl ├── spongerng_SUITE.erl ├── spongerng_SUITE_data └── seed.txt └── timeslice_SUITE.erl /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | test: 7 | name: Test 8 | runs-on: ubuntu-latest 9 | 10 | strategy: 11 | fail-fast: false 12 | matrix: 13 | include: 14 | - erlang: 25.0.4-alpine-3.16.1 15 | # - erlang: 24.3.4.4-alpine-3.16.1 # appears to have a broken 'ssl' library 16 | - erlang: 23.3.4.16-alpine-3.16.0 17 | 18 | steps: 19 | - uses: actions/checkout@v2 20 | 21 | - name: Setup 22 | run: | 23 | make docker-setup DOCKER_OTP_VERSION=${{matrix.erlang}} 24 | 25 | - name: Test 26 | run: | 27 | make docker-test DOCKER_OTP_VERSION=${{matrix.erlang}} 28 | 29 | - name: Logs 30 | uses: actions/upload-artifact@v2-preview 31 | if: failure() 32 | with: 33 | name: ct-logs-${{matrix.erlang}} 34 | path: logs/* 35 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # The directory Mix will write compiled artifacts to. 2 | /_build/ 3 | 4 | # The directory make downloads the C dependencies sources to. 5 | /c_deps/ed448goldilocks-build/ 6 | !/c_deps/ed448goldilocks/ 7 | 8 | # If you run "mix test --cover", coverage assets end up here. 9 | /cover/ 10 | 11 | # The directory Mix downloads your dependencies sources to. 12 | /deps/ 13 | 14 | # Where 3rd-party dependencies like ExDoc output generated docs. 15 | /doc/ 16 | 17 | # Ignore .fetch files in case you like to edit your project deps locally. 18 | /.fetch 19 | 20 | # If the VM crashes, it generates a dump, let's ignore it too. 21 | erl_crash.dump 22 | 23 | # Also ignore archive artifacts (built via "mix archive.build"). 24 | *.ez 25 | 26 | # Ignore package tarball (built via "mix hex.build"). 27 | libdecaf-*.tar 28 | 29 | # Build artifact exclusions. 30 | /c_src/env.mk 31 | /c_src/Makefile.auto.win 32 | /c_src/*.obj 33 | /priv/*.dll 34 | /priv/*.lib 35 | /priv/*.exp 36 | /priv/*.dylib 37 | /priv/*.so 38 | 39 | # erlang.mk exclusions. 40 | .erlang.mk.packages.* 41 | ct.coverdata 42 | _rel 43 | _deps 44 | _plugins 45 | _tdeps 46 | /.erlang.mk 47 | /libdecaf.d 48 | 49 | # Rebar3 exclusions. 50 | .rebar3 51 | _* 52 | .eunit 53 | *.o 54 | *.beam 55 | *.plt 56 | *.swp 57 | *.swo 58 | .erlang.cookie 59 | ebin 60 | log 61 | erl_crash.dump 62 | .rebar 63 | logs 64 | _build 65 | .idea 66 | *.iml 67 | rebar3.crashdump 68 | /rebar3 69 | 70 | # Other test artifacts. 71 | /test/fips180_4_SUITE_data/shabytetestvectors 72 | /test/fips202_SUITE_data/keccaktestvectors 73 | /test/legacy_keccak_SUITE_data/keccaktestvectors 74 | /test/legacy_keccak_SUITE_data/temp 75 | /tmp 76 | 77 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## 2.1.1 (2022-08-31) 4 | 5 | * Fixes 6 | * Include `Makefile` in hex.pm package so it works correctly with erlang.mk 7 | 8 | ## 2.1.0 (2022-08-28) 9 | 10 | * Fixes 11 | * Security fix for [Misuse of public apis can result in private key exposure #13](https://github.com/potatosalad/erlang-libdecaf/issues/13) (see [report here](https://github.com/MystenLabs/ed25519-unsafe-libs)). 12 | * Library Support 13 | * Legacy KECCAK SHA-3 (thanks to [@ukazap](https://github.com/ukazap)) 14 | * `libdecaf_keccak_sha3:hash/2`, `libdecaf_keccak_sha3:hash/3` 15 | * `libdecaf_keccak_sha3:init/1` 16 | * `libdecaf_keccak_sha3:update/2` 17 | * `libdecaf_keccak_sha3:final/1`, `libdecaf_keccak_sha3:final/2` 18 | * Enhancements 19 | * New Keypair API for Ed25519 and Ed448 operations (see [#13](https://github.com/potatosalad/erlang-libdecaf/issues/13)). 20 | * [Add legacy Keccak support #15](https://github.com/potatosalad/erlang-libdecaf/pull/15) (see also [#12](https://github.com/potatosalad/erlang-libdecaf/issues/12).) 21 | * Upstream update to [`ed448goldilocks` version `features-20220828`](https://github.com/potatosalad/ed448goldilocks/tree/features-20220828) (vendored as part of `libdecaf` app). 22 | 23 | ## 2.0.0 (2022-01-25) 24 | 25 | * Fixes 26 | * Remove `xnif_slice` related code and refactor to use regular timeslice reduction bumping (see [#7](https://github.com/potatosalad/erlang-libdecaf/issues/7)). 27 | * Compilation problems on macOS and Erlang/OTP 23+ compatibility. 28 | * Enhancements 29 | * Upstream update to [`ed448goldilocks` version `features-20220121`](https://github.com/potatosalad/ed448goldilocks/tree/features-20220121) (now vendored as part of `libdecaf` app). 30 | * Added tests for timeslice checking with large input and/or large output. 31 | * Switch from Travis CI to GitHub Actions. 32 | * Relicense library under MIT license. 33 | 34 | ## 1.0.0 (2018-11-30) 35 | 36 | * Upstream update to [`ed448goldilocks` version 1.0](https://sourceforge.net/p/ed448goldilocks/code/ci/v1.0/tree/) 37 | * Library Support 38 | * SPONGERNG 39 | * `libdecaf_spongerng:init_from_buffer/2` 40 | * `libdecaf_spongerng:init_from_file/3` 41 | * `libdecaf_spongerng:init_from_dev_urandom/0` 42 | * `libdecaf_spongerng:next/2` 43 | * `libdecaf_spongerng:stir/2` 44 | * Verious improvements to the build system (more appropriate usage of dirty schedulers and time slices). 45 | * Added Ed25519 to X25519 and Ed448 to X448 conversion functions. 46 | 47 | ## 0.0.4 (2016-09-02) 48 | 49 | * Upstream version [features-20160902](https://github.com/potatosalad/ed448goldilocks/tree/features-20160902) which adds support for Ed25519ctx according to [draft 08 of EdDSA](https://tools.ietf.org/html/draft-irtf-cfrg-eddsa-08#section-5.1). 50 | 51 | * Library Support 52 | * EdDSA 53 | * `libdecaf_curve25519:ed25519ctx_sign/3` 54 | * `libdecaf_curve25519:ed25519ctx_verify/4` 55 | 56 | ## 0.0.3 (2016-03-10) 57 | 58 | * Upstream version [features-20160629](https://github.com/potatosalad/ed448goldilocks/tree/features-20160629) 59 | 60 | * Fixes 61 | * Support for modern versions of FreeBSD, NetBSD, and DragonflyBSD. 62 | 63 | ## 0.0.2 (2016-03-10) 64 | 65 | * Upstream version [f29b338f3788f052441478bb03b5d9e6fdd3eb28](https://github.com/potatosalad/ed448goldilocks/tree/f29b338f3788f052441478bb03b5d9e6fdd3eb28) 66 | 67 | * Library Support 68 | * ECDH 69 | * `libdecaf:x25519_generate_key/1` 70 | * `libdecaf:x25519/2` 71 | * `libdecaf:x448_generate_key/1` 72 | * `libdecaf:x448/2` 73 | * EdDSA 74 | * `libdecaf:ed25519_derive_public_key/1` 75 | * `libdecaf:ed25519_sign/4` 76 | * `libdecaf:ed25519_sign_prehash/3` 77 | * `libdecaf:ed25519_verify/4` 78 | * `libdecaf:ed25519_verify_prehash/3` 79 | * `libdecaf:ed448_derive_public_key/1` 80 | * `libdecaf:ed448_sign/5` 81 | * `libdecaf:ed448_sign_prehash/4` 82 | * `libdecaf:ed448_verify/5` 83 | * `libdecaf:ed448_verify_prehash/4` 84 | 85 | * Fixes 86 | * Include `stdint.h` to hopefully fix build issues on Linux. 87 | 88 | ## 0.0.1 (2016-03-01) 89 | 90 | * Initial Release 91 | 92 | * Publish to [hex.pm](https://hex.pm/packages/libdecaf). 93 | 94 | * Library Support 95 | * ECDH 96 | * `libdecaf:decaf_x25519_base_scalarmul/1` 97 | * `libdecaf:decaf_x25519_direct_scalarmul/2` 98 | * `libdecaf:decaf_x448_base_scalarmul/1` 99 | * `libdecaf:decaf_x448_direct_scalarmul/2` 100 | * EdDSA 101 | * `libdecaf:decaf_255_eddsa_derive_public_key/1` 102 | * `libdecaf:decaf_255_eddsa_sign/4` 103 | * `libdecaf:decaf_255_eddsa_verify/4` 104 | * `libdecaf:decaf_448_eddsa_derive_public_key/1` 105 | * `libdecaf:decaf_448_eddsa_sign/5` 106 | * `libdecaf:decaf_448_eddsa_verify/5` 107 | * SHA-2 108 | * `libdecaf:sha2_512/2` 109 | * Streaming support 110 | * `libdecaf:sha2_512_init/0`, `libdecaf:sha2_512_update/2`, `libdecaf:sha2_512_final/2` 111 | * SHA-3 112 | * `libdecaf:sha3_224/1` 113 | * `libdecaf:sha3_256/1` 114 | * `libdecaf:sha3_384/1` 115 | * `libdecaf:sha3_512/1` 116 | * `libdecaf:shake128/2` 117 | * `libdecaf:shake256/2` 118 | * Streaming support 119 | * `libdecaf:sha3_224_init/0`, `libdecaf:sha3_224_update/2`, `libdecaf:sha3_224_final/1` 120 | * `libdecaf:sha3_256_init/0`, `libdecaf:sha3_256_update/2`, `libdecaf:sha3_256_final/1` 121 | * `libdecaf:sha3_384_init/0`, `libdecaf:sha3_384_update/2`, `libdecaf:sha3_384_final/1` 122 | * `libdecaf:sha3_512_init/0`, `libdecaf:sha3_512_update/2`, `libdecaf:sha3_512_final/1` 123 | * `libdecaf:shake128_init/0`, `libdecaf:shake128_update/2`, `libdecaf:shake128_final/2` 124 | * `libdecaf:shake256_init/0`, `libdecaf:shake256_update/2`, `libdecaf:shake256_final/2` 125 | 126 | * Basic Tests based on the [draft-irtf-cfrg-eddsa](https://tools.ietf.org/html/draft-irtf-cfrg-eddsa), [FIPS 180-4](http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf), [FIPS 202](http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf), and [RFC 7748](https://tools.ietf.org/html/rfc7748) test vectors. 127 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | ===================== 3 | 4 | Copyright (c) 2014-2022, Andrew Bennett 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 10 | of the Software, and to permit persons to whom the Software is furnished to do 11 | so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | PROJECT = libdecaf 2 | PROJECT_DESCRIPTION = libdecaf NIF for ECDH (X25519, X448), EdDSA (Ed25519, Ed25519ctx, Ed25519ph, Ed448, Ed448ph), curve25519, curve448, spongerng 3 | PROJECT_VERSION = 2.1.1 4 | 5 | include erlang.mk 6 | 7 | .PHONY: docker-build docker-load docker-setup docker-save docker-shell docker-test 8 | 9 | DOCKER_OTP_VERSION ?= 25.0.4-alpine-3.16.1 10 | 11 | docker-build:: 12 | $(gen_verbose) docker build \ 13 | --tag ${PROJECT}-${DOCKER_OTP_VERSION} \ 14 | --file test/Dockerfile \ 15 | --build-arg OTP_VERSION=${DOCKER_OTP_VERSION} \ 16 | test 17 | 18 | docker-load:: 19 | $(gen_verbose) docker load \ 20 | -i "${PROJECT}-${DOCKER_OTP_VERSION}/image.tar" 21 | 22 | docker-save:: 23 | $(verbose) mkdir -p "${PROJECT}-${DOCKER_OTP_VERSION}" 24 | $(gen_verbose) docker save \ 25 | -o "${PROJECT}-${DOCKER_OTP_VERSION}/image.tar" \ 26 | ${PROJECT}-${DOCKER_OTP_VERSION} 27 | 28 | docker-setup:: 29 | $(verbose) if [ -f "${PROJECT}-${DOCKER_OTP_VERSION}/image.tar" ]; then \ 30 | $(MAKE) docker-load; \ 31 | else \ 32 | $(MAKE) docker-build; \ 33 | $(MAKE) docker-save; \ 34 | fi 35 | 36 | docker-shell:: 37 | $(verbose) docker run \ 38 | -v "$(shell pwd)":"/build/${PROJECT}" --rm -it "${PROJECT}-${DOCKER_OTP_VERSION}" \ 39 | /bin/bash -l 40 | 41 | docker-test:: 42 | $(gen_verbose) docker run \ 43 | -v "$(shell pwd)":"/build/${PROJECT}" "${PROJECT}-${DOCKER_OTP_VERSION}" \ 44 | /bin/bash -c 'cd ${PROJECT} && make ct' 45 | -------------------------------------------------------------------------------- /build.config: -------------------------------------------------------------------------------- 1 | # Do *not* comment or remove core modules 2 | # unless you know what you are doing. 3 | # 4 | # Feel free to comment plugins out however. 5 | 6 | # Core modules. 7 | core/core 8 | core/kerl 9 | index/* 10 | core/index 11 | core/deps 12 | 13 | # Core modules, continued. 14 | core/erlc 15 | core/docs 16 | core/rel 17 | core/test 18 | core/compat 19 | 20 | # Plugins. 21 | plugins/asciidoc 22 | plugins/bootstrap 23 | plugins/c_src 24 | plugins/ci 25 | plugins/concuerror 26 | plugins/ct 27 | plugins/dialyzer 28 | plugins/edoc 29 | plugins/erlydtl 30 | plugins/escript 31 | plugins/eunit 32 | plugins/hex 33 | plugins/proper 34 | plugins/protobuffs 35 | plugins/relx 36 | plugins/shell 37 | plugins/sphinx 38 | plugins/syntastic 39 | plugins/triq 40 | plugins/xref 41 | 42 | # Plugins enhancing the functionality of other plugins. 43 | plugins/cover 44 | plugins/sfx 45 | 46 | # External plugins. 47 | core/plugins 48 | 49 | # Core modules which can use variables from plugins. 50 | core/deps-tools -------------------------------------------------------------------------------- /c_deps/ed448goldilocks/.gitignore: -------------------------------------------------------------------------------- 1 | src/generator/curve_data.pyc 2 | src/generator/__pycache__/ 3 | -------------------------------------------------------------------------------- /c_deps/ed448goldilocks/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | ############################################################################ 2 | # CMakeLists.txt 3 | # 4 | # Released under the MIT License. See LICENSE.txt for license information. 5 | # 6 | ############################################################################ 7 | 8 | cmake_minimum_required(VERSION 3.0) 9 | project(DECAF VERSION 1.0 LANGUAGES C CXX) 10 | 11 | set(DECAF_SO_VERSION "0") 12 | 13 | find_package(PythonInterp 3 REQUIRED) 14 | 15 | option(ENABLE_SHARED "Build shared library." ON) 16 | option(ENABLE_STATIC "Build static library." ON) 17 | option(ENABLE_STRICT "Build with strict compile options." YES) 18 | option(ENABLE_TESTS "Enable compilation of tests." OFF) 19 | option(GENERATED_SOURCE_PATH "Where the generated source code is stored, default in the building tree" OFF) 20 | if (CMAKE_SYSTEM_NAME STREQUAL "WindowsStore") 21 | set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -nostdlib") 22 | endif() 23 | 24 | if (GENERATED_SOURCE_PATH) 25 | set(GSOURCE_PATH ${GENERATED_SOURCE_PATH}) 26 | else() 27 | set(GSOURCE_PATH ${PROJECT_BINARY_DIR}/src/GENERATED) 28 | endif() 29 | message("Generated source code in ${GSOURCE_PATH}") 30 | 31 | if(NOT CPACK_GENERATOR AND NOT CMAKE_INSTALL_RPATH AND CMAKE_INSTALL_PREFIX) 32 | set(CMAKE_INSTALL_RPATH ${CMAKE_INSTALL_FULL_LIBDIR}) 33 | message(STATUS "Setting install rpath to ${CMAKE_INSTALL_RPATH}") 34 | endif() 35 | 36 | include(GNUInstallDirs) 37 | include(CheckSymbolExists) 38 | include(CMakePushCheckState) 39 | 40 | include_directories( 41 | ${GSOURCE_PATH}/include/ 42 | src/include/ 43 | src/ 44 | ${CMAKE_CURRENT_BINARY_DIR} 45 | ) 46 | 47 | set(STRICT_OPTIONS_CPP ) 48 | set(STRICT_OPTIONS_C ) 49 | set(STRICT_OPTIONS_CXX ) 50 | if(MSVC) 51 | if(ENABLE_STRICT) 52 | set(STRICT_OPTIONS_CPP "${STRICT_OPTIONS_CPP} /WX /Zc:__cplusplus") 53 | endif() 54 | else() 55 | set(STRICT_OPTIONS_CXX "${STRICT_OPTIONS_CXX} -std=c++14 -O2") 56 | set(STRICT_OPTIONS_CPP "${STRICT_OPTIONS_CPP} -Wall -Wuninitialized -Wno-deprecated-declarations -Wno-missing-field-initializers") 57 | set(STRICT_OPTIONS_C "${STRICT_OPTIONS_C} -std=c99 -O2 -Wstrict-prototypes -Wno-error=strict-prototypes -fvisibility=hidden -Wno-error=implicit-function-declaration -Wno-error=attributes") 58 | if(CMAKE_C_COMPILER_ID MATCHES "Clang") 59 | set(STRICT_OPTIONS_CPP "${STRICT_OPTIONS_CPP} -Wno-error=unknown-warning-option -Qunused-arguments -Wno-tautological-compare") 60 | set(STRICT_OPTIONS_CPP "${STRICT_OPTIONS_CPP} -Wno-unused-function -Wno-pass-failed") 61 | endif() 62 | if(ENABLE_STRICT) 63 | set(STRICT_OPTIONS_CPP "${STRICT_OPTIONS_CPP} -Werror -Wextra -Wno-unused-parameter -fno-strict-aliasing") 64 | endif() 65 | endif() 66 | 67 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${STRICT_OPTIONS_C} ${STRICT_OPTIONS_CPP}") 68 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${STRICT_OPTIONS_CXX} ${STRICT_OPTIONS_CPP}") 69 | 70 | add_subdirectory(src) 71 | 72 | if(ENABLE_TESTS) 73 | enable_testing() 74 | add_subdirectory(test) 75 | endif() 76 | 77 | include(CMakePackageConfigHelpers) 78 | set(ConfigPackageLocation share/decaf/cmake) 79 | export(EXPORT ${EXPORT_TARGETS_NAME}Targets 80 | FILE "${CMAKE_CURRENT_BINARY_DIR}/DecafTargets.cmake" 81 | ) 82 | configure_package_config_file(cmake/DecafConfig.cmake.in 83 | "${CMAKE_CURRENT_BINARY_DIR}/DecafConfig.cmake" 84 | INSTALL_DESTINATION ${ConfigPackageLocation} 85 | NO_SET_AND_CHECK_MACRO 86 | ) 87 | 88 | install(EXPORT ${EXPORT_TARGETS_NAME}Targets 89 | FILE DecafTargets.cmake 90 | DESTINATION ${ConfigPackageLocation} 91 | ) 92 | install(FILES 93 | "${CMAKE_CURRENT_BINARY_DIR}/DecafConfig.cmake" 94 | DESTINATION ${ConfigPackageLocation} 95 | ) 96 | 97 | # Doxygen 98 | find_package(Doxygen) 99 | if (DOXYGEN_FOUND) 100 | configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile @ONLY) 101 | add_custom_target(doc 102 | ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile 103 | WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} 104 | DEPENDS generatedCode 105 | COMMENT "Generating API documentation with Doxygen" VERBATIM 106 | ) 107 | endif() 108 | 109 | # CPack settings 110 | set(CPACK_PACKAGE_NAME "decaf") 111 | set(CPACK_PACKAGE_VERSION ${PROJECT_VERSION}) 112 | set(CPACK_SOURCE_GENERATOR "TGZ") 113 | set(CPACK_SOURCE_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}") 114 | set(CPACK_SOURCE_IGnore_FILES 115 | "^${CMAKE_BINARY_DIR}" 116 | "/\\\\..+" 117 | ) 118 | 119 | include(CPack) 120 | -------------------------------------------------------------------------------- /c_deps/ed448goldilocks/LICENSE.txt: -------------------------------------------------------------------------------- 1 | The Python bindings are Copyright 2017 John-Mark Gurney, and are provided 2 | under a BSD license as described in python/edgold/ed448.py 3 | 4 | Certain sections of code are public domain or CC0, as marked. 5 | 6 | Earlier versions of this project used small amounts of code which were 7 | Copyright (c) 2011 Stanford University 8 | Copyright (c) 2011 Mike Hamburg 9 | but I believe that all of this code has now been replaced. 10 | 11 | The bulk of this library is 12 | Copyright (c) 2014-2017 Cryptography Research, Inc. 13 | and licensed under the following MIT license. 14 | 15 | 16 | 17 | The MIT License (MIT) 18 | 19 | Copyright (c) 2014-2017 Cryptography Research, Inc. 20 | 21 | Permission is hereby granted, free of charge, to any person obtaining a copy 22 | of this software and associated documentation files (the "Software"), to deal 23 | in the Software without restriction, including without limitation the rights 24 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 25 | copies of the Software, and to permit persons to whom the Software is 26 | furnished to do so, subject to the following conditions: 27 | 28 | The above copyright notice and this permission notice shall be included in 29 | all copies or substantial portions of the Software. 30 | 31 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 32 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 33 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 34 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 35 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 36 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 37 | THE SOFTWARE. 38 | -------------------------------------------------------------------------------- /c_deps/ed448goldilocks/README.md: -------------------------------------------------------------------------------- 1 | # Decaf elliptic curve library 2 | 3 | The libdecaf library is for elliptic curve research and practical application. 4 | It currently supports Ed448-Goldilocks and Curve25519. 5 | 6 | The goals of this library are: 7 | 8 | * Implementing the X25519, X448 key exchange protocols (RFC 7748). 9 | * Implementing the Ed25519 and EdDSA-Ed448 signature schemes (RFC 8032). 10 | * Providing a platform for research and development of advanced cryptographic schemes using twisted Edwards curves. 11 | 12 | This library is intended for developers who have experience with 13 | cryptography. It doesn't (yet?) include documentation on how to use 14 | digital signatures or key exchange securely. Consult your local 15 | cryptographer for advice. 16 | 17 | ## Mailing lists 18 | 19 | Because this is new software, please expect it to have bugs, perhaps 20 | even critical security bugs. If you are using it, please sign up for 21 | updates: 22 | 23 | * Security-critical announcements (very low volume, God willing): 24 | decaf-security@googlegroups.com, join at https://groups.google.com/forum/#!forum/decaf-security 25 | * New version announcements (low volume): 26 | decaf-announce@googlegroups.com, join at https://groups.google.com/forum/#!forum/decaf-annonuce 27 | * Library discussion (potentially more volume): 28 | decaf-discuss@googlegroups.com, join at https://groups.google.com/forum/#!forum/decaf-discuss 29 | 30 | ## General elliptic curve operations. 31 | 32 | This is a multi-purpose elliptic curve library. There is a C library, 33 | and a set of C++ wrapper headers. The C++ code consists entirely of 34 | inline calls, and has no compiled component. 35 | 36 | The library implements a fairly complete suite of operations on the 37 | supported curves: 38 | 39 | * Point and scalar serialization and deserialization. 40 | * Point addition, subtraction, doubling, and equality. 41 | * Point multiplication by scalars. Accelerated double- and dual-scalar multiply. 42 | * Scalar addition, subtraction, multiplication, division, and equality. 43 | * Construction of precomputed tables from points. Precomputed scalarmul. 44 | * Hashing to the curve with an Elligator variant. Inverse of elligator for steganography. These are useful for advanced protocols such as password-authenticated key exchange (PAKE) and verifiable random functions (VRFs). 45 | 46 | Internally, the library uses twisted Edwards curves with the "decaf" 47 | and "ristretto" technique to remove the curve's cofactor of 4 or 8. 48 | The upshot is that systems using the "decaf" interface will be using 49 | a prime-order group, which mitigates one of the few disadvantages of 50 | Edwards curves. However, this means that it is not able to implement 51 | systems which care about cofactor information. 52 | 53 | The goal of this library is not only to follow best practices, but to 54 | make it easier for clients of the library to follow best practices. 55 | With a few well-marked exceptions, the functions in this library should 56 | be strongly constant-time: they do not allow secret data to flow to 57 | array indices, nor to control decisions except for a final failure 58 | check. Furthermore, the C++ wrapping uses RAII to automatically clear 59 | sensitive data, and has interfaces designed to prevent certain mistakes. 60 | 61 | ## CFRG cryptosystems. 62 | 63 | The library additionally supports two cryptosystems defined by the 64 | Crypto Forum Research Group (CFRG): the X448/X25519 Diffie-Hellman 65 | functions (RFC 7748), and the EdDSA signature scheme (RFC 8032). 66 | Future versions might support additional operations on these curves, 67 | such as precomputed signature verification. 68 | 69 | ## Symmetric crypto and hashing 70 | 71 | The Decaf library doesn't implement much symmetric crypto, but it does 72 | contain the hash functions required by the CFRG cryptosystems: SHA512, 73 | SHA-3 and SHAKE. 74 | 75 | ## Internals 76 | 77 | The "decaf" technique is described in https://eprint.iacr.org/2015/673 78 | While the title of that paper is "removing cofactors through point 79 | compression", it might be more accurate to say "through quotients and 80 | isogenies". The internal representation of points is as "even" elements 81 | of a twisted Edwards curve with a=-1. Using this subgroup removes a 82 | factor of 2 from the cofactor. The remaining factor of 2 or 4 is 83 | removed with a quotient group: any two points which differ by an element 84 | of the 2- or 4-torsion subgroup are considered equal to each other. 85 | 86 | When a point is written out to wire format, it is converted (by isogeny) 87 | to a Jacobi quartic curve, which is halfway between an Edwards curve 88 | and a Montgomery curve. One of the 4 or 8 equivalent points on the 89 | Jacobi quartic is chosen (it is "distinguished" according to certain 90 | criteria, such as having a positive x-coordinate). The x-coordinate of 91 | this point is written out. The y-coordinate is not written out, but the 92 | decoder knows which of the two possible y-coordinates is correct because 93 | of the distinguishing rules. See the paper for more details. 94 | 95 | As of v0.9.4, libdecaf uses the "Ristretto" variant of this encoding. 96 | See https://www.ristretto.group for details, once that site is up. 97 | 98 | ## Build and Install 99 | 100 | cmake -DCMAKE_INSTALL_PREFIX= 101 | make 102 | make test 103 | make install 104 | 105 | Most C source code is generated through a python script during the build. 106 | Some files holding tables are generated in one more step building an 107 | executable to generate them. They are thus stored in the source tree to help 108 | cross-compilation. The build script update them when their dependencies 109 | are modified, to build only these files: 110 | 111 | make decaf_tables 112 | 113 | Doxygen generated documentation is located in ./doc directory in the 114 | binary tree after running 115 | 116 | make doc 117 | 118 | ## Licensing 119 | 120 | Most of the source files here are by Mike Hamburg. Those files are (c) 121 | 2014-2017 Cryptography Research, Inc (a division of Rambus). All of these 122 | files are usable under the MIT license contained in LICENSE.txt. 123 | 124 | ## Caveats 125 | 126 | As mentioned in the license, there is absolutely NO WARRANTY on any of this 127 | code. This code might well have security-critical bugs despite my best efforts. 128 | 129 | I've attempted to protect against timing attacks and invalid point attacks, 130 | but as of yet I've made no attempt to protect against power analysis. 131 | 132 | -------------------------------------------------------------------------------- /c_deps/ed448goldilocks/TODO.txt: -------------------------------------------------------------------------------- 1 | Important work items for Ed448-Goldilocks / decaf / Ristretto. 2 | 3 | * Test signed 32-bit NEON implementation to avoid bias/reduce after subtract 4 | 5 | * Documentation: write high-level API docs, and internal docs to help 6 | other implementors. 7 | * Pretty good progress on Doxygenating the code. 8 | 9 | * Documentation: help work on ristretto.group website. 10 | 11 | * Cleanup: unify intrinsics code 12 | * Generate asm intrinsics with a script? 13 | 14 | * Testing: 15 | * More testing. Testing, testing and testing. 16 | * Test corner cases better. 17 | * Try to formally verify some things. 18 | 19 | * Safety: 20 | * If RNG fails, return error and zeroize 21 | 22 | * Portability: test and make clean with other compilers 23 | * Using a fair amount of __attribute__ code. 24 | * Should work for GCC now. 25 | * Autoconf 26 | 27 | * Portability: try to make the vector code as portable as possible 28 | * Currently using clang ext_vector_length. 29 | * I can't get a simple for-loop to autovectorize :-/ 30 | * Autogenerate somehow? 31 | -------------------------------------------------------------------------------- /c_deps/ed448goldilocks/cmake/DecafConfig.cmake.in: -------------------------------------------------------------------------------- 1 | ############################################################################ 2 | # decafConfig.cmake 3 | # Copyright (C) 2017 Belledonne Communications, Grenoble France 4 | # 5 | ############################################################################ 6 | # 7 | # This program is free software; you can redistribute it and/or 8 | # modify it under the terms of the GNU General Public License 9 | # as published by the Free Software Foundation; either version 2 10 | # of the License, or (at your option) any later version. 11 | # 12 | # This program is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with this program; if not, write to the Free Software 19 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 | # 21 | ############################################################################ 22 | # 23 | # Config file for the decaf package. 24 | # It defines the following variables: 25 | # 26 | # DECAF_FOUND - system has decaf 27 | # DECAF_INCLUDE_DIRS - the decaf include directory 28 | # DECAF_LIBRARIES - The libraries needed to use decaf 29 | # DECAF_CPPFLAGS - The compilation flags needed to use decaf 30 | 31 | @PACKAGE_INIT@ 32 | 33 | include("${CMAKE_CURRENT_LIST_DIR}/DecafTargets.cmake") 34 | 35 | if(@ENABLE_SHARED@) 36 | set(DECAF_TARGETNAME decaf) 37 | else() 38 | set(DECAF_TARGETNAME decaf-static) 39 | endif() 40 | 41 | get_target_property(DECAF_INCLUDE_DIRS ${DECAF_TARGETNAME} INTERFACE_INCLUDE_DIRECTORIES) 42 | 43 | if(TARGET ${DECAF_TARGETNAME}) 44 | get_target_property(DECAF_LIBRARIES ${DECAF_TARGETNAME} LOCATION) 45 | get_target_property(DECAF_LINK_LIBRARIES ${DECAF_TARGETNAME} INTERFACE_LINK_LIBRARIES) 46 | if(DECAF_LINK_LIBRARIES) 47 | list(APPEND DECAF_LIBRARIES ${DECAF_LINK_LIBRARIES}) 48 | endif() 49 | endif() 50 | 51 | set(DECAF_CPPFLAGS @DECAF_CPPFLAGS@) 52 | set(DECAF_FOUND 1) 53 | -------------------------------------------------------------------------------- /c_deps/ed448goldilocks/python/.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | -------------------------------------------------------------------------------- /c_deps/ed448goldilocks/python/setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from distutils.command.build import build 4 | from distutils.core import setup 5 | 6 | import os 7 | 8 | class my_build(build): 9 | def run(self): 10 | build.run(self) 11 | if not self.dry_run: 12 | os.spawnlp(os.P_WAIT, 'sh', 'sh', '-c', 'cd .. && gmake lib') 13 | self.copy_file(os.path.join('..', 'build', 'lib', 'libdecaf.so'), os.path.join(self.build_lib, 'edgold')) 14 | 15 | cmdclass = {} 16 | cmdclass['build'] = my_build 17 | 18 | setup(name='edgold', 19 | version='0.1', 20 | description='The Ed ECC Goldilocks Python wrapper', 21 | author='John-Mark Gurney', 22 | author_email='jmg@funkthat.com', 23 | #url='', 24 | cmdclass=cmdclass, 25 | packages=['edgold', ], 26 | ) 27 | -------------------------------------------------------------------------------- /c_deps/ed448goldilocks/src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | ############################################################################ 2 | # CMakeLists.txt 3 | # 4 | # Released under the MIT License. See LICENSE.txt for license information. 5 | # 6 | ############################################################################ 7 | 8 | if(MSVC) 9 | add_definitions(-D_CRT_SECURE_NO_WARNINGS) 10 | endif() 11 | 12 | set(DECAF_HEADER_FILES 13 | include/constant_time.h 14 | include/field.h 15 | include/keccak_internal.h 16 | include/portable_endian.h 17 | include/word.h 18 | ) 19 | set(DECAF_SOURCE_FILES_C 20 | utils.c 21 | shake.c 22 | sha512.c 23 | spongerng.c 24 | 25 | ) 26 | 27 | # default target arch is arch_32 which shall be generic enough to compile mostly on anything 28 | # target arch dirs: 29 | # global one to get the include/arch_intrinsics.h 30 | # availables: arch_32, arch_arm_32, arch_neon, arch_ref64, arch_x86_64 31 | set(TARGET_ARCH_DIR arch_32) 32 | # specific to p25519, to get f_impl.c/h in p25519 33 | #availables: arch_32, arch_ref64, arch_x86_64 34 | set(TARGET_ARCH_DIR_P25519 arch_32) 35 | # specific to p448, to get f_impl.c/h in p448 36 | # availables: arch_32, arch_arm_32, arch_neon, arch_ref64, arch_x86_64 37 | set(TARGET_ARCH_DIR_P448 arch_32) 38 | 39 | 40 | if(MSVC)# On MSVC Windows, Processor is always AMD64 on both platforms (x86/x64) 41 | set(MSVC_ARCH ${CMAKE_CXX_COMPILER_ARCHITECTURE_ID})# ${MSVC_ARCH} MATCHES "X64" 42 | else() 43 | set(MSVC_ARCH ${CMAKE_SYSTEM_PROCESSOR})# just to have a value 44 | endif() 45 | if(${CMAKE_SYSTEM_PROCESSOR} MATCHES "x86_64" AND NOT MSVC)#Decaf doesn't support 64bits on MSVC yet 46 | message("Target architecture is x86_64") 47 | set(TARGET_ARCH_DIR arch_x86_64) 48 | set(TARGET_ARCH_DIR_P25519 arch_x86_64) 49 | set(TARGET_ARCH_DIR_P448 arch_x86_64) 50 | elseif(${CMAKE_SYSTEM_PROCESSOR} MATCHES "arch64") # shall be arm64 bits, stick to ref64. 51 | message("Target architecture is 64 bits general purpose(arm64 shall use this)") 52 | set(TARGET_ARCH_DIR arch_ref64) 53 | set(TARGET_ARCH_DIR_P25519 arch_ref64) 54 | set(TARGET_ARCH_DIR_P448 arch_ref64) 55 | elseif(${CMAKE_SYSTEM_PROCESSOR} MATCHES "arm") # is an arm 32 bits 56 | if (NOT ${CMAKE_ANDROID_ARCH_ABI} STREQUAL "armeabi") # arm <= 5.0 does not support instructions from the lib, keep arch_32 57 | if(${ANDROID_ARM_NEON}) 58 | message("Target architecture is arm32 NEON") 59 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mfpu=neon") # build with neon flag 60 | set(TARGET_ARCH_DIR arch_neon) 61 | set(TARGET_ARCH_DIR_P25519 arch_32) # nothing specific for neon on p25519 62 | set(TARGET_ARCH_DIR_P448 arch_neon) 63 | else(${ANDROID_ARM_NEON}) 64 | message("Target architecture is arm32 no NEON") 65 | set(TARGET_ARCH_DIR arch_arm_32) 66 | set(TARGET_ARCH_DIR_P25519 arch_32) # nothing specific for arch_arm on p25519 67 | set(TARGET_ARCH_DIR_P448 arch_arm_32) 68 | endif(${ANDROID_ARM_NEON}) 69 | endif (NOT ${CMAKE_ANDROID_ARCH_ABI} STREQUAL "armeabi") 70 | else() # nothing picked yet, stick to the 71 | message("Target architecture is general purpose 32bits") 72 | endif() 73 | 74 | include_directories( 75 | ${PROJECT_SOURCE_DIR}/src/include/${TARGET_ARCH_DIR} 76 | ) 77 | 78 | set(DECAF_SOURCE_FILES_CXX 79 | ) 80 | 81 | add_subdirectory(curve25519) 82 | add_subdirectory(ed448goldilocks) 83 | add_subdirectory(p25519) 84 | add_subdirectory(p448) 85 | 86 | add_subdirectory(generator) 87 | 88 | if(ENABLE_STATIC) 89 | add_library(decaf-static STATIC ${DECAF_HEADER_FILES} ${DECAF_SOURCE_FILES_C} ${DECAF_SOURCE_FILES_CXX} $ $ $ $) 90 | add_dependencies(decaf-static generatedCode) 91 | set_target_properties(decaf-static PROPERTIES OUTPUT_NAME decaf) 92 | target_include_directories(decaf-static INTERFACE $) 93 | target_link_libraries(decaf-static INTERFACE) 94 | endif() 95 | if(ENABLE_SHARED) 96 | add_library(decaf SHARED ${DECAF_HEADER_FILES} ${DECAF_SOURCE_FILES_C} ${DECAF_SOURCE_FILES_CXX} $ $ $ $) 97 | add_dependencies(decaf generatedCode) 98 | set_target_properties(decaf PROPERTIES VERSION ${DECAF_SO_VERSION}) 99 | target_include_directories(decaf INTERFACE $) 100 | target_link_libraries(decaf PRIVATE) 101 | if(MSVC) 102 | if(CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo") 103 | install(FILES $ 104 | DESTINATION ${CMAKE_INSTALL_BINDIR} 105 | PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE 106 | ) 107 | endif() 108 | endif() 109 | endif() 110 | 111 | if(ENABLE_STATIC) 112 | install(TARGETS decaf-static EXPORT ${EXPORT_TARGETS_NAME}Targets 113 | RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} 114 | LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} 115 | ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} 116 | PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE 117 | ) 118 | endif() 119 | if(ENABLE_SHARED) 120 | install(TARGETS decaf EXPORT ${EXPORT_TARGETS_NAME}Targets 121 | RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} 122 | LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} 123 | ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} 124 | PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE 125 | ) 126 | endif() 127 | 128 | install(DIRECTORY ${GSOURCE_PATH}/include/ 129 | DESTINATION include/decaf 130 | FILES_MATCHING PATTERN "*.h*" 131 | PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ 132 | ) 133 | -------------------------------------------------------------------------------- /c_deps/ed448goldilocks/src/curve25519/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | ############################################################################ 2 | # CMakeLists.txt 3 | # 4 | # Released under the MIT License. See LICENSE.txt for license information. 5 | # 6 | ############################################################################ 7 | 8 | include_directories( 9 | ${PROJECT_SOURCE_DIR}/src/p25519 10 | ${GSOURCE_PATH}/c/p25519 11 | ${PROJECT_SOURCE_DIR}/src/p25519/${TARGET_ARCH_DIR_P25519} 12 | ) 13 | 14 | set(CURVE25519_SOURCE_FILES_C 15 | ${GSOURCE_PATH}/c/curve25519/decaf.c 16 | ${GSOURCE_PATH}/c/curve25519/elligator.c 17 | ${GSOURCE_PATH}/c/curve25519/scalar.c 18 | ${GSOURCE_PATH}/c/curve25519/eddsa.c 19 | ${PROJECT_SOURCE_DIR}/src/curve25519/decaf_tables.c 20 | ) 21 | 22 | SET_SOURCE_FILES_PROPERTIES(${GSOURCE_PATH}/c/curve25519/decaf.c PROPERTIES GENERATED 1) 23 | SET_SOURCE_FILES_PROPERTIES(${GSOURCE_PATH}/c/curve25519/elligator.c PROPERTIES GENERATED 1) 24 | SET_SOURCE_FILES_PROPERTIES(${GSOURCE_PATH}/c/curve25519/scalar.c PROPERTIES GENERATED 1) 25 | SET_SOURCE_FILES_PROPERTIES(${GSOURCE_PATH}/c/curve25519/eddsa.c PROPERTIES GENERATED 1) 26 | SET_SOURCE_FILES_PROPERTIES(${PROJECT_SOURCE_DIR}/src/curve25519/decaf_tables.c PROPERTIES GENERATED 1) 27 | 28 | add_library(CURVE25519 OBJECT ${CURVE25519_SOURCE_FILES_C}) 29 | add_dependencies(CURVE25519 generatedCode p25519) 30 | set_target_properties(CURVE25519 PROPERTIES POSITION_INDEPENDENT_CODE True) 31 | -------------------------------------------------------------------------------- /c_deps/ed448goldilocks/src/ed448goldilocks/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | ############################################################################ 2 | # CMakeLists.txt 3 | # 4 | # Released under the MIT License. See LICENSE.txt for license information. 5 | # 6 | ############################################################################ 7 | 8 | include_directories( 9 | ${PROJECT_SOURCE_DIR}/src/p448 10 | ${GSOURCE_PATH}/c/p448 11 | ${PROJECT_SOURCE_DIR}/src/p448/${TARGET_ARCH_DIR_P448} 12 | ) 13 | 14 | set(CURVE448_SOURCE_FILES_C 15 | ${GSOURCE_PATH}/c/ed448goldilocks/decaf.c 16 | ${GSOURCE_PATH}/c/ed448goldilocks/elligator.c 17 | ${GSOURCE_PATH}/c/ed448goldilocks/scalar.c 18 | ${GSOURCE_PATH}/c/ed448goldilocks/eddsa.c 19 | ${PROJECT_SOURCE_DIR}/src/ed448goldilocks/decaf_tables.c 20 | ) 21 | 22 | SET_SOURCE_FILES_PROPERTIES(${GSOURCE_PATH}/c/ed448goldilocks/decaf.c PROPERTIES GENERATED 1) 23 | SET_SOURCE_FILES_PROPERTIES(${GSOURCE_PATH}/c/ed448goldilocks/elligator.c PROPERTIES GENERATED 1) 24 | SET_SOURCE_FILES_PROPERTIES(${GSOURCE_PATH}/c/ed448goldilocks/scalar.c PROPERTIES GENERATED 1) 25 | SET_SOURCE_FILES_PROPERTIES(${GSOURCE_PATH}/c/ed448goldilocks/eddsa.c PROPERTIES GENERATED 1) 26 | SET_SOURCE_FILES_PROPERTIES(${PROJECT_SOURCE_DIR}/src/ed448goldilocks/decaf_tables.c PROPERTIES GENERATED 1) 27 | 28 | add_library(CURVE448 OBJECT ${CURVE448_SOURCE_FILES_C}) 29 | add_dependencies(CURVE448 generatedCode p448) 30 | set_target_properties(CURVE448 PROPERTIES POSITION_INDEPENDENT_CODE True) 31 | -------------------------------------------------------------------------------- /c_deps/ed448goldilocks/src/generator/curve25519/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | ############################################################################ 2 | # CMakeLists.txt 3 | # 4 | # Released under the MIT License. See LICENSE.txt for license information. 5 | # 6 | ############################################################################ 7 | # p25519 field 8 | add_custom_command( 9 | COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/src/generator/template.py --per=field --guard=p25519/f_field.h --item=p25519 -o ${GSOURCE_PATH}/c/p25519/f_field.h ${PROJECT_SOURCE_DIR}/src/per_field/f_field.tmpl.h 10 | DEPENDS ${PROJECT_SOURCE_DIR}/src/generator/template.py ${PROJECT_SOURCE_DIR}/src/per_field/f_field.tmpl.h 11 | OUTPUT ${GSOURCE_PATH}/c/p25519/f_field.h 12 | COMMENT "Generating code for p25519/f_field.h" 13 | ) 14 | 15 | add_custom_command( 16 | COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/src/generator/template.py --per=field --guard=p25519/f_generic.c --item=p25519 -o ${GSOURCE_PATH}/c/p25519/f_generic.c ${PROJECT_SOURCE_DIR}/src/per_field/f_generic.tmpl.c 17 | DEPENDS ${PROJECT_SOURCE_DIR}/src/generator/template.py ${PROJECT_SOURCE_DIR}/src/per_field/f_generic.tmpl.c 18 | OUTPUT ${GSOURCE_PATH}/c/p25519/f_generic.c 19 | COMMENT "Generating code for p25519/f_generic.c" 20 | ) 21 | 22 | add_custom_target(generatorP25519 DEPENDS 23 | generatorCommonCode 24 | ${GSOURCE_PATH}/c/p25519/f_field.h 25 | ${GSOURCE_PATH}/c/p25519/f_generic.c 26 | ) 27 | 28 | # curve25519 29 | add_custom_command( 30 | COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/src/generator/template.py --per=curve --item=curve25519 --guard=curve25519/scalar.c -o ${GSOURCE_PATH}/c/curve25519/scalar.c ${PROJECT_SOURCE_DIR}/src/per_curve/scalar.tmpl.c 31 | DEPENDS ${PROJECT_SOURCE_DIR}/src/generator/template.py ${PROJECT_SOURCE_DIR}/src/per_curve/scalar.tmpl.c 32 | OUTPUT ${GSOURCE_PATH}/c/curve25519/scalar.c 33 | COMMENT "Generating code for curve25519/scalar.c" 34 | ) 35 | 36 | add_custom_command( 37 | COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/src/generator/template.py --per=curve --item=curve25519 --guard=curve25519/decaf.c -o ${GSOURCE_PATH}/c/curve25519/decaf.c ${PROJECT_SOURCE_DIR}/src/per_curve/decaf.tmpl.c 38 | DEPENDS ${PROJECT_SOURCE_DIR}/src/generator/template.py ${PROJECT_SOURCE_DIR}/src/per_curve/decaf.tmpl.c 39 | OUTPUT ${GSOURCE_PATH}/c/curve25519/decaf.c 40 | COMMENT "Generating code for curve25519/decaf.c" 41 | ) 42 | 43 | add_custom_command( 44 | COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/src/generator/template.py --per=curve --item=curve25519 --guard=curve25519/elligator.c -o ${GSOURCE_PATH}/c/curve25519/elligator.c ${PROJECT_SOURCE_DIR}/src/per_curve/elligator.tmpl.c 45 | DEPENDS ${PROJECT_SOURCE_DIR}/src/generator/template.py ${PROJECT_SOURCE_DIR}/src/per_curve/elligator.tmpl.c 46 | OUTPUT ${GSOURCE_PATH}/c/curve25519/elligator.c 47 | COMMENT "Generating code for curve25519/elligator.c" 48 | ) 49 | 50 | add_custom_command( 51 | COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/src/generator/template.py --per=curve --item=curve25519 --guard=curve25519/eddsa.c -o ${GSOURCE_PATH}/c/curve25519/eddsa.c ${PROJECT_SOURCE_DIR}/src/per_curve/eddsa.tmpl.c 52 | DEPENDS ${PROJECT_SOURCE_DIR}/src/generator/template.py ${PROJECT_SOURCE_DIR}/src/per_curve/eddsa.tmpl.c 53 | OUTPUT ${GSOURCE_PATH}/c/curve25519/eddsa.c 54 | COMMENT "Generating code for curve25519/eddsa.c" 55 | ) 56 | 57 | add_custom_command( 58 | COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/src/generator/template.py --per=curve --item=curve25519 --guard=curve25519/decaf_gen_tables.c -o ${GSOURCE_PATH}/c/curve25519/decaf_gen_tables.c ${PROJECT_SOURCE_DIR}/src/per_curve/decaf_gen_tables.tmpl.c 59 | DEPENDS ${PROJECT_SOURCE_DIR}/src/generator/template.py ${PROJECT_SOURCE_DIR}/src/per_curve/decaf_gen_tables.tmpl.c 60 | OUTPUT ${GSOURCE_PATH}/c/curve25519/decaf_gen_tables.c 61 | COMMENT "Generating code for curve25519/decaf_gen_tables.c" 62 | ) 63 | 64 | add_custom_command( 65 | COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/src/generator/template.py --per=curve --item=curve25519 --guard=decaf/point_255.hxx -o ${GSOURCE_PATH}/include/decaf/point_255.hxx ${PROJECT_SOURCE_DIR}/src/per_curve/point.tmpl.hxx 66 | DEPENDS ${PROJECT_SOURCE_DIR}/src/generator/template.py ${PROJECT_SOURCE_DIR}/src/per_curve/point.tmpl.hxx 67 | OUTPUT ${GSOURCE_PATH}/include/decaf/point_255.hxx 68 | COMMENT "Generating code for include/decaf/point_255.hxx" 69 | ) 70 | 71 | add_custom_command( 72 | COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/src/generator/template.py --per=curve --item=curve25519 --guard=decaf/ed255.hxx -o ${GSOURCE_PATH}/include/decaf/ed255.hxx ${PROJECT_SOURCE_DIR}/src/per_curve/eddsa.tmpl.hxx 73 | DEPENDS ${PROJECT_SOURCE_DIR}/src/generator/template.py ${PROJECT_SOURCE_DIR}/src/per_curve/eddsa.tmpl.hxx 74 | OUTPUT ${GSOURCE_PATH}/include/decaf/ed255.hxx 75 | COMMENT "Generating code for include/decaf/ed255.hxx" 76 | ) 77 | 78 | add_custom_target(genC25519nTab DEPENDS 79 | ${GSOURCE_PATH}/c/curve25519/decaf.c 80 | ${GSOURCE_PATH}/c/curve25519/scalar.c 81 | ) 82 | add_custom_target(generatorCurve25519 DEPENDS 83 | generatorP25519 84 | genC25519nTab 85 | ${GSOURCE_PATH}/c/curve25519/elligator.c 86 | ${GSOURCE_PATH}/c/curve25519/eddsa.c 87 | ${GSOURCE_PATH}/include/decaf/point_255.hxx 88 | ${GSOURCE_PATH}/include/decaf/ed255.hxx 89 | ) 90 | include_directories( 91 | ${PROJECT_SOURCE_DIR}/src/p25519 92 | ${GSOURCE_PATH}/c/p25519 93 | ${PROJECT_SOURCE_DIR}/src/p25519/${TARGET_ARCH_DIR_P25519} 94 | ) 95 | 96 | add_executable(decaf_gen_tables_curve25519 EXCLUDE_FROM_ALL ${GSOURCE_PATH}/c/curve25519/decaf_gen_tables.c 97 | ${GSOURCE_PATH}/c/curve25519/decaf.c 98 | ${GSOURCE_PATH}/c/curve25519/scalar.c 99 | ${PROJECT_SOURCE_DIR}/src/utils.c 100 | $) 101 | add_dependencies(decaf_gen_tables_curve25519 genC25519nTab) 102 | 103 | add_custom_target(decaf_tables_curve25519 104 | COMMAND decaf_gen_tables_curve25519 > ${PROJECT_SOURCE_DIR}/src/curve25519/decaf_tables.c 105 | DEPENDS decaf_gen_tables_curve25519 106 | COMMENT "Generating code for curve25519/decaf_tables.c" 107 | ) 108 | -------------------------------------------------------------------------------- /c_deps/ed448goldilocks/src/generator/curve_data.py: -------------------------------------------------------------------------------- 1 | from collections import namedtuple 2 | from binascii import unhexlify 3 | 4 | comb_config = namedtuple("comb_config",["n","t","s"]) 5 | wnaf_config = namedtuple("wnaf_config",["fixed","var"]) 6 | 7 | field_data = { 8 | "p25519" : { 9 | "gf_desc" : "2^255 - 19", 10 | "gf_shortname" : "25519", 11 | "gf_impl_bits" : 320, 12 | "gf_lit_limb_bits" : 51, 13 | "elligator_onto" : 0 14 | }, 15 | "p448" : { 16 | "gf_desc" : "2^448 - 2^224 - 1", 17 | "gf_shortname" : "448", 18 | "gf_impl_bits" : 512, 19 | "gf_lit_limb_bits" : 56, 20 | "elligator_onto" : 0 21 | } 22 | } 23 | 24 | curve_data = { 25 | "curve25519" : { 26 | "altname" : "IsoEd25519", 27 | "iso_to" : "Curve25519", 28 | "name" : "Ristretto", 29 | "cofactor" : 8, 30 | "field" : "p25519", 31 | "scalar_bits" : 253, 32 | "d": -121665, 33 | "trace": -0xa6f7cef517bce6b2c09318d2e7ae9f7a, 34 | "mont_base": 9, 35 | "rist_base": "e2f2ae0a6abc4e71a884a961c500515f58e30b6aa582dd8db6a65945e08d2d76", 36 | "eddsa_encode_ratio": 4, 37 | "x_encode_ratio": 4, 38 | 39 | "combs":comb_config(3,5,17), 40 | "wnaf":wnaf_config(5,3), 41 | "window_bits":4, 42 | 43 | "eddsa_hash": "sha512", 44 | "eddsa_no_context": 1, 45 | "eddsa_dom": "SigEd25519 no Ed25519 collisions", 46 | "eddsa_sigma_iso": 1 47 | }, 48 | "ed448goldilocks" : { 49 | "eddsa_encode_ratio": 4, 50 | "x_encode_ratio": 2, 51 | "altname": None, 52 | "name" : "Ed448-Goldilocks", 53 | "cofactor" : 4, 54 | "field" : "p448", 55 | "scalar_bits" : 446, 56 | "d": -39081, 57 | "trace": 0x10cd77058eec492d944a725bf7a4cf635c8e9c2ab721cf5b5529eec34, 58 | "rist_base": "6666666666666666666666666666666666666666666666666666666633333333333333333333333333333333333333333333333333333333", 59 | "mont_base": 5, 60 | 61 | "combs":comb_config(5,5,18), 62 | "wnaf":wnaf_config(5,3), 63 | "window_bits":5, 64 | 65 | "eddsa_dom":"SigEd448" 66 | } 67 | } 68 | 69 | def ser(x,bits,paren=None): 70 | out = "" 71 | mask = 2**bits - 1 72 | first = True 73 | while x > 0 or first: 74 | desc = "0x%0*x" % ((bits+3)//4,x&mask) 75 | if paren is not None: 76 | desc = "%s(%s)" % (paren,desc) 77 | if not first: out += ", " 78 | out += desc 79 | x = x >> bits 80 | first = False 81 | return out 82 | 83 | def msqrt(x,p,hi_bit_clear = True, lo_bit_clear = False): 84 | if p % 4 == 3: ret = pow(x,(p+1)//4,p) 85 | elif p % 8 == 5: 86 | for u in range(1,1000): 87 | if pow(u,(p-1)//2,p) != 1: break 88 | u = pow(u,(p-1)//4,p) 89 | ret = pow(x,(p+3)//8,p) 90 | if pow(ret,2,p) != (x % p): ret = (ret * u) % p 91 | else: raise Exception("sqrt only for 3-mod-4 or 5-mod-8") 92 | 93 | if (ret**2-x) % p != 0: raise Exception("No sqrt") 94 | if hi_bit_clear and ret > p//2: ret = p-ret 95 | # lo_bit_clear overrides hi_bit_clear because it's not default 96 | if lo_bit_clear and (ret & 1): ret = p-ret 97 | return ret 98 | 99 | def ceil_log2(x): 100 | out = 0 101 | cmp = 1 102 | while x > cmp: 103 | cmp = cmp<<1 104 | out += 1 105 | return out 106 | 107 | for field,data in field_data.items(): 108 | if "modulus" not in data: 109 | data["modulus"] = eval(data["gf_desc"].replace("^","**")) 110 | 111 | if "gf_bits" not in data: 112 | data["gf_bits"] = ceil_log2(data["modulus"]) 113 | 114 | for curve,data in curve_data.items(): 115 | for key in field_data[data["field"]]: 116 | if key not in data: 117 | data[key] = field_data[data["field"]][key] 118 | 119 | 120 | if "iso_to" not in data: 121 | data["iso_to"] = data["name"] 122 | 123 | if "eddsa_hash" not in data: 124 | data["eddsa_hash"] = "shake256" 125 | 126 | if "eddsa_no_context" not in data: 127 | data["eddsa_no_context"] = 0 128 | 129 | if "cxx_ns" not in data: 130 | data["cxx_ns"] = data["name"].replace("-","") 131 | 132 | if "eddsa_sigma_iso" not in data: 133 | data["eddsa_sigma_iso"] = 0 134 | 135 | if "rist_base_decoded" not in data: 136 | def xord(x): 137 | if isinstance(x,str): return ord(x) 138 | else: return x 139 | data["rist_base_decoded"] = sum( 140 | xord(b)<<(8*i) for i,b in enumerate(unhexlify(data["rist_base"])) 141 | ) 142 | 143 | if "imagine_twist" not in data: 144 | # This is a HACK. The real problem is that iso-Ed25519 145 | # has points at infinity unless you IMAGINE_TWIST. 146 | # 147 | # Also there are lots of bugs when cofactor=8 != IMAGINE_TWIST. 148 | # (FUTURE: fix all this to support other curves, eventually) 149 | if data["modulus"]%4 == 3: data["imagine_twist"] = 0 150 | else: data["imagine_twist"] = 1 151 | # data["imagine_twist"] = 0 152 | 153 | data["q"] = (data["modulus"]+1-data["trace"]) // data["cofactor"] 154 | data["bits"] = ceil_log2(data["modulus"]) 155 | 156 | if "c_ns" not in data: 157 | data["c_ns"] = "decaf_" + str(data["bits"]) 158 | data["C_NS"] = data["c_ns"].upper() 159 | 160 | 161 | -------------------------------------------------------------------------------- /c_deps/ed448goldilocks/src/generator/ed448goldilocks/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | ############################################################################ 2 | # CMakeLists.txt 3 | # 4 | # Released under the MIT License. See LICENSE.txt for license information. 5 | # 6 | ############################################################################ 7 | # p448 field 8 | add_custom_command( 9 | COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/src/generator/template.py --per=field --guard=p448/f_field.h --item=p448 -o ${GSOURCE_PATH}/c/p448/f_field.h ${PROJECT_SOURCE_DIR}/src/per_field/f_field.tmpl.h 10 | 11 | DEPENDS ${PROJECT_SOURCE_DIR}/src/generator/template.py ${PROJECT_SOURCE_DIR}/src/per_field/f_field.tmpl.h 12 | OUTPUT ${GSOURCE_PATH}/c/p448/f_field.h 13 | COMMENT "Generating code for p448/f_field.h" 14 | ) 15 | 16 | add_custom_command( 17 | COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/src/generator/template.py --per=field --guard=p448/f_generic.c --item=p448 -o ${GSOURCE_PATH}/c/p448/f_generic.c ${PROJECT_SOURCE_DIR}/src/per_field/f_generic.tmpl.c 18 | 19 | DEPENDS ${PROJECT_SOURCE_DIR}/src/generator/template.py ${PROJECT_SOURCE_DIR}/src/per_field/f_generic.tmpl.c 20 | OUTPUT ${GSOURCE_PATH}/c/p448/f_generic.c 21 | COMMENT "Generating code for p448/f_generic.c" 22 | ) 23 | 24 | add_custom_target(generatorP448 DEPENDS 25 | generatorCommonCode 26 | ${GSOURCE_PATH}/c/p448/f_field.h 27 | ${GSOURCE_PATH}/c/p448/f_generic.c 28 | ) 29 | 30 | # ed448goldilocks 31 | add_custom_command( 32 | COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/src/generator/template.py --per=curve --item=ed448goldilocks --guard=ed448goldilocks/scalar.c -o ${GSOURCE_PATH}/c/ed448goldilocks/scalar.c ${PROJECT_SOURCE_DIR}/src/per_curve/scalar.tmpl.c 33 | 34 | DEPENDS ${PROJECT_SOURCE_DIR}/src/generator/template.py ${PROJECT_SOURCE_DIR}/src/per_curve/scalar.tmpl.c 35 | OUTPUT ${GSOURCE_PATH}/c/ed448goldilocks/scalar.c 36 | COMMENT "Generating code for ed448goldilocks/scalar.c" 37 | ) 38 | 39 | add_custom_command( 40 | COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/src/generator/template.py --per=curve --item=ed448goldilocks --guard=ed448goldilocks/decaf.c -o ${GSOURCE_PATH}/c/ed448goldilocks/decaf.c ${PROJECT_SOURCE_DIR}/src/per_curve/decaf.tmpl.c 41 | 42 | DEPENDS ${PROJECT_SOURCE_DIR}/src/generator/template.py ${PROJECT_SOURCE_DIR}/src/per_curve/decaf.tmpl.c 43 | OUTPUT ${GSOURCE_PATH}/c/ed448goldilocks/decaf.c 44 | COMMENT "Generating code for ed448goldilocks/decaf.c" 45 | ) 46 | 47 | add_custom_command( 48 | COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/src/generator/template.py --per=curve --item=ed448goldilocks --guard=ed448goldilocks/elligator.c -o ${GSOURCE_PATH}/c/ed448goldilocks/elligator.c ${PROJECT_SOURCE_DIR}/src/per_curve/elligator.tmpl.c 49 | 50 | DEPENDS ${PROJECT_SOURCE_DIR}/src/generator/template.py ${PROJECT_SOURCE_DIR}/src/per_curve/elligator.tmpl.c 51 | OUTPUT ${GSOURCE_PATH}/c/ed448goldilocks/elligator.c 52 | COMMENT "Generating code for ed448goldilocks/elligator.c" 53 | ) 54 | 55 | add_custom_command( 56 | COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/src/generator/template.py --per=curve --item=ed448goldilocks --guard=ed448goldilocks/eddsa.c -o ${GSOURCE_PATH}/c/ed448goldilocks/eddsa.c ${PROJECT_SOURCE_DIR}/src/per_curve/eddsa.tmpl.c 57 | 58 | DEPENDS ${PROJECT_SOURCE_DIR}/src/generator/template.py ${PROJECT_SOURCE_DIR}/src/per_curve/eddsa.tmpl.c 59 | OUTPUT ${GSOURCE_PATH}/c/ed448goldilocks/eddsa.c 60 | COMMENT "Generating code for ed448goldilocks/eddsa.c" 61 | ) 62 | 63 | add_custom_command( 64 | COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/src/generator/template.py --per=curve --item=ed448goldilocks --guard=ed448goldilocks/decaf_gen_tables.c -o ${GSOURCE_PATH}/c/ed448goldilocks/decaf_gen_tables.c ${PROJECT_SOURCE_DIR}/src/per_curve/decaf_gen_tables.tmpl.c 65 | 66 | DEPENDS ${PROJECT_SOURCE_DIR}/src/generator/template.py ${PROJECT_SOURCE_DIR}/src/per_curve/decaf_gen_tables.tmpl.c 67 | OUTPUT ${GSOURCE_PATH}/c/ed448goldilocks/decaf_gen_tables.c 68 | COMMENT "Generating code for ed448goldilocks/decaf_gen_tables.c" 69 | ) 70 | 71 | add_custom_command( 72 | COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/src/generator/template.py --per=curve --item=ed448goldilocks --guard=decaf/point_448.hxx -o ${GSOURCE_PATH}/include/decaf/point_448.hxx ${PROJECT_SOURCE_DIR}/src/per_curve/point.tmpl.hxx 73 | DEPENDS ${PROJECT_SOURCE_DIR}/src/generator/template.py ${PROJECT_SOURCE_DIR}/src/per_curve/point.tmpl.hxx 74 | OUTPUT ${GSOURCE_PATH}/include/decaf/point_448.hxx 75 | COMMENT "Generating code for include/decaf/point_448.hxx" 76 | ) 77 | 78 | add_custom_command( 79 | COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/src/generator/template.py --per=curve --item=ed448goldilocks --guard=decaf/ed448.hxx -o ${GSOURCE_PATH}/include/decaf/ed448.hxx ${PROJECT_SOURCE_DIR}/src/per_curve/eddsa.tmpl.hxx 80 | DEPENDS ${PROJECT_SOURCE_DIR}/src/generator/template.py ${PROJECT_SOURCE_DIR}/src/per_curve/eddsa.tmpl.hxx 81 | OUTPUT ${GSOURCE_PATH}/include/decaf/ed448.hxx 82 | COMMENT "Generating code for include/decaf/ed448.hxx" 83 | ) 84 | 85 | add_custom_target(genEd448nTab DEPENDS 86 | ${GSOURCE_PATH}/c/ed448goldilocks/scalar.c 87 | ${GSOURCE_PATH}/c/ed448goldilocks/decaf.c 88 | ) 89 | add_custom_target(generatorEd448goldilocks DEPENDS 90 | generatorP448 91 | genEd448nTab 92 | ${GSOURCE_PATH}/c/ed448goldilocks/elligator.c 93 | ${GSOURCE_PATH}/c/ed448goldilocks/eddsa.c 94 | ${GSOURCE_PATH}/include/decaf/point_448.hxx 95 | ${GSOURCE_PATH}/include/decaf/ed448.hxx 96 | ) 97 | include_directories( 98 | ${PROJECT_SOURCE_DIR}/src/p448 99 | ${GSOURCE_PATH}/c/p448 100 | ${PROJECT_SOURCE_DIR}/src/p448/${TARGET_ARCH_DIR_P448} 101 | ) 102 | 103 | add_executable(decaf_gen_tables_ed448goldilocks EXCLUDE_FROM_ALL ${GSOURCE_PATH}/c/ed448goldilocks/decaf_gen_tables.c 104 | ${GSOURCE_PATH}/c/ed448goldilocks/decaf.c 105 | ${GSOURCE_PATH}/c/ed448goldilocks/scalar.c 106 | ${PROJECT_SOURCE_DIR}/src/utils.c 107 | $) 108 | add_dependencies(decaf_gen_tables_ed448goldilocks genEd448nTab) 109 | 110 | add_custom_target(decaf_tables_ed448goldilocks 111 | COMMAND decaf_gen_tables_ed448goldilocks > ${PROJECT_SOURCE_DIR}/src/ed448goldilocks/decaf_tables.c 112 | DEPENDS decaf_gen_tables_ed448goldilocks 113 | COMMENT "Generating code for ed448goldilocks/decaf_tables.c" 114 | ) 115 | -------------------------------------------------------------------------------- /c_deps/ed448goldilocks/src/generator/template.py: -------------------------------------------------------------------------------- 1 | from textwrap import dedent 2 | from curve_data import field_data,curve_data,ser,msqrt,ceil_log2 3 | 4 | import os 5 | import argparse 6 | import re 7 | import errno 8 | 9 | parser = argparse.ArgumentParser(description='Generate Decaf headers and other such files.') 10 | parser.add_argument('-o', required = True, help = "Output") 11 | parser.add_argument('--per', required = True, help = "Files to be generated are global or per field/curve", choices=["global","field","curve"]) 12 | parser.add_argument('--item', required = False, default = "global", help = "Which curve/field to choose") 13 | parser.add_argument('--guard', required = False, default = None, help = "header guard") 14 | parser.add_argument('files', metavar='file', type=str, nargs='+', help='a list of files to fill') 15 | args = parser.parse_args() 16 | 17 | per_map = {"field":field_data, "curve":curve_data, "global":{"global":{"field":field_data,"curve":curve_data} }} 18 | 19 | def redoc(filename,doc,author): 20 | doc = doc.replace("\n","\n * ") 21 | doc = dedent(""" 22 | /** 23 | * @file %(filename)s 24 | * @author %(author)s 25 | * 26 | * @copyright 27 | * Copyright (c) 2015-2016 Cryptography Research, Inc. \\n 28 | * Released under the MIT License. See LICENSE.txt for license information. 29 | * 30 | * %(doc)s 31 | * 32 | * @warning This file was automatically generated in Python. 33 | * Please do not edit it. 34 | */""") % { "filename": filename, "doc": doc, "author" : author } 35 | doc = doc.replace(" * \n", " *\n") 36 | return doc[1:] 37 | 38 | def gen_file(public,name,doc,code,per="global",author="Mike Hamburg"): 39 | is_header = name.endswith(".h") or name.endswith(".hxx") or name.endswith(".h++") 40 | 41 | def fillin(template,data): 42 | position = 0 43 | ret = "" 44 | while True: 45 | dollars = template.find("$(",position) 46 | if dollars == -1: return ret + template[position:] 47 | ret += template[position:dollars] 48 | position = dollars + 2 49 | parens = 1 50 | while parens > 0: 51 | if template[position] == '(': parens += 1 52 | elif template[position] == ')': parens -= 1 53 | position += 1 54 | ret += str(eval(template[dollars+2:position-1],{'re':re,'ser':ser,'msqrt':msqrt,'ceil_log2':ceil_log2},data)) 55 | 56 | author = "Mike Hamburg" # FUTURE 57 | for name in args.files: 58 | _,_,name_suffix = name.rpartition(".") 59 | template0 = open(name,"r").read() 60 | 61 | data = per_map[args.per][args.item] 62 | 63 | template = template0 64 | 65 | outname = args.o 66 | guard = args.guard 67 | if guard is None: guard = outname 68 | header_guard = "__" + guard.replace(".","_").replace("/","_").upper() + "__" 69 | 70 | # Extract doxygenation 71 | m = re.match(r"^\s*/\*\*([^*]|\*[^/])+\*/[ \t]*\n",template) 72 | if m: 73 | doc = re.sub("^\s*/?\*+/?[ \t]*","",m.group(),flags=re.MULTILINE) 74 | doc = re.sub("\\s*\*/","",doc) 75 | template = template[m.end():] 76 | else: doc = "" 77 | 78 | ns_doc = dedent(doc).strip().rstrip() 79 | ns_doc = redoc(guard, fillin(ns_doc,data), author) 80 | ns_code = fillin(template,data) 81 | ret = ns_doc + "\n" 82 | 83 | if outname.endswith(".h") or outname.endswith(".hxx"): 84 | ns_code = dedent("""\n 85 | #ifndef %(header_guard)s 86 | #define %(header_guard)s 1 87 | %(code)s 88 | #endif /* %(header_guard)s */ 89 | """) % { "header_guard" : header_guard, "code": ns_code } 90 | ret += ns_code[1:-1] 91 | 92 | try: 93 | os.makedirs(os.path.dirname(outname)) 94 | except OSError as e: 95 | if e.errno != errno.EEXIST: 96 | raise 97 | with open(outname,"w") as f: 98 | f.write(ret + "\n") 99 | -------------------------------------------------------------------------------- /c_deps/ed448goldilocks/src/include/arch_32/arch_intrinsics.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2016 Cryptography Research, Inc. 2 | * Released under the MIT License. See LICENSE.txt for license information. 3 | */ 4 | 5 | #ifndef __ARCH_ARCH_32_ARCH_INTRINSICS_H__ 6 | #define __ARCH_ARCH_32_ARCH_INTRINSICS_H__ 7 | 8 | #define ARCH_WORD_BITS 32 9 | 10 | #if defined _MSC_VER 11 | #define __attribute(x) 12 | #define __inline__ __inline 13 | #endif // MSVC 14 | 15 | static __inline__ __attribute((always_inline,unused)) 16 | uint32_t word_is_zero(uint32_t a) { 17 | /* let's hope the compiler isn't clever enough to optimize this. */ 18 | return (((uint64_t)a)-1)>>32; 19 | } 20 | 21 | static __inline__ __attribute((always_inline,unused)) 22 | uint64_t widemul(uint32_t a, uint32_t b) { 23 | return ((uint64_t)a) * b; 24 | } 25 | 26 | #endif /* __ARCH_ARM_32_ARCH_INTRINSICS_H__ */ 27 | 28 | -------------------------------------------------------------------------------- /c_deps/ed448goldilocks/src/include/arch_arm_32/arch_intrinsics.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2016 Cryptography Research, Inc. 2 | * Released under the MIT License. See LICENSE.txt for license information. 3 | */ 4 | 5 | #ifndef __ARCH_ARM_32_ARCH_INTRINSICS_H__ 6 | #define __ARCH_ARM_32_ARCH_INTRINSICS_H__ 7 | 8 | #define ARCH_WORD_BITS 32 9 | 10 | static __inline__ __attribute((always_inline,unused)) 11 | uint32_t word_is_zero(uint32_t a) { 12 | uint32_t ret; 13 | __asm__("subs %0, %1, #1;\n\tsbc %0, %0, %0" : "=r"(ret) : "r"(a) : "cc"); 14 | return ret; 15 | } 16 | 17 | static __inline__ __attribute((always_inline,unused)) 18 | uint64_t widemul(uint32_t a, uint32_t b) { 19 | /* Could be UMULL, but it's hard to express to CC that the registers must be different */ 20 | return ((uint64_t)a) * b; 21 | } 22 | 23 | #endif /* __ARCH_ARM_32_ARCH_INTRINSICS_H__ */ 24 | 25 | -------------------------------------------------------------------------------- /c_deps/ed448goldilocks/src/include/arch_neon/arch_intrinsics.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2016 Cryptography Research, Inc. 2 | * Released under the MIT License. See LICENSE.txt for license information. 3 | */ 4 | 5 | #ifndef __ARCH_NEON_ARCH_INTRINSICS_H__ 6 | #define __ARCH_NEON_ARCH_INTRINSICS_H__ 7 | 8 | #define ARCH_WORD_BITS 32 9 | 10 | static __inline__ __attribute((always_inline,unused)) 11 | uint32_t word_is_zero(uint32_t a) { 12 | uint32_t ret; 13 | __asm__("subs %0, %1, #1;\n\tsbc %0, %0, %0" : "=r"(ret) : "r"(a) : "cc"); 14 | return ret; 15 | } 16 | 17 | static __inline__ __attribute((always_inline,unused)) 18 | uint64_t widemul(uint32_t a, uint32_t b) { 19 | /* Could be UMULL, but it's hard to express to CC that the registers must be different */ 20 | return ((uint64_t)a) * b; 21 | } 22 | 23 | #endif /* __ARCH_NEON_ARCH_INTRINSICS_H__ */ 24 | 25 | -------------------------------------------------------------------------------- /c_deps/ed448goldilocks/src/include/arch_ref64/arch_intrinsics.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2016 Cryptography Research, Inc. 2 | * Released under the MIT License. See LICENSE.txt for license information. 3 | */ 4 | 5 | #ifndef __ARCH_REF64_ARCH_INTRINSICS_H__ 6 | #define __ARCH_REF64_ARCH_INTRINSICS_H__ 7 | 8 | #define ARCH_WORD_BITS 64 9 | 10 | static __inline__ __attribute((always_inline,unused)) 11 | uint64_t word_is_zero(uint64_t a) { 12 | /* let's hope the compiler isn't clever enough to optimize this. */ 13 | return (((__uint128_t)a)-1)>>64; 14 | } 15 | 16 | static __inline__ __attribute((always_inline,unused)) 17 | __uint128_t widemul(uint64_t a, uint64_t b) { 18 | return ((__uint128_t)a) * b; 19 | } 20 | 21 | #endif /* ARCH_REF64_ARCH_INTRINSICS_H__ */ 22 | 23 | -------------------------------------------------------------------------------- /c_deps/ed448goldilocks/src/include/decaf/crypto.tmpl.hxx: -------------------------------------------------------------------------------- 1 | /** 2 | * Example Decaf crypto routines, C++ metaheader. 3 | * @warning These are merely examples, though they ought to be secure. But real 4 | * protocols will decide differently on magic numbers, formats, which items to 5 | * hash, etc. 6 | */ 7 | 8 | $("\n".join([ 9 | "#include " % g for g in sorted([c["bits"] for _,c in curve.items()]) 10 | ])) 11 | -------------------------------------------------------------------------------- /c_deps/ed448goldilocks/src/include/field.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file field.h 3 | * @brief Generic gf header. 4 | * @copyright 5 | * Copyright (c) 2014 Cryptography Research, Inc. \n 6 | * Released under the MIT License. See LICENSE.txt for license information. 7 | * @author Mike Hamburg 8 | */ 9 | 10 | #ifndef __GF_H__ 11 | #define __GF_H__ 12 | 13 | #include "constant_time.h" 14 | #include "f_field.h" 15 | #include 16 | 17 | /** Square x, n times. */ 18 | static DECAF_INLINE void gf_sqrn ( 19 | gf_s *__restrict__ y, 20 | const gf x, 21 | int n 22 | ) { 23 | gf tmp; 24 | assert(n>0); 25 | if (n&1) { 26 | gf_sqr(y,x); 27 | n--; 28 | } else { 29 | gf_sqr(tmp,x); 30 | gf_sqr(y,tmp); 31 | n-=2; 32 | } 33 | for (; n; n-=2) { 34 | gf_sqr(tmp,y); 35 | gf_sqr(y,tmp); 36 | } 37 | } 38 | 39 | #define gf_add_nr gf_add_RAW 40 | 41 | /** Subtract mod p. Bias by 2 and don't reduce */ 42 | static inline void gf_sub_nr ( gf c, const gf a, const gf b ) { 43 | gf_sub_RAW(c,a,b); 44 | gf_bias(c, 2); 45 | if (GF_HEADROOM < 3) gf_weak_reduce(c); 46 | } 47 | 48 | /** Subtract mod p. Bias by amt but don't reduce. */ 49 | static inline void gf_subx_nr ( gf c, const gf a, const gf b, int amt ) { 50 | gf_sub_RAW(c,a,b); 51 | gf_bias(c, amt); 52 | if (GF_HEADROOM < amt+1) gf_weak_reduce(c); 53 | } 54 | 55 | /** Mul by signed int. Not constant-time WRT the sign of that int. */ 56 | static inline void gf_mulw(gf c, const gf a, int32_t w) { 57 | if (w>0) { 58 | gf_mulw_unsigned(c, a, w); 59 | } else { 60 | gf_mulw_unsigned(c, a, -w); 61 | gf_sub(c,ZERO,c); 62 | } 63 | } 64 | 65 | /** Constant time, x = is_z ? z : y */ 66 | static inline void gf_cond_sel(gf x, const gf y, const gf z, mask_t is_z) { 67 | constant_time_select(x,y,z,sizeof(gf),is_z,0); 68 | } 69 | 70 | /** Constant time, if (neg) x=-x; */ 71 | static inline void gf_cond_neg(gf x, mask_t neg) { 72 | gf y; 73 | gf_sub(y,ZERO,x); 74 | gf_cond_sel(x,x,y,neg); 75 | } 76 | 77 | /** Constant time, if (swap) (x,y) = (y,x); */ 78 | static inline void 79 | gf_cond_swap(gf x, gf_s *__restrict__ y, mask_t swap) { 80 | constant_time_cond_swap(x,y,sizeof(gf_s),swap); 81 | } 82 | 83 | static DECAF_INLINE void gf_mul_qnr(gf_s *__restrict__ out, const gf x) { 84 | #if P_MOD_8 == 5 85 | /* r = QNR * r0^2 */ 86 | gf_mul(out,x,SQRT_MINUS_ONE); 87 | #elif P_MOD_8 == 3 || P_MOD_8 == 7 88 | gf_sub(out,ZERO,x); 89 | #else 90 | #error "Only supporting p=3,5,7 mod 8" 91 | #endif 92 | } 93 | 94 | static DECAF_INLINE void gf_div_qnr(gf_s *__restrict__ out, const gf x) { 95 | #if P_MOD_8 == 5 96 | /* r = QNR * r0^2 */ 97 | gf_mul(out,x,SQRT_MINUS_ONE); 98 | gf_sub(out,ZERO,out); 99 | #elif P_MOD_8 == 3 || P_MOD_8 == 7 100 | gf_sub(out,ZERO,x); 101 | #else 102 | #error "Only supporting p=3,5,7 mod 8" 103 | #endif 104 | } 105 | 106 | #if P_MOD_8 == 5 107 | #define gf_mul_i gf_mul_qnr 108 | #define gf_div_i gf_div_qnr 109 | #endif 110 | 111 | 112 | #endif // __GF_H__ 113 | -------------------------------------------------------------------------------- /c_deps/ed448goldilocks/src/include/keccak_internal.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @cond internal 3 | * @file keccak_internal.h 4 | * @copyright 5 | * Copyright (c) 2016 Cryptography Research, Inc. \n 6 | * Released under the MIT License. See LICENSE.txt for license information. 7 | * @author Mike Hamburg 8 | * @brief Keccak internal interfaces. Will be used by STROBE once reintegrated. 9 | */ 10 | #ifndef __DECAF_KECCAK_INTERNAL_H__ 11 | #define __DECAF_KECCAK_INTERNAL_H__ 1 12 | 13 | #include 14 | 15 | /* Aliasing MSVC preprocessing to GNU preprocessing */ 16 | #if defined _MSC_VER 17 | #define __attribute__(x) // Turn off attribute code 18 | #define __attribute(x) 19 | #define __restrict__ __restrict // Use MSVC restrict code 20 | #endif // MSVC 21 | 22 | /* The internal, non-opaque definition of the decaf_sponge struct. */ 23 | typedef union { 24 | uint64_t w[25]; uint8_t b[25*8]; 25 | } kdomain_t[1]; 26 | 27 | typedef struct decaf_kparams_s { 28 | uint8_t position, flags, rate, start_round, pad, rate_pad, max_out, remaining; 29 | } decaf_kparams_s, decaf_kparams_t[1]; 30 | 31 | typedef struct decaf_keccak_sponge_s { 32 | kdomain_t state; 33 | decaf_kparams_t params; 34 | } decaf_keccak_sponge_s, decaf_keccak_sponge_t[1]; 35 | 36 | #define INTERNAL_SPONGE_STRUCT 1 37 | 38 | void __attribute__((noinline)) keccakf(kdomain_t state, uint8_t start_round); 39 | 40 | static inline void dokeccak (decaf_keccak_sponge_t decaf_sponge) { 41 | keccakf(decaf_sponge->state, decaf_sponge->params->start_round); 42 | decaf_sponge->params->position = 0; 43 | } 44 | 45 | #endif /* __DECAF_KECCAK_INTERNAL_H__ */ 46 | -------------------------------------------------------------------------------- /c_deps/ed448goldilocks/src/include/portable_endian.h: -------------------------------------------------------------------------------- 1 | /* Subset of Mathias Panzenböck's portable endian code, public domain */ 2 | 3 | #ifndef __PORTABLE_ENDIAN_H__ 4 | #define __PORTABLE_ENDIAN_H__ 5 | 6 | #if defined(__linux__) || defined(__CYGWIN__) 7 | # include 8 | #elif defined(__OpenBSD__) 9 | # include 10 | #elif defined(__APPLE__) 11 | # include 12 | # define htole64(x) OSSwapHostToLittleInt64(x) 13 | # define le64toh(x) OSSwapLittleToHostInt64(x) 14 | #elif defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__) 15 | # include 16 | # ifndef le64toh 17 | # define le64toh(x) letoh64(x) 18 | # endif 19 | #elif defined(__sun) && defined(__SVR4) 20 | # include 21 | # define htole64(x) LE_64(x) 22 | # define le64toh(x) LE_64(x) 23 | #elif defined(_WIN16) || defined(_WIN32) || defined(_WIN64) || defined(__WINDOWS__) 24 | # if defined(_MSC_VER) 25 | # define __builtin_bswap64(x) _byteswap_uint64((x)) 26 | # else 27 | # include 28 | # endif 29 | # include 30 | # if BYTE_ORDER == LITTLE_ENDIAN 31 | # define htole64(x) (x) 32 | # define le64toh(x) (x) 33 | # elif BYTE_ORDER == BIG_ENDIAN 34 | # define htole64(x) __builtin_bswap64(x) 35 | # define le64toh(x) __builtin_bswap64(x) 36 | # else 37 | # error byte order not supported 38 | # endif 39 | #else 40 | # error platform not supported 41 | #endif 42 | 43 | #endif // __PORTABLE_ENDIAN_H__ 44 | -------------------------------------------------------------------------------- /c_deps/ed448goldilocks/src/p25519/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | ############################################################################ 2 | # CMakeLists.txt 3 | # 4 | # Released under the MIT License. See LICENSE.txt for license information. 5 | # 6 | ############################################################################ 7 | include_directories( 8 | ${PROJECT_SOURCE_DIR}/src/p25519 9 | ${GSOURCE_PATH}/c/p25519 10 | ${PROJECT_SOURCE_DIR}/src/p25519/${TARGET_ARCH_DIR_P25519} 11 | ) 12 | 13 | set(P25519_HEADER_FILES 14 | ${GSOURCE_PATH}/c/p25519/f_field.h 15 | ${TARGET_ARCH_DIR_P25519}/f_impl.h 16 | ) 17 | set(P25519_SOURCE_FILES_C 18 | ${TARGET_ARCH_DIR_P25519}/f_impl.c 19 | f_arithmetic.c 20 | ${GSOURCE_PATH}/c/p25519/f_generic.c 21 | ) 22 | 23 | SET_SOURCE_FILES_PROPERTIES(${GSOURCE_PATH}/c/p25519/f_field.h PROPERTIES GENERATED 1) 24 | SET_SOURCE_FILES_PROPERTIES(${GSOURCE_PATH}/c/p25519/f_generic.c PROPERTIES GENERATED 1) 25 | 26 | add_library(p25519 OBJECT ${P25519_HEADER_FILES} ${P25519_SOURCE_FILES_C}) 27 | add_dependencies(p25519 generatorP25519) 28 | 29 | set_target_properties(p25519 PROPERTIES POSITION_INDEPENDENT_CODE True) 30 | -------------------------------------------------------------------------------- /c_deps/ed448goldilocks/src/p25519/arch_32/f_impl.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2016 Cryptography Research, Inc. 2 | * Released under the MIT License. See LICENSE.txt for license information. 3 | */ 4 | 5 | #include "f_field.h" 6 | 7 | void gf_mul (gf_s *__restrict__ cs, const gf as, const gf bs) { 8 | const uint32_t *a = as->limb, *b = bs->limb, maske = ((1<<26)-1), masko = ((1<<25)-1); 9 | 10 | uint32_t bh[9]; 11 | int i,j; 12 | for (i=0; i<9; i++) bh[i] = b[i+1] * 19; 13 | 14 | uint32_t *c = cs->limb; 15 | 16 | uint64_t accum = 0; 17 | for (i=0; i<10; /*i+=2*/) { 18 | /* Even case. */ 19 | for (j=0; j>= 26; 31 | i++; 32 | 33 | /* Odd case is easier: all place values are exact. */ 34 | for (j=0; j<=i; j++) { 35 | accum += widemul(b[i-j], a[j]); 36 | } 37 | for (; j<10; j++) { 38 | accum += widemul(bh[i-j+9], a[j]); 39 | } 40 | c[i] = accum & masko; 41 | accum >>= 25; 42 | i++; 43 | } 44 | 45 | accum *= 19; 46 | accum += c[0]; 47 | c[0] = accum & maske; 48 | accum >>= 26; 49 | 50 | assert(accum < masko); 51 | c[1] += (uint32_t)accum; 52 | } 53 | 54 | void gf_mulw_unsigned (gf_s *__restrict__ cs, const gf as, uint32_t b) { 55 | const uint32_t *a = as->limb, maske = ((1<<26)-1), masko = ((1<<25)-1); 56 | uint32_t *c = cs->limb; 57 | uint64_t accum = widemul(b, a[0]); 58 | c[0] = accum & maske; 59 | accum >>= 26; 60 | 61 | accum += widemul(b, a[1]); 62 | c[1] = accum & masko; 63 | accum >>= 25; 64 | 65 | for (int i=2; i<10; /*i+=2*/) { 66 | accum += widemul(b, a[i]); 67 | c[i] = accum & maske; 68 | accum >>= 26; 69 | i++; 70 | 71 | accum += widemul(b, a[i]); 72 | c[i] = accum & masko; 73 | accum >>= 25; 74 | i++; 75 | } 76 | 77 | accum *= 19; 78 | accum += c[0]; 79 | c[0] = accum & maske; 80 | accum >>= 26; 81 | 82 | assert(accum < masko); 83 | c[1] += (uint32_t)accum; 84 | } 85 | 86 | void gf_sqr (gf_s *__restrict__ cs, const gf as) { 87 | gf_mul(cs,as,as); /* Performs better with dedicated square */ 88 | } 89 | 90 | 91 | -------------------------------------------------------------------------------- /c_deps/ed448goldilocks/src/p25519/arch_32/f_impl.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2014-2016 Cryptography Research, Inc. 2 | * Released under the MIT License. See LICENSE.txt for license information. 3 | */ 4 | 5 | #define GF_HEADROOM 3 /* Would be 5, but 3*19 * 2^26+small is all that fits in a uint32_t */ 6 | #define LIMB(x) (x##ull)&((1ull<<26)-1), (x##ull)>>26 7 | #define FIELD_LITERAL(a,b,c,d,e) {{LIMB(a),LIMB(b),LIMB(c),LIMB(d),LIMB(e)}} 8 | 9 | #define LIMB_PLACE_VALUE(i) (((i)&1)?25:26) 10 | 11 | void gf_add_RAW (gf out, const gf a, const gf b) { 12 | for (unsigned int i=0; i<10; i++) { 13 | out->limb[i] = a->limb[i] + b->limb[i]; 14 | } 15 | } 16 | 17 | void gf_sub_RAW (gf out, const gf a, const gf b) { 18 | for (unsigned int i=0; i<10; i++) { 19 | out->limb[i] = a->limb[i] - b->limb[i]; 20 | } 21 | } 22 | 23 | void gf_bias (gf a, int amt) { 24 | uint32_t coe = ((1ull<<26)-1)*amt, coo = ((1ull<<25)-1)*amt, co0 = coe-18*amt; 25 | for (unsigned int i=0; i<10; i+=2) { 26 | a->limb[i] += ((i==0) ? co0 : coe); 27 | a->limb[i+1] += coo; 28 | } 29 | } 30 | 31 | void gf_weak_reduce (gf a) { 32 | uint32_t maske = (1ull<<26) - 1, masko = (1ull<<25) - 1; 33 | uint32_t tmp = a->limb[9] >> 25; 34 | for (unsigned int i=8; i>0; i-=2) { 35 | a->limb[i+1] = (a->limb[i+1] & masko) + (a->limb[i]>>26); 36 | a->limb[i] = (a->limb[i] & maske) + (a->limb[i-1]>>25); 37 | } 38 | a->limb[1] = (a->limb[1] & masko) + (a->limb[0]>>26); 39 | a->limb[0] = (a->limb[0] & maske) + tmp*19; 40 | } 41 | 42 | -------------------------------------------------------------------------------- /c_deps/ed448goldilocks/src/p25519/arch_ref64/f_impl.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2014 Cryptography Research, Inc. 2 | * Released under the MIT License. See LICENSE.txt for license information. 3 | */ 4 | 5 | #include "f_field.h" 6 | 7 | void gf_mul (gf_s *__restrict__ cs, const gf as, const gf bs) { 8 | const uint64_t *a = as->limb, *b = bs->limb, mask = ((1ull<<51)-1); 9 | 10 | uint64_t bh[4]; 11 | int i,j; 12 | for (i=0; i<4; i++) bh[i] = b[i+1] * 19; 13 | 14 | uint64_t *c = cs->limb; 15 | 16 | __uint128_t accum = 0; 17 | for (i=0; i<5; i++) { 18 | for (j=0; j<=i; j++) { 19 | accum += widemul(b[i-j], a[j]); 20 | } 21 | for (; j<5; j++) { 22 | accum += widemul(bh[i-j+4], a[j]); 23 | } 24 | c[i] = accum & mask; 25 | accum >>= 51; 26 | } 27 | 28 | accum *= 19; 29 | accum += c[0]; 30 | c[0] = accum & mask; 31 | accum >>= 51; 32 | 33 | assert(accum < mask); 34 | c[1] += accum; 35 | } 36 | 37 | void gf_mulw_unsigned (gf_s *__restrict__ cs, const gf as, uint32_t b) { 38 | const uint64_t *a = as->limb, mask = ((1ull<<51)-1); 39 | int i; 40 | 41 | uint64_t *c = cs->limb; 42 | 43 | __uint128_t accum = 0; 44 | for (i=0; i<5; i++) { 45 | accum += widemul(b, a[i]); 46 | c[i] = accum & mask; 47 | accum >>= 51; 48 | } 49 | 50 | accum *= 19; 51 | accum += c[0]; 52 | c[0] = accum & mask; 53 | accum >>= 51; 54 | 55 | assert(accum < mask); 56 | c[1] += accum; 57 | } 58 | 59 | void gf_sqr (gf_s *__restrict__ cs, const gf as) { 60 | gf_mul(cs,as,as); /* Performs better with dedicated square */ 61 | } 62 | -------------------------------------------------------------------------------- /c_deps/ed448goldilocks/src/p25519/arch_ref64/f_impl.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2014-2016 Cryptography Research, Inc. 2 | * Released under the MIT License. See LICENSE.txt for license information. 3 | */ 4 | 5 | #define GF_HEADROOM 9999 /* Always reduced */ 6 | #define FIELD_LITERAL(a,b,c,d,e) {{ a,b,c,d,e }} 7 | 8 | #define LIMB_PLACE_VALUE(i) 51 9 | 10 | void gf_add_RAW (gf out, const gf a, const gf b) { 11 | for (unsigned int i=0; i<5; i++) { 12 | out->limb[i] = a->limb[i] + b->limb[i]; 13 | } 14 | gf_weak_reduce(out); 15 | } 16 | 17 | void gf_sub_RAW (gf out, const gf a, const gf b) { 18 | uint64_t co1 = ((1ull<<51)-1)*2, co2 = co1-36; 19 | for (unsigned int i=0; i<5; i++) { 20 | out->limb[i] = a->limb[i] - b->limb[i] + ((i==0) ? co2 : co1); 21 | } 22 | gf_weak_reduce(out); 23 | } 24 | 25 | void gf_bias (gf a, int amt) { 26 | (void) a; 27 | (void) amt; 28 | } 29 | 30 | void gf_weak_reduce (gf a) { 31 | uint64_t mask = (1ull<<51) - 1; 32 | uint64_t tmp = a->limb[4] >> 51; 33 | for (unsigned int i=4; i>0; i--) { 34 | a->limb[i] = (a->limb[i] & mask) + (a->limb[i-1]>>51); 35 | } 36 | a->limb[0] = (a->limb[0] & mask) + tmp*19; 37 | } 38 | 39 | -------------------------------------------------------------------------------- /c_deps/ed448goldilocks/src/p25519/arch_x86_64/f_impl.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2014 Cryptography Research, Inc. 2 | * Released under the MIT License. See LICENSE.txt for license information. 3 | */ 4 | 5 | #include "f_field.h" 6 | 7 | /** Requires: input limbs < 9*2^51 */ 8 | void gf_mul (gf_s *__restrict__ cs, const gf as, const gf bs) { 9 | const uint64_t *a = as->limb, *b = bs->limb, mask = ((1ull<<51)-1); 10 | uint64_t *c = cs->limb; 11 | 12 | __uint128_t accum0, accum1, accum2; 13 | 14 | uint64_t ai = a[0]; 15 | accum0 = widemul_rm(ai, &b[0]); 16 | accum1 = widemul_rm(ai, &b[1]); 17 | accum2 = widemul_rm(ai, &b[2]); 18 | 19 | ai = a[1]; 20 | mac_rm(&accum2, ai, &b[1]); 21 | mac_rm(&accum1, ai, &b[0]); 22 | ai *= 19; 23 | mac_rm(&accum0, ai, &b[4]); 24 | 25 | ai = a[2]; 26 | mac_rm(&accum2, ai, &b[0]); 27 | ai *= 19; 28 | mac_rm(&accum0, ai, &b[3]); 29 | mac_rm(&accum1, ai, &b[4]); 30 | 31 | ai = a[3] * 19; 32 | mac_rm(&accum0, ai, &b[2]); 33 | mac_rm(&accum1, ai, &b[3]); 34 | mac_rm(&accum2, ai, &b[4]); 35 | 36 | ai = a[4] * 19; 37 | mac_rm(&accum0, ai, &b[1]); 38 | mac_rm(&accum1, ai, &b[2]); 39 | mac_rm(&accum2, ai, &b[3]); 40 | 41 | uint64_t c0 = accum0 & mask; 42 | accum1 += shrld(accum0, 51); 43 | uint64_t c1 = accum1 & mask; 44 | accum2 += shrld(accum1, 51); 45 | c[2] = accum2 & mask; 46 | 47 | accum0 = shrld(accum2, 51); 48 | 49 | mac_rm(&accum0, ai, &b[4]); 50 | 51 | ai = a[0]; 52 | mac_rm(&accum0, ai, &b[3]); 53 | accum1 = widemul_rm(ai, &b[4]); 54 | 55 | ai = a[1]; 56 | mac_rm(&accum0, ai, &b[2]); 57 | mac_rm(&accum1, ai, &b[3]); 58 | 59 | ai = a[2]; 60 | mac_rm(&accum0, ai, &b[1]); 61 | mac_rm(&accum1, ai, &b[2]); 62 | 63 | ai = a[3]; 64 | mac_rm(&accum0, ai, &b[0]); 65 | mac_rm(&accum1, ai, &b[1]); 66 | 67 | ai = a[4]; 68 | mac_rm(&accum1, ai, &b[0]); 69 | /* Here accum1 < 5*(9*2^51)^2 */ 70 | 71 | c[3] = accum0 & mask; 72 | accum1 += shrld(accum0, 51); 73 | c[4] = accum1 & mask; 74 | 75 | uint64_t a1 = shrld(accum1,51); 76 | /* Here a1 < (5*(9*2^51)^2 + small) >> 51 = 405 * 2^51 + small 77 | * a1 * 19 + c0 < (405*19+1)*2^51 + small < 2^13 * 2^51. 78 | */ 79 | accum1 = a1 * 19 + c0; 80 | c[0] = accum1 & mask; 81 | c[1] = c1 + (accum1>>51); 82 | } 83 | 84 | void gf_sqr (gf_s *__restrict__ cs, const gf as) { 85 | const uint64_t *a = as->limb, mask = ((1ull<<51)-1); 86 | uint64_t *c = cs->limb; 87 | 88 | __uint128_t accum0, accum1, accum2; 89 | 90 | uint64_t ai = a[0]; 91 | accum0 = widemul_rr(ai, ai); 92 | ai *= 2; 93 | accum1 = widemul_rm(ai, &a[1]); 94 | accum2 = widemul_rm(ai, &a[2]); 95 | 96 | ai = a[1]; 97 | mac_rr(&accum2, ai, ai); 98 | ai *= 38; 99 | mac_rm(&accum0, ai, &a[4]); 100 | 101 | ai = a[2] * 38; 102 | mac_rm(&accum0, ai, &a[3]); 103 | mac_rm(&accum1, ai, &a[4]); 104 | 105 | ai = a[3] * 19; 106 | mac_rm(&accum1, ai, &a[3]); 107 | ai *= 2; 108 | mac_rm(&accum2, ai, &a[4]); 109 | 110 | uint64_t c0 = accum0 & mask; 111 | accum1 += shrld(accum0, 51); 112 | uint64_t c1 = accum1 & mask; 113 | accum2 += shrld(accum1, 51); 114 | c[2] = accum2 & mask; 115 | 116 | accum0 = accum2 >> 51; 117 | 118 | ai = a[0]*2; 119 | mac_rm(&accum0, ai, &a[3]); 120 | accum1 = widemul_rm(ai, &a[4]); 121 | 122 | ai = a[1]*2; 123 | mac_rm(&accum0, ai, &a[2]); 124 | mac_rm(&accum1, ai, &a[3]); 125 | 126 | mac_rr(&accum0, a[4]*19, a[4]); 127 | mac_rr(&accum1, a[2], a[2]); 128 | 129 | c[3] = accum0 & mask; 130 | accum1 += shrld(accum0, 51); 131 | c[4] = accum1 & mask; 132 | 133 | /* 2^102 * 16 * 5 * 19 * (1+ep) >> 64 134 | * = 2^(-13 + <13) 135 | */ 136 | 137 | uint64_t a1 = shrld(accum1,51); 138 | accum1 = a1 * 19 + c0; 139 | c[0] = accum1 & mask; 140 | c[1] = c1 + (accum1>>51); 141 | } 142 | 143 | void gf_mulw_unsigned (gf_s *__restrict__ cs, const gf as, uint32_t b) { 144 | const uint64_t *a = as->limb, mask = ((1ull<<51)-1); 145 | uint64_t *c = cs->limb; 146 | 147 | __uint128_t accum = widemul_rm(b, &a[0]); 148 | uint64_t c0 = accum & mask; 149 | accum = shrld(accum,51); 150 | 151 | mac_rm(&accum, b, &a[1]); 152 | uint64_t c1 = accum & mask; 153 | accum = shrld(accum,51); 154 | 155 | mac_rm(&accum, b, &a[2]); 156 | c[2] = accum & mask; 157 | accum = shrld(accum,51); 158 | 159 | mac_rm(&accum, b, &a[3]); 160 | c[3] = accum & mask; 161 | accum = shrld(accum,51); 162 | 163 | mac_rm(&accum, b, &a[4]); 164 | c[4] = accum & mask; 165 | 166 | uint64_t a1 = shrld(accum,51); 167 | a1 = a1*19+c0; 168 | 169 | c[0] = a1 & mask; 170 | c[1] = c1 + (a1>>51); 171 | } 172 | -------------------------------------------------------------------------------- /c_deps/ed448goldilocks/src/p25519/arch_x86_64/f_impl.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2014-2016 Cryptography Research, Inc. 2 | * Released under the MIT License. See LICENSE.txt for license information. 3 | */ 4 | 5 | #define GF_HEADROOM 933 6 | #define FIELD_LITERAL(a,b,c,d,e) {{ a,b,c,d,e }} 7 | 8 | #define LIMB_PLACE_VALUE(i) 51 9 | 10 | void gf_add_RAW (gf out, const gf a, const gf b) { 11 | for (unsigned int i=0; i<5; i++) { 12 | out->limb[i] = a->limb[i] + b->limb[i]; 13 | } 14 | } 15 | 16 | void gf_sub_RAW (gf out, const gf a, const gf b) { 17 | for (unsigned int i=0; i<5; i++) { 18 | out->limb[i] = a->limb[i] - b->limb[i]; 19 | } 20 | } 21 | 22 | void gf_bias (gf a, int amt) { 23 | a->limb[0] += ((uint64_t)(amt)<<52) - 38*amt; 24 | for (unsigned int i=1; i<5; i++) { 25 | a->limb[i] += ((uint64_t)(amt)<<52)-2*amt; 26 | } 27 | } 28 | 29 | void gf_weak_reduce (gf a) { 30 | uint64_t mask = (1ull<<51) - 1; 31 | uint64_t tmp = a->limb[4] >> 51; 32 | for (unsigned int i=4; i>0; i--) { 33 | a->limb[i] = (a->limb[i] & mask) + (a->limb[i-1]>>51); 34 | } 35 | a->limb[0] = (a->limb[0] & mask) + tmp*19; 36 | } 37 | -------------------------------------------------------------------------------- /c_deps/ed448goldilocks/src/p25519/f_arithmetic.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @cond internal 3 | * @file f_arithmetic.c 4 | * @copyright 5 | * Copyright (c) 2014 Cryptography Research, Inc. \n 6 | * Released under the MIT License. See LICENSE.txt for license information. 7 | * @author Mike Hamburg 8 | * @brief Field-specific arithmetic. 9 | */ 10 | 11 | #include "field.h" 12 | #include "constant_time.h" 13 | 14 | /* Guarantee: a^2 x = 0 if x = 0; else a^2 x = 1 or SQRT_MINUS_ONE; */ 15 | mask_t gf_isr (gf a, const gf x) { 16 | gf L0, L1, L2, L3; 17 | 18 | gf_sqr (L0, x); 19 | gf_mul (L1, L0, x); 20 | gf_sqr (L0, L1); 21 | gf_mul (L1, L0, x); 22 | gf_sqrn(L0, L1, 3); 23 | gf_mul (L2, L0, L1); 24 | gf_sqrn(L0, L2, 6); 25 | gf_mul (L1, L2, L0); 26 | gf_sqr (L2, L1); 27 | gf_mul (L0, L2, x); 28 | gf_sqrn(L2, L0, 12); 29 | gf_mul (L0, L2, L1); 30 | gf_sqrn(L2, L0, 25); 31 | gf_mul (L3, L2, L0); 32 | gf_sqrn(L2, L3, 25); 33 | gf_mul (L1, L2, L0); 34 | gf_sqrn(L2, L1, 50); 35 | gf_mul (L0, L2, L3); 36 | gf_sqrn(L2, L0, 125); 37 | gf_mul (L3, L2, L0); 38 | gf_sqrn(L2, L3, 2); 39 | gf_mul (L0, L2, x); 40 | 41 | gf_sqr (L2, L0); 42 | gf_mul (L3, L2, x); 43 | gf_add(L1,L3,ONE); 44 | mask_t one = gf_eq(L3,ONE); 45 | mask_t succ = one | gf_eq(L1,ZERO); 46 | mask_t qr = one | gf_eq(L3,SQRT_MINUS_ONE); 47 | 48 | constant_time_select(L2, SQRT_MINUS_ONE, ONE, sizeof(L2), qr, 0); 49 | gf_mul (a,L2,L0); 50 | return succ; 51 | } 52 | -------------------------------------------------------------------------------- /c_deps/ed448goldilocks/src/p448/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | ############################################################################ 2 | # CMakeLists.txt 3 | # 4 | # Released under the MIT License. See LICENSE.txt for license information. 5 | # 6 | ############################################################################ 7 | include_directories( 8 | ${PROJECT_SOURCE_DIR}/src/p448 9 | ${GSOURCE_PATH}/c/p448 10 | ${PROJECT_SOURCE_DIR}/src/p448/${TARGET_ARCH_DIR_P448} 11 | ) 12 | 13 | set(P448_HEADER_FILES 14 | ${GSOURCE_PATH}/c/p448/f_field.h 15 | ${TARGET_ARCH_DIR_P448}/f_impl.h 16 | ) 17 | set(P448_SOURCE_FILES_C 18 | ${TARGET_ARCH_DIR_P448}/f_impl.c 19 | f_arithmetic.c 20 | ${GSOURCE_PATH}/c/p448/f_generic.c 21 | ) 22 | 23 | SET_SOURCE_FILES_PROPERTIES(${GSOURCE_PATH}/c/p448/f_field.h PROPERTIES GENERATED 1) 24 | SET_SOURCE_FILES_PROPERTIES(${GSOURCE_PATH}/c/p448/f_generic.c PROPERTIES GENERATED 1) 25 | 26 | add_library(p448 OBJECT ${P448_HEADER_FILES} ${P448_SOURCE_FILES_C}) 27 | add_dependencies(p448 generatorP448) 28 | 29 | set_target_properties(p448 PROPERTIES POSITION_INDEPENDENT_CODE True) 30 | -------------------------------------------------------------------------------- /c_deps/ed448goldilocks/src/p448/arch_32/f_impl.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2014 Cryptography Research, Inc. 2 | * Released under the MIT License. See LICENSE.txt for license information. 3 | */ 4 | 5 | #include "f_field.h" 6 | 7 | #if (defined(__OPTIMIZE__) && !defined(__OPTIMIZE_SIZE__) && !I_HATE_UNROLLED_LOOPS) \ 8 | || defined(DECAF_FORCE_UNROLL) 9 | #define REPEAT8(_x) _x _x _x _x _x _x _x _x 10 | #define FOR_LIMB(_i,_start,_end,_x) do { _i=_start; REPEAT8( if (_i<_end) { _x; } _i++;) } while (0) 11 | #else 12 | #define FOR_LIMB(_i,_start,_end,_x) do { for (_i=_start; _i<_end; _i++) _x; } while (0) 13 | #endif 14 | 15 | void gf_mul (gf_s *__restrict__ cs, const gf as, const gf bs) { 16 | const uint32_t *a = as->limb, *b = bs->limb; 17 | uint32_t *c = cs->limb; 18 | 19 | uint64_t accum0 = 0, accum1 = 0, accum2 = 0; 20 | uint32_t mask = (1<<28) - 1; 21 | 22 | uint32_t aa[8], bb[8]; 23 | 24 | int i,j; 25 | for (i=0; i<8; i++) { 26 | aa[i] = a[i] + a[i+8]; 27 | bb[i] = b[i] + b[i+8]; 28 | } 29 | 30 | FOR_LIMB(j,0,8,{ 31 | accum2 = 0; 32 | 33 | FOR_LIMB (i,0,j+1,{ 34 | accum2 += widemul(a[j-i],b[i]); 35 | accum1 += widemul(aa[j-i],bb[i]); 36 | accum0 += widemul(a[8+j-i], b[8+i]); 37 | }); 38 | 39 | accum1 -= accum2; 40 | accum0 += accum2; 41 | accum2 = 0; 42 | 43 | FOR_LIMB (i,j+1,8,{ 44 | accum0 -= widemul(a[8+j-i], b[i]); 45 | accum2 += widemul(aa[8+j-i], bb[i]); 46 | accum1 += widemul(a[16+j-i], b[8+i]); 47 | }); 48 | 49 | accum1 += accum2; 50 | accum0 += accum2; 51 | 52 | c[j] = ((uint32_t)(accum0)) & mask; 53 | c[j+8] = ((uint32_t)(accum1)) & mask; 54 | 55 | accum0 >>= 28; 56 | accum1 >>= 28; 57 | }); 58 | 59 | accum0 += accum1; 60 | accum0 += c[8]; 61 | accum1 += c[0]; 62 | c[8] = ((uint32_t)(accum0)) & mask; 63 | c[0] = ((uint32_t)(accum1)) & mask; 64 | 65 | accum0 >>= 28; 66 | accum1 >>= 28; 67 | c[9] += ((uint32_t)(accum0)); 68 | c[1] += ((uint32_t)(accum1)); 69 | } 70 | 71 | void gf_mulw_unsigned (gf_s *__restrict__ cs, const gf as, uint32_t b) { 72 | assert(b<1<<28); 73 | 74 | const uint32_t *a = as->limb; 75 | uint32_t *c = cs->limb; 76 | 77 | uint64_t accum0 = 0, accum8 = 0; 78 | uint32_t mask = (1ull<<28)-1; 79 | 80 | int i; 81 | FOR_LIMB(i,0,8,{ 82 | accum0 += widemul(b, a[i]); 83 | accum8 += widemul(b, a[i+8]); 84 | 85 | c[i] = accum0 & mask; accum0 >>= 28; 86 | c[i+8] = accum8 & mask; accum8 >>= 28; 87 | }); 88 | 89 | accum0 += accum8 + c[8]; 90 | c[8] = accum0 & mask; 91 | c[9] += (uint32_t)(accum0 >> 28); 92 | 93 | accum8 += c[0]; 94 | c[0] = accum8 & mask; 95 | c[1] += (uint32_t)(accum8 >> 28); 96 | } 97 | 98 | void gf_sqr (gf_s *__restrict__ cs, const gf as) { 99 | gf_mul(cs,as,as); /* Performs better with a dedicated square */ 100 | } 101 | 102 | -------------------------------------------------------------------------------- /c_deps/ed448goldilocks/src/p448/arch_32/f_impl.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2014-2016 Cryptography Research, Inc. 2 | * Released under the MIT License. See LICENSE.txt for license information. 3 | */ 4 | 5 | #define GF_HEADROOM 2 6 | #define LIMB(x) (x##ull)&((1ull<<28)-1), (x##ull)>>28 7 | #define FIELD_LITERAL(a,b,c,d,e,f,g,h) \ 8 | {{LIMB(a),LIMB(b),LIMB(c),LIMB(d),LIMB(e),LIMB(f),LIMB(g),LIMB(h)}} 9 | 10 | #define LIMB_PLACE_VALUE(i) 28 11 | 12 | void gf_add_RAW (gf out, const gf a, const gf b) { 13 | for (unsigned int i=0; ilimb[0]); i++) { 14 | out->limb[i] = a->limb[i] + b->limb[i]; 15 | } 16 | } 17 | 18 | void gf_sub_RAW (gf out, const gf a, const gf b) { 19 | for (unsigned int i=0; ilimb[0]); i++) { 20 | out->limb[i] = a->limb[i] - b->limb[i]; 21 | } 22 | } 23 | 24 | void gf_bias (gf a, int amt) { 25 | uint32_t co1 = ((1ull<<28)-1)*amt, co2 = co1-amt; 26 | for (unsigned int i=0; ilimb[0]); i++) { 27 | a->limb[i] += (i==sizeof(*a)/sizeof(a->limb[0])/2) ? co2 : co1; 28 | } 29 | } 30 | 31 | void gf_weak_reduce (gf a) { 32 | uint32_t mask = (1ull<<28) - 1; 33 | uint32_t tmp = a->limb[15] >> 28; 34 | a->limb[8] += tmp; 35 | for (unsigned int i=15; i>0; i--) { 36 | a->limb[i] = (a->limb[i] & mask) + (a->limb[i-1]>>28); 37 | } 38 | a->limb[0] = (a->limb[0] & mask) + tmp; 39 | } 40 | 41 | -------------------------------------------------------------------------------- /c_deps/ed448goldilocks/src/p448/arch_arm_32/f_impl.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2014-2016 Cryptography Research, Inc. 2 | * Released under the MIT License. See LICENSE.txt for license information. 3 | */ 4 | 5 | #define GF_HEADROOM 2 6 | #define LIMB(x) (x##ull)&((1ull<<28)-1), (x##ull)>>28 7 | #define FIELD_LITERAL(a,b,c,d,e,f,g,h) \ 8 | {{LIMB(a),LIMB(b),LIMB(c),LIMB(d),LIMB(e),LIMB(f),LIMB(g),LIMB(h)}} 9 | 10 | #define LIMB_PLACE_VALUE(i) 28 11 | 12 | void gf_add_RAW (gf out, const gf a, const gf b) { 13 | for (unsigned int i=0; ilimb[0]); i++) { 18 | out->limb[i] = a->limb[i] + b->limb[i]; 19 | } 20 | */ 21 | } 22 | 23 | void gf_sub_RAW (gf out, const gf a, const gf b) { 24 | for (unsigned int i=0; ilimb[0]); i++) { 29 | out->limb[i] = a->limb[i] - b->limb[i]; 30 | } 31 | */ 32 | } 33 | 34 | void gf_bias (gf a, int amt) { 35 | uint32_t co1 = ((1ull<<28)-1)*amt, co2 = co1-amt; 36 | uint32x4_t lo = {co1,co1,co1,co1}, hi = {co2,co1,co1,co1}; 37 | uint32x4_t *aa = (uint32x4_t*) a; 38 | aa[0] += lo; 39 | aa[1] += lo; 40 | aa[2] += hi; 41 | aa[3] += lo; 42 | } 43 | 44 | void gf_weak_reduce (gf a) { 45 | uint64_t mask = (1ull<<28) - 1; 46 | uint64_t tmp = a->limb[15] >> 28; 47 | a->limb[8] += tmp; 48 | for (unsigned int i=15; i>0; i--) { 49 | a->limb[i] = (a->limb[i] & mask) + (a->limb[i-1]>>28); 50 | } 51 | a->limb[0] = (a->limb[0] & mask) + tmp; 52 | } 53 | 54 | -------------------------------------------------------------------------------- /c_deps/ed448goldilocks/src/p448/arch_neon/f_impl.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2014-2016 Cryptography Research, Inc. 2 | * Released under the MIT License. See LICENSE.txt for license information. 3 | */ 4 | 5 | #define GF_HEADROOM 2 6 | #define LIMBPERM(x) (((x)<<1 | (x)>>3) & 15) 7 | #define USE_NEON_PERM 1 8 | #define LIMBHI(x) ((x##ull)>>28) 9 | #define LIMBLO(x) ((x##ull)&((1ull<<28)-1)) 10 | # define FIELD_LITERAL(a,b,c,d,e,f,g,h) \ 11 | {{LIMBLO(a),LIMBLO(e), LIMBHI(a),LIMBHI(e), \ 12 | LIMBLO(b),LIMBLO(f), LIMBHI(b),LIMBHI(f), \ 13 | LIMBLO(c),LIMBLO(g), LIMBHI(c),LIMBHI(g), \ 14 | LIMBLO(d),LIMBLO(h), LIMBHI(d),LIMBHI(h)}} 15 | 16 | #define LIMB_PLACE_VALUE(i) 28 17 | 18 | void gf_add_RAW (gf out, const gf a, const gf b) { 19 | for (unsigned int i=0; ilimb[0]); i++) { 31 | out->limb[i] = a->limb[i] - b->limb[i]; 32 | } 33 | */ 34 | } 35 | 36 | void gf_bias (gf a, int amt) { 37 | uint32_t co1 = ((1ull<<28)-1)*amt, co2 = co1-amt; 38 | uint32x4_t lo = {co1,co2,co1,co1}, hi = {co1,co1,co1,co1}; 39 | uint32x4_t *aa = (uint32x4_t*) a; 40 | aa[0] += lo; 41 | aa[1] += hi; 42 | aa[2] += hi; 43 | aa[3] += hi; 44 | } 45 | 46 | void gf_weak_reduce (gf a) { 47 | 48 | uint32x2_t *aa = (uint32x2_t*) a, vmask = {(1ull<<28)-1, (1ull<<28)-1}, vm2 = {0,-1}, 49 | tmp = vshr_n_u32(aa[7],28); 50 | 51 | for (unsigned int i=7; i>=1; i--) { 52 | aa[i] = vsra_n_u32(aa[i] & vmask, aa[i-1], 28); 53 | } 54 | aa[0] = (aa[0] & vmask) + vrev64_u32(tmp) + (tmp&vm2); 55 | } 56 | 57 | -------------------------------------------------------------------------------- /c_deps/ed448goldilocks/src/p448/arch_ref64/f_impl.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2014-2016 Cryptography Research, Inc. 2 | * Released under the MIT License. See LICENSE.txt for license information. 3 | */ 4 | 5 | #define GF_HEADROOM 9999 /* Everything is reduced anyway */ 6 | #define FIELD_LITERAL(a,b,c,d,e,f,g,h) {{a,b,c,d,e,f,g,h}} 7 | 8 | #define LIMB_PLACE_VALUE(i) 56 9 | 10 | void gf_add_RAW (gf out, const gf a, const gf b) { 11 | for (unsigned int i=0; i<8; i++) { 12 | out->limb[i] = a->limb[i] + b->limb[i]; 13 | } 14 | gf_weak_reduce(out); 15 | } 16 | 17 | void gf_sub_RAW (gf out, const gf a, const gf b) { 18 | uint64_t co1 = ((1ull<<56)-1)*2, co2 = co1-2; 19 | for (unsigned int i=0; i<8; i++) { 20 | out->limb[i] = a->limb[i] - b->limb[i] + ((i==4) ? co2 : co1); 21 | } 22 | gf_weak_reduce(out); 23 | } 24 | 25 | void gf_bias (gf a, int amt) { 26 | (void) a; 27 | (void) amt; 28 | } 29 | 30 | void gf_weak_reduce (gf a) { 31 | uint64_t mask = (1ull<<56) - 1; 32 | uint64_t tmp = a->limb[7] >> 56; 33 | a->limb[4] += tmp; 34 | for (unsigned int i=7; i>0; i--) { 35 | a->limb[i] = (a->limb[i] & mask) + (a->limb[i-1]>>56); 36 | } 37 | a->limb[0] = (a->limb[0] & mask) + tmp; 38 | } 39 | -------------------------------------------------------------------------------- /c_deps/ed448goldilocks/src/p448/arch_x86_64/f_impl.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2014-2016 Cryptography Research, Inc. 2 | * Released under the MIT License. See LICENSE.txt for license information. 3 | */ 4 | 5 | #define GF_HEADROOM 60 6 | #define FIELD_LITERAL(a,b,c,d,e,f,g,h) {{a,b,c,d,e,f,g,h}} 7 | #define LIMB_PLACE_VALUE(i) 56 8 | 9 | void gf_add_RAW (gf out, const gf a, const gf b) { 10 | for (unsigned int i=0; ilimb[0]); i++) { 16 | out->limb[i] = a->limb[i] + b->limb[i]; 17 | } 18 | */ 19 | } 20 | 21 | void gf_sub_RAW (gf out, const gf a, const gf b) { 22 | for (unsigned int i=0; ilimb[0]); i++) { 28 | out->limb[i] = a->limb[i] - b->limb[i]; 29 | } 30 | */ 31 | } 32 | 33 | void gf_bias (gf a, int amt) { 34 | uint64_t co1 = ((1ull<<56)-1)*amt, co2 = co1-amt; 35 | 36 | #if __AVX2__ 37 | uint64x4_t lo = {co1,co1,co1,co1}, hi = {co2,co1,co1,co1}; 38 | uint64x4_t *aa = (uint64x4_t*) a; 39 | aa[0] += lo; 40 | aa[1] += hi; 41 | #elif __SSE2__ 42 | uint64x2_t lo = {co1,co1}, hi = {co2,co1}; 43 | uint64x2_t *aa = (uint64x2_t*) a; 44 | aa[0] += lo; 45 | aa[1] += lo; 46 | aa[2] += hi; 47 | aa[3] += lo; 48 | #else 49 | for (unsigned int i=0; ilimb[i] += (i==4) ? co2 : co1; 51 | } 52 | #endif 53 | } 54 | 55 | void gf_weak_reduce (gf a) { 56 | /* PERF: use pshufb/palignr if anyone cares about speed of this */ 57 | uint64_t mask = (1ull<<56) - 1; 58 | uint64_t tmp = a->limb[7] >> 56; 59 | a->limb[4] += tmp; 60 | for (unsigned int i=7; i>0; i--) { 61 | a->limb[i] = (a->limb[i] & mask) + (a->limb[i-1]>>56); 62 | } 63 | a->limb[0] = (a->limb[0] & mask) + tmp; 64 | } 65 | 66 | -------------------------------------------------------------------------------- /c_deps/ed448goldilocks/src/p448/f_arithmetic.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @cond internal 3 | * @file f_arithmetic.c 4 | * @copyright 5 | * Copyright (c) 2014 Cryptography Research, Inc. \n 6 | * Released under the MIT License. See LICENSE.txt for license information. 7 | * @author Mike Hamburg 8 | * @brief Field-specific arithmetic. 9 | */ 10 | 11 | #include "field.h" 12 | 13 | mask_t gf_isr ( 14 | gf a, 15 | const gf x 16 | ) { 17 | gf L0, L1, L2; 18 | gf_sqr (L1, x ); 19 | gf_mul (L2, x, L1 ); 20 | gf_sqr (L1, L2 ); 21 | gf_mul (L2, x, L1 ); 22 | gf_sqrn (L1, L2, 3 ); 23 | gf_mul (L0, L2, L1 ); 24 | gf_sqrn (L1, L0, 3 ); 25 | gf_mul (L0, L2, L1 ); 26 | gf_sqrn (L2, L0, 9 ); 27 | gf_mul (L1, L0, L2 ); 28 | gf_sqr (L0, L1 ); 29 | gf_mul (L2, x, L0 ); 30 | gf_sqrn (L0, L2, 18 ); 31 | gf_mul (L2, L1, L0 ); 32 | gf_sqrn (L0, L2, 37 ); 33 | gf_mul (L1, L2, L0 ); 34 | gf_sqrn (L0, L1, 37 ); 35 | gf_mul (L1, L2, L0 ); 36 | gf_sqrn (L0, L1, 111 ); 37 | gf_mul (L2, L1, L0 ); 38 | gf_sqr (L0, L2 ); 39 | gf_mul (L1, x, L0 ); 40 | gf_sqrn (L0, L1, 223 ); 41 | gf_mul (L1, L2, L0 ); 42 | gf_sqr (L2, L1); 43 | gf_mul (L0, L2, x); 44 | gf_copy(a,L1); 45 | return gf_eq(L0,ONE); 46 | } 47 | -------------------------------------------------------------------------------- /c_deps/ed448goldilocks/src/per_curve/decaf_gen_tables.tmpl.c: -------------------------------------------------------------------------------- 1 | /** @brief Decaf global constant table precomputation. */ 2 | 3 | #define _XOPEN_SOURCE 600 /* for posix_memalign */ 4 | #include 5 | #include 6 | 7 | #include "field.h" 8 | #include "f_field.h" 9 | #include "decaf.h" 10 | 11 | #define API_NS(_id) $(c_ns)_##_id 12 | static const unsigned char base_point_ser_for_pregen[SER_BYTES] = { 13 | $(ser(rist_base_decoded,8)) 14 | }; 15 | 16 | /* To satisfy linker. */ 17 | const gf API_NS(precomputed_base_as_fe)[1]; 18 | const API_NS(point_t) API_NS(point_base); 19 | 20 | struct niels_s; 21 | const gf_s *API_NS(precomputed_wnaf_as_fe); 22 | extern const size_t API_NS(sizeof_precomputed_wnafs); 23 | 24 | void API_NS(precompute_wnafs) ( 25 | struct niels_s *out, 26 | const API_NS(point_t) base 27 | ); 28 | static void field_print(const gf f) { 29 | unsigned char ser[SER_BYTES]; 30 | gf_serialize(ser,f); 31 | int b=0, i, comma=0; 32 | unsigned long long limb = 0; 33 | printf("{FIELD_LITERAL("); 34 | for (i=0; i= GF_LIT_LIMB_BITS || i == SER_BYTES-1) { 38 | limb &= (1ull<>(8-b); 44 | } 45 | } 46 | printf(")}"); 47 | assert(b<8); 48 | } 49 | 50 | int main(int argc, char **argv) { 51 | (void)argc; (void)argv; 52 | 53 | API_NS(point_t) real_point_base; 54 | int ret = API_NS(point_decode)(real_point_base,base_point_ser_for_pregen,0); 55 | if (ret != DECAF_SUCCESS) { 56 | fprintf(stderr, "Can't decode base point!\n"); 57 | return 1; 58 | } 59 | 60 | API_NS(precomputed_s) *pre; 61 | ret = posix_memalign((void**)&pre, API_NS(alignof_precomputed_s), API_NS(sizeof_precomputed_s)); 62 | if (ret || !pre) { 63 | fprintf(stderr, "Can't allocate space for precomputed table\n"); 64 | return 1; 65 | } 66 | API_NS(precompute)(pre, real_point_base); 67 | 68 | struct niels_s *pre_wnaf; 69 | ret = posix_memalign((void**)&pre_wnaf, API_NS(alignof_precomputed_s), API_NS(sizeof_precomputed_wnafs)); 70 | if (ret || !pre_wnaf) { 71 | fprintf(stderr, "Can't allocate space for precomputed WNAF table\n"); 72 | return 1; 73 | } 74 | API_NS(precompute_wnafs)(pre_wnaf, real_point_base); 75 | 76 | const gf_s *output; 77 | unsigned i; 78 | 79 | printf("/** @warning: this file was automatically generated. */\n"); 80 | printf("#include \"field.h\"\n\n"); 81 | printf("#include \n\n"); 82 | printf("#define API_NS(_id) $(c_ns)_##_id\n"); 83 | 84 | output = (const gf_s *)real_point_base; 85 | printf("const API_NS(point_t) API_NS(point_base) = {{\n"); 86 | for (i=0; i < sizeof(API_NS(point_t)); i+=sizeof(gf)) { 87 | if (i) printf(",\n "); 88 | field_print(output++); 89 | } 90 | printf("\n}};\n"); 91 | 92 | output = (const gf_s *)pre; 93 | printf("const gf API_NS(precomputed_base_as_fe)[%d]\n", 94 | (int)(API_NS(sizeof_precomputed_s) / sizeof(gf))); 95 | printf("VECTOR_ALIGNED __attribute__((visibility(\"hidden\"))) = {\n "); 96 | 97 | for (i=0; i < API_NS(sizeof_precomputed_s); i+=sizeof(gf)) { 98 | if (i) printf(",\n "); 99 | field_print(output++); 100 | } 101 | printf("\n};\n"); 102 | 103 | output = (const gf_s *)pre_wnaf; 104 | printf("const gf API_NS(precomputed_wnaf_as_fe)[%d]\n", 105 | (int)(API_NS(sizeof_precomputed_wnafs) / sizeof(gf))); 106 | printf("VECTOR_ALIGNED __attribute__((visibility(\"hidden\"))) = {\n "); 107 | for (i=0; i < API_NS(sizeof_precomputed_wnafs); i+=sizeof(gf)) { 108 | if (i) printf(",\n "); 109 | field_print(output++); 110 | } 111 | printf("\n};\n"); 112 | 113 | return 0; 114 | } 115 | -------------------------------------------------------------------------------- /c_deps/ed448goldilocks/src/per_curve/elligator.tmpl.c: -------------------------------------------------------------------------------- 1 | /** @brief Elligator high-level functions. */ 2 | 3 | #include "word.h" 4 | #include "field.h" 5 | #include 6 | 7 | /* Template stuff */ 8 | #define API_NS(_id) $(c_ns)_##_id 9 | #define point_t API_NS(point_t) 10 | #define IMAGINE_TWIST $(imagine_twist) 11 | #define COFACTOR $(cofactor) 12 | static const int EDWARDS_D = $(d); 13 | 14 | #define RISTRETTO_FACTOR $(C_NS)_RISTRETTO_FACTOR 15 | extern const gf RISTRETTO_FACTOR; 16 | 17 | /* End of template stuff */ 18 | extern mask_t API_NS(deisogenize) ( 19 | gf_s *__restrict__ s, 20 | gf_s *__restrict__ inv_el_sum, 21 | gf_s *__restrict__ inv_el_m1, 22 | const point_t p, 23 | mask_t toggle_hibit_s, 24 | mask_t toggle_altx, 25 | mask_t toggle_rotation 26 | ); 27 | 28 | void API_NS(point_from_hash_nonuniform) ( 29 | point_t p, 30 | const unsigned char ser[SER_BYTES] 31 | ) { 32 | gf r0,r,a,b,c,N,e; 33 | const uint8_t mask = (uint8_t)(0xFE<<($((gf_bits-1)%8))); 34 | ignore_result(gf_deserialize(r0,ser,mask)); 35 | gf_strong_reduce(r0); 36 | gf_sqr(a,r0); 37 | gf_mul_qnr(r,a); 38 | 39 | /* Compute D@c := (dr+a-d)(dr-ar-d) with a=1 */ 40 | gf_sub(a,r,ONE); 41 | gf_mulw(b,a,EDWARDS_D); /* dr-d */ 42 | gf_add(a,b,ONE); 43 | gf_sub(b,b,r); 44 | gf_mul(c,a,b); 45 | 46 | /* compute N := (r+1)(a-2d) */ 47 | gf_add(a,r,ONE); 48 | gf_mulw(N,a,1-2*EDWARDS_D); 49 | 50 | /* e = +-sqrt(1/ND) or +-r0 * sqrt(qnr/ND) */ 51 | gf_mul(a,c,N); 52 | mask_t square = gf_isr(b,a); 53 | gf_cond_sel(c,r0,ONE,square); /* r? = square ? 1 : r0 */ 54 | gf_mul(e,b,c); 55 | 56 | /* s@a = +-|N.e| */ 57 | gf_mul(a,N,e); 58 | gf_cond_neg(a,gf_lobit(a) ^ ~square); 59 | 60 | /* t@b = -+ cN(r-1)((a-2d)e)^2 - 1 */ 61 | gf_mulw(c,e,1-2*EDWARDS_D); /* (a-2d)e */ 62 | gf_sqr(b,c); 63 | gf_sub(e,r,ONE); 64 | gf_mul(c,b,e); 65 | gf_mul(b,c,N); 66 | gf_cond_neg(b,square); 67 | gf_sub(b,b,ONE); 68 | 69 | /* isogenize */ 70 | #if IMAGINE_TWIST 71 | gf_mul(c,a,SQRT_MINUS_ONE); 72 | gf_copy(a,c); 73 | #endif 74 | 75 | gf_sqr(c,a); /* s^2 */ 76 | gf_add(a,a,a); /* 2s */ 77 | gf_add(e,c,ONE); 78 | gf_mul(p->t,a,e); /* 2s(1+s^2) */ 79 | gf_mul(p->x,a,b); /* 2st */ 80 | gf_sub(a,ONE,c); 81 | gf_mul(p->y,e,a); /* (1+s^2)(1-s^2) */ 82 | gf_mul(p->z,a,b); /* (1-s^2)t */ 83 | 84 | assert(API_NS(point_valid)(p)); 85 | } 86 | 87 | void API_NS(point_from_hash_uniform) ( 88 | point_t pt, 89 | const unsigned char hashed_data[2*SER_BYTES] 90 | ) { 91 | point_t pt2; 92 | API_NS(point_from_hash_nonuniform)(pt,hashed_data); 93 | API_NS(point_from_hash_nonuniform)(pt2,&hashed_data[SER_BYTES]); 94 | API_NS(point_add)(pt,pt,pt2); 95 | } 96 | 97 | /* Elligator_onto: 98 | * Make elligator-inverse onto at the cost of roughly halving the success probability. 99 | * Currently no effect for curves with field size 1 bit mod 8 (where the top bit 100 | * is chopped off). FUTURE MAGIC: automatic at least for brainpool-style curves; support 101 | * log p == 1 mod 8 brainpool curves maybe? 102 | */ 103 | #define MAX(A,B) (((A)>(B)) ? (A) : (B)) 104 | 105 | decaf_error_t 106 | API_NS(invert_elligator_nonuniform) ( 107 | unsigned char recovered_hash[SER_BYTES], 108 | const point_t p, 109 | uint32_t hint_ 110 | ) { 111 | mask_t hint = hint_; 112 | mask_t sgn_s = bit_to_mask(hint & 1), 113 | sgn_altx = bit_to_mask((hint>>1) & 1), 114 | sgn_r0 = bit_to_mask((hint>>2) & 1), 115 | /* FUTURE MAGIC: eventually if there's a curve which needs sgn_ed_T but not sgn_r0, 116 | * change this mask extraction. 117 | */ 118 | sgn_ed_T = bit_to_mask((hint>>3) & 1); 119 | gf a,b,c; 120 | API_NS(deisogenize)(a,b,c,p,sgn_s,sgn_altx,sgn_ed_T); 121 | 122 | mask_t is_identity = gf_eq(p->t,ZERO); 123 | #if COFACTOR==4 124 | gf_cond_sel(b,b,ONE,is_identity & sgn_altx); 125 | gf_cond_sel(c,c,ONE,is_identity & sgn_s &~ sgn_altx); 126 | #elif IMAGINE_TWIST 127 | /* Terrible, terrible special casing due to lots of 0/0 is deisogenize 128 | * Basically we need to generate -D and +- i*RISTRETTO_FACTOR 129 | */ 130 | gf_mul_i(a,RISTRETTO_FACTOR); 131 | gf_cond_sel(b,b,ONE,is_identity); 132 | gf_cond_neg(a,sgn_altx); 133 | gf_cond_sel(c,c,a,is_identity & sgn_ed_T); 134 | gf_cond_sel(c,c,ZERO,is_identity & ~sgn_ed_T); 135 | gf_mulw(a,ONE,-EDWARDS_D); 136 | gf_cond_sel(c,c,a,is_identity & ~sgn_ed_T &~ sgn_altx); 137 | #else 138 | #error "Different special-casing goes here!" 139 | #endif 140 | 141 | #if IMAGINE_TWIST 142 | gf_mulw(a,b,-EDWARDS_D); 143 | #else 144 | gf_mulw(a,b,EDWARDS_D-1); 145 | #endif 146 | gf_add(b,a,b); 147 | gf_sub(a,a,c); 148 | gf_add(b,b,c); 149 | gf_cond_swap(a,b,sgn_s); 150 | gf_mul_qnr(c,b); 151 | gf_mul(b,c,a); 152 | mask_t succ = gf_isr(c,b); 153 | succ |= gf_eq(b,ZERO); 154 | gf_mul(b,c,a); 155 | 156 | #if $(gf_bits) == 8*SER_BYTES + 1 /* p521. */ 157 | #error "this won't work because it needs to adjust high bit, not low bit" 158 | sgn_r0 = 0; 159 | #endif 160 | 161 | gf_cond_neg(b, sgn_r0^gf_lobit(b)); 162 | /* Eliminate duplicate values for identity ... */ 163 | succ &= ~(gf_eq(b,ZERO) & (sgn_r0 | sgn_s)); 164 | // #if COFACTOR == 8 165 | // succ &= ~(is_identity & sgn_ed_T); /* NB: there are no preimages of rotated identity. */ 166 | // #endif 167 | 168 | gf_serialize(recovered_hash,b); 169 | #if $(gf_bits%8) 170 | #if COFACTOR==8 171 | recovered_hash[SER_BYTES-1] ^= (hint>>4)<<$(gf_bits%8); 172 | #else 173 | recovered_hash[SER_BYTES-1] ^= (hint>>3)<<$(gf_bits%8); 174 | #endif 175 | #endif 176 | return decaf_succeed_if(mask_to_bool(succ)); 177 | } 178 | 179 | decaf_error_t 180 | API_NS(invert_elligator_uniform) ( 181 | unsigned char partial_hash[2*SER_BYTES], 182 | const point_t p, 183 | uint32_t hint 184 | ) { 185 | point_t pt2; 186 | API_NS(point_from_hash_nonuniform)(pt2,&partial_hash[SER_BYTES]); 187 | API_NS(point_sub)(pt2,p,pt2); 188 | return API_NS(invert_elligator_nonuniform)(partial_hash,pt2,hint); 189 | } 190 | -------------------------------------------------------------------------------- /c_deps/ed448goldilocks/src/per_field/f_field.tmpl.h: -------------------------------------------------------------------------------- 1 | /** @brief Field-specific code for $(gf_desc). */ 2 | 3 | #include "constant_time.h" 4 | #include 5 | #include 6 | 7 | #include "word.h" 8 | 9 | #define __DECAF_$(gf_shortname)_GF_DEFINED__ 1 10 | #define NLIMBS ($(gf_impl_bits//8)/sizeof(word_t)) 11 | #define SER_BYTES $(((gf_bits-1)//8 + 1)) 12 | typedef struct gf_$(gf_shortname)_s { 13 | word_t limb[NLIMBS]; 14 | } __attribute__((aligned(32))) gf_$(gf_shortname)_s, gf_$(gf_shortname)_t[1]; 15 | 16 | #define GF_LIT_LIMB_BITS $(gf_lit_limb_bits) 17 | #define GF_BITS $(gf_bits) 18 | #define ZERO gf_$(gf_shortname)_ZERO 19 | #define ONE gf_$(gf_shortname)_ONE 20 | #define MODULUS gf_$(gf_shortname)_MODULUS 21 | #define gf gf_$(gf_shortname)_t 22 | #define gf_s gf_$(gf_shortname)_s 23 | #define gf_eq gf_$(gf_shortname)_eq 24 | #define gf_lobit gf_$(gf_shortname)_lobit 25 | #define gf_copy gf_$(gf_shortname)_copy 26 | #define gf_add gf_$(gf_shortname)_add 27 | #define gf_sub gf_$(gf_shortname)_sub 28 | #define gf_add_RAW gf_$(gf_shortname)_add_RAW 29 | #define gf_sub_RAW gf_$(gf_shortname)_sub_RAW 30 | #define gf_bias gf_$(gf_shortname)_bias 31 | #define gf_weak_reduce gf_$(gf_shortname)_weak_reduce 32 | #define gf_strong_reduce gf_$(gf_shortname)_strong_reduce 33 | #define gf_mul gf_$(gf_shortname)_mul 34 | #define gf_sqr gf_$(gf_shortname)_sqr 35 | #define gf_mulw_unsigned gf_$(gf_shortname)_mulw_unsigned 36 | #define gf_isr gf_$(gf_shortname)_isr 37 | #define gf_serialize gf_$(gf_shortname)_serialize 38 | #define gf_deserialize gf_$(gf_shortname)_deserialize 39 | 40 | /* RFC 7748 support */ 41 | #define X_PUBLIC_BYTES SER_BYTES 42 | #define X_PRIVATE_BYTES X_PUBLIC_BYTES 43 | #define X_PRIVATE_BITS $(gf_bits) 44 | 45 | #define SQRT_MINUS_ONE P$(gf_shortname)_SQRT_MINUS_ONE /* might not be defined */ 46 | 47 | #define INLINE_UNUSED __inline__ __attribute__((unused,always_inline)) 48 | 49 | #ifdef __cplusplus 50 | extern "C" { 51 | #endif 52 | 53 | /* Defined below in f_impl.h */ 54 | static INLINE_UNUSED void gf_copy (gf out, const gf a) { *out = *a; } 55 | static INLINE_UNUSED void gf_add_RAW (gf out, const gf a, const gf b); 56 | static INLINE_UNUSED void gf_sub_RAW (gf out, const gf a, const gf b); 57 | static INLINE_UNUSED void gf_bias (gf inout, int amount); 58 | static INLINE_UNUSED void gf_weak_reduce (gf inout); 59 | 60 | void gf_strong_reduce (gf inout); 61 | void gf_add (gf out, const gf a, const gf b); 62 | void gf_sub (gf out, const gf a, const gf b); 63 | void gf_mul (gf_s *__restrict__ out, const gf a, const gf b); 64 | void gf_mulw_unsigned (gf_s *__restrict__ out, const gf a, uint32_t b); 65 | void gf_sqr (gf_s *__restrict__ out, const gf a); 66 | mask_t gf_isr(gf a, const gf x); /** a^2 x = 1, QNR, or 0 if x=0. Return true if successful */ 67 | mask_t gf_eq (const gf x, const gf y); 68 | mask_t gf_lobit (const gf x); 69 | 70 | void gf_serialize (uint8_t *serial, const gf x); 71 | mask_t gf_deserialize (gf x, const uint8_t serial[SER_BYTES],uint8_t hi_nmask); 72 | 73 | 74 | #ifdef __cplusplus 75 | } /* extern "C" */ 76 | #endif 77 | 78 | #include "f_impl.h" /* Bring in the inline implementations */ 79 | 80 | #define P_MOD_8 $(modulus % 8) 81 | #if P_MOD_8 == 5 82 | extern const gf SQRT_MINUS_ONE; 83 | #endif 84 | 85 | #ifndef LIMBPERM 86 | #define LIMBPERM(i) (i) 87 | #endif 88 | #define LIMB_MASK(i) (((1ull)<limb[LIMBPERM(j)]) << fill; 26 | fill += LIMB_PLACE_VALUE(LIMBPERM(j)); 27 | j++; 28 | } 29 | serial[i] = (uint8_t)buffer; 30 | fill -= 8; 31 | buffer >>= 8; 32 | } 33 | } 34 | 35 | /** Return high bit of x = low bit of 2x mod p */ 36 | mask_t gf_lobit(const gf x) { 37 | gf y; 38 | gf_copy(y,x); 39 | gf_strong_reduce(y); 40 | return bit_to_mask((y->limb[0]) & 1); 41 | } 42 | 43 | /** Deserialize from wire format; return -1 on success and 0 on failure. */ 44 | mask_t gf_deserialize (gf x, const uint8_t serial[SER_BYTES], uint8_t hi_nmask) { 45 | unsigned int j=0, fill=0; 46 | dword_t buffer = 0; 47 | dsword_t scarry = 0; 48 | UNROLL for (unsigned int i=0; ilimb[LIMBPERM(i)] = (word_t)((i>= LIMB_PLACE_VALUE(LIMBPERM(i)); 59 | scarry = (scarry + x->limb[LIMBPERM(i)] - MODULUS->limb[LIMBPERM(i)]) >> (8*sizeof(word_t)); 60 | } 61 | return word_is_zero((word_t)buffer) & ~word_is_zero((word_t)scarry); 62 | } 63 | 64 | /** Reduce to canonical form. */ 65 | void gf_strong_reduce (gf a) { 66 | /* first, clear high */ 67 | gf_weak_reduce(a); /* Determined to have negligible perf impact. */ 68 | 69 | /* now the total is less than 2p */ 70 | 71 | /* compute total_value - p. No need to reduce mod p. */ 72 | dsword_t scarry = 0; 73 | for (unsigned int i=0; ilimb[LIMBPERM(i)] - MODULUS->limb[LIMBPERM(i)]; 75 | a->limb[LIMBPERM(i)] = scarry & LIMB_MASK(LIMBPERM(i)); 76 | scarry >>= LIMB_PLACE_VALUE(LIMBPERM(i)); 77 | } 78 | 79 | /* uncommon case: it was >= p, so now scarry = 0 and this = x 80 | * common case: it was < p, so now scarry = -1 and this = x - p + 2^255 81 | * so let's add back in p. will carry back off the top for 2^255. 82 | */ 83 | assert(word_is_zero((word_t)scarry) | word_is_zero((word_t)scarry+1)); 84 | 85 | word_t scarry_0 = (word_t)scarry; 86 | dword_t carry = 0; 87 | 88 | /* add it back */ 89 | for (unsigned int i=0; ilimb[LIMBPERM(i)] + (scarry_0 & MODULUS->limb[LIMBPERM(i)]); 91 | a->limb[LIMBPERM(i)] = carry & LIMB_MASK(LIMBPERM(i)); 92 | carry >>= LIMB_PLACE_VALUE(LIMBPERM(i)); 93 | } 94 | 95 | assert(word_is_zero((word_t)(carry) + scarry_0)); 96 | } 97 | 98 | /** Subtract two gf elements d=a-b */ 99 | void gf_sub (gf d, const gf a, const gf b) { 100 | gf_sub_RAW ( d, a, b ); 101 | gf_bias( d, 2 ); 102 | gf_weak_reduce ( d ); 103 | } 104 | 105 | /** Add two field elements d = a+b */ 106 | void gf_add (gf d, const gf a, const gf b) { 107 | gf_add_RAW ( d, a, b ); 108 | gf_weak_reduce ( d ); 109 | } 110 | 111 | /** Compare a==b */ 112 | mask_t gf_eq(const gf a, const gf b) { 113 | gf c; 114 | gf_sub(c,a,b); 115 | gf_strong_reduce(c); 116 | mask_t ret=0; 117 | for (unsigned int i=0; ilimb[LIMBPERM(i)]; 119 | } 120 | 121 | return word_is_zero(ret); 122 | } 123 | -------------------------------------------------------------------------------- /c_deps/ed448goldilocks/src/public_include/decaf.tmpl.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Master header for Decaf library. 3 | * 4 | * The Decaf library implements cryptographic operations on a elliptic curve 5 | * groups of prime order p. It accomplishes this by using a twisted Edwards 6 | * curve (isogenous to Ed448-Goldilocks or Ed25519) and wiping out the cofactor. 7 | * 8 | * The formulas are all complete and have no special cases. However, some 9 | * functions can fail. For example, decoding functions can fail because not 10 | * every string is the encoding of a valid group element. 11 | * 12 | * The formulas contain no data-dependent branches, timing or memory accesses, 13 | * except for decaf_XXX_base_double_scalarmul_non_secret. 14 | */ 15 | 16 | $("\n".join([ 17 | "#include " % g for g in sorted([c["bits"] for _,c in curve.items()]) 18 | ])) 19 | -------------------------------------------------------------------------------- /c_deps/ed448goldilocks/src/public_include/decaf.tmpl.hxx: -------------------------------------------------------------------------------- 1 | /** Master header for Decaf library, C++ version. */ 2 | 3 | $("\n".join([ 4 | "#include " % g for g in sorted([c["bits"] for _,c in curve.items()]) 5 | ])) 6 | 7 | /** Namespace for all C++ decaf objects. */ 8 | namespace decaf { 9 | /** Given a template with a "run" function, run it for all curves */ 10 | template class Run> 11 | void run_for_all_curves() { 12 | $("\n".join([ 13 | " Run<%s>::run();" % cd["cxx_ns"] 14 | for cd in sorted(curve.values(), key=lambda x:x["c_ns"]) 15 | ]) 16 | ) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /c_deps/ed448goldilocks/src/public_include/decaf/eddsa.tmpl.hxx: -------------------------------------------------------------------------------- 1 | /** 2 | * EdDSA crypto routines, metaheader. 3 | */ 4 | 5 | /** Namespace for all libdecaf C++ objects. */ 6 | namespace decaf { 7 | /** How signatures handle hashing. */ 8 | enum Prehashed { 9 | PURE, /**< Sign the message itself. This can't be done in one pass. */ 10 | PREHASHED /**< Sign the hash of the message. */ 11 | }; 12 | } 13 | 14 | $("\n".join([ 15 | "#include " % g for g in sorted([c["bits"] for _,c in curve.items()]) 16 | ])) 17 | -------------------------------------------------------------------------------- /c_deps/ed448goldilocks/src/public_include/decaf/sha512.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file decaf/shake.h 3 | * @copyright Public domain. 4 | * @author Mike Hamburg 5 | * @brief SHA2-512 6 | */ 7 | 8 | #ifndef __DECAF_SHA512_H__ 9 | #define __DECAF_SHA512_H__ 10 | 11 | #include 12 | #include 13 | #include /* for NULL */ 14 | 15 | #include 16 | 17 | #ifdef __cplusplus 18 | extern "C" { 19 | #endif 20 | 21 | /** Hash context for SHA-512 */ 22 | typedef struct decaf_sha512_ctx_s { 23 | /** @cond internal */ 24 | uint64_t state[8]; 25 | uint8_t block[128]; 26 | uint64_t bytes_processed; 27 | /* @endcond */ 28 | } decaf_sha512_ctx_s, decaf_sha512_ctx_t[1]; 29 | 30 | /** Initialize a SHA-512 context. */ 31 | void DECAF_API_VIS decaf_sha512_init(decaf_sha512_ctx_t ctx) DECAF_NONNULL; 32 | 33 | /** Update context by hashing part of a message. */ 34 | void DECAF_API_VIS decaf_sha512_update(decaf_sha512_ctx_t ctx, const uint8_t *message, size_t message_len) DECAF_NONNULL; 35 | 36 | /** Finalize context and write out hash. 37 | * @param [inout] ctx The context. Will be destroyed and re-initialized on return. 38 | * @param [out] output Place to store the output hash. 39 | * @param [in] output_len Length in bytes of the output hash. Must between 0 and 64, inclusive. 40 | */ 41 | void DECAF_API_VIS decaf_sha512_final(decaf_sha512_ctx_t ctx, uint8_t *output, size_t output_len) DECAF_NONNULL; 42 | 43 | /** Securely destroy a SHA512 context. */ 44 | static inline void decaf_sha512_destroy(decaf_sha512_ctx_t ctx) { 45 | decaf_bzero(ctx,sizeof(*ctx)); 46 | } 47 | 48 | /** Hash a message. 49 | * @param [out] output Place to store the output hash. 50 | * @param [in] output_len Length in bytes of the output hash. Must between 0 and 64, inclusive. 51 | * @param [in] message A message to hash. 52 | * @param [in] message_len Length in bytes of the input message. 53 | */ 54 | static inline void decaf_sha512_hash( 55 | uint8_t *output, 56 | size_t output_len, 57 | const uint8_t *message, 58 | size_t message_len 59 | ) { 60 | decaf_sha512_ctx_t ctx; 61 | decaf_sha512_init(ctx); 62 | decaf_sha512_update(ctx,message,message_len); 63 | decaf_sha512_final(ctx,output,output_len); 64 | decaf_sha512_destroy(ctx); 65 | } 66 | 67 | #ifdef __cplusplus 68 | } /* extern "C" */ 69 | #endif 70 | 71 | #endif /* __DECAF_SHA512_H__ */ 72 | -------------------------------------------------------------------------------- /c_deps/ed448goldilocks/src/public_include/decaf/sha512.hxx: -------------------------------------------------------------------------------- 1 | /** 2 | * @file decaf/sha512.hxx 3 | * @copyright 4 | * Based on public domain code by Dan Bernstein \n 5 | * Copyright (c) 2015 Cryptography Research, Inc. \n 6 | * Released under the MIT License. See LICENSE.txt for license information. 7 | * @author Mike Hamburg 8 | * @brief SHA512 instance, C++ wrapper. 9 | */ 10 | 11 | #ifndef __DECAF_SHA512_HXX__ 12 | #define __DECAF_SHA512_HXX__ 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | /** @cond internal */ 19 | #if __cplusplus >= 201103L 20 | #define DECAF_NOEXCEPT noexcept 21 | #else 22 | #define DECAF_NOEXCEPT throw() 23 | #endif 24 | /** @endcond */ 25 | 26 | namespace decaf { 27 | 28 | /** SHA512 wrapper function */ 29 | class SHA512 { 30 | protected: 31 | /** @cond internal */ 32 | /** The C-wrapper sponge state */ 33 | decaf_sha512_ctx_t wrapped; 34 | /** @endcond */ 35 | 36 | public: 37 | /** Number of bytes ouf output */ 38 | static const size_t OUTPUT_BYTES = 64; 39 | 40 | /** Number of bytes of output */ 41 | static const size_t MAX_OUTPUT_BYTES = OUTPUT_BYTES; 42 | 43 | /** Default number of bytes to output */ 44 | static const size_t DEFAULT_OUTPUT_BYTES = OUTPUT_BYTES; 45 | 46 | /** Constructor */ 47 | inline SHA512() DECAF_NOEXCEPT { decaf_sha512_init(wrapped); } 48 | 49 | /** Add more data to running hash */ 50 | inline void update(const uint8_t *__restrict__ in, size_t len) DECAF_NOEXCEPT { decaf_sha512_update(wrapped,in,len); } 51 | 52 | /** Add more data to running hash, C++ version. */ 53 | inline void update(const Block &s) DECAF_NOEXCEPT { update(s.data(),s.size()); } 54 | 55 | /** Add more data, stream version. */ 56 | inline SHA512 &operator<<(const Block &s) { update(s); return *this; } 57 | 58 | /** Same as <<. */ 59 | inline SHA512 &operator+=(const Block &s) { return *this << s; } 60 | 61 | /** @brief Output bytes from the SHA context, and resets it. */ 62 | inline void final(Buffer b) /*throw(LengthException)*/ { 63 | if (b.size() > OUTPUT_BYTES) throw LengthException(); 64 | decaf_sha512_final(wrapped,b.data(),b.size()); 65 | } 66 | 67 | /** Resets the SHA context */ 68 | inline void reset() DECAF_NOEXCEPT { decaf_sha512_init(wrapped); } 69 | 70 | /** @brief Output bytes from the sponge. */ 71 | inline SecureBuffer final(size_t len = OUTPUT_BYTES) /*throw(LengthException)*/ { 72 | if (len > OUTPUT_BYTES) throw LengthException(); 73 | SecureBuffer buffer(len); 74 | decaf_sha512_final(wrapped,buffer.data(),len); 75 | return buffer; 76 | } 77 | 78 | /** @brief Return the sponge's default output size. */ 79 | inline size_t default_output_size() const DECAF_NOEXCEPT { return OUTPUT_BYTES; } 80 | 81 | /** @brief Return the sponge's maximum output size. */ 82 | inline size_t max_output_size() const DECAF_NOEXCEPT { return MAX_OUTPUT_BYTES; } 83 | 84 | /** @brief Hash a message in one pass */ 85 | static inline SecureBuffer hash ( 86 | const Block &message, 87 | size_t outlen = OUTPUT_BYTES 88 | ) /*throw(LengthException, std::bad_alloc)*/ { 89 | if (outlen > OUTPUT_BYTES) throw LengthException(); 90 | SecureBuffer buffer(outlen); 91 | decaf_sha512_hash(buffer.data(),outlen,message.data(),message.size()); 92 | return buffer; 93 | } 94 | 95 | /** Destructor zeroizes state */ 96 | inline ~SHA512() DECAF_NOEXCEPT { decaf_sha512_destroy(wrapped); } 97 | }; 98 | 99 | } /* namespace decaf */ 100 | 101 | #undef DECAF_NOEXCEPT 102 | 103 | #endif /* __DECAF_SHA512_HXX__ */ 104 | -------------------------------------------------------------------------------- /c_deps/ed448goldilocks/src/public_include/decaf/spongerng.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file decaf/spongerng.h 3 | * @copyright 4 | * Copyright (c) 2015-2016 Cryptography Research, Inc. \n 5 | * Released under the MIT License. See LICENSE.txt for license information. 6 | * @author Mike Hamburg 7 | * @brief Sponge-based RNGs. 8 | * @warning This construction isn't final. In particular, 9 | * the outputs of deterministic RNGs from this mechanism might change in future versions. 10 | */ 11 | 12 | #ifndef __DECAF_SPONGERNG_H__ 13 | #define __DECAF_SPONGERNG_H__ 14 | 15 | #include 16 | 17 | #ifdef __cplusplus 18 | extern "C" { 19 | #endif 20 | 21 | /** Keccak CSPRNG structure as struct. */ 22 | typedef struct { 23 | decaf_keccak_sponge_t sponge; /**< Internal sponge object. */ 24 | } decaf_keccak_prng_s; 25 | 26 | /** Keccak CSPRNG structure as one-element array */ 27 | typedef decaf_keccak_prng_s decaf_keccak_prng_t[1]; 28 | 29 | /** Initialize a sponge-based CSPRNG from a buffer. */ 30 | void DECAF_API_VIS decaf_spongerng_init_from_buffer ( 31 | decaf_keccak_prng_t prng, /**< [out] The PRNG object. */ 32 | const uint8_t *__restrict__ in, /**< [in] The initialization data. */ 33 | size_t len, /**< [in] The length of the initialization data. */ 34 | int deterministic /**< [in] If zero, allow RNG to stir in nondeterministic data from RDRAND or RDTSC.*/ 35 | ) DECAF_NONNULL; 36 | 37 | /** 38 | * @brief Initialize a sponge-based CSPRNG from a file. 39 | * @retval DECAF_SUCCESS success. 40 | * @retval DECAF_FAILURE failure. 41 | * @note On failure, errno can be used to determine the cause. 42 | */ 43 | decaf_error_t DECAF_API_VIS decaf_spongerng_init_from_file ( 44 | decaf_keccak_prng_t prng, /**< [out] The PRNG object. */ 45 | const char *file, /**< [in] A name of a file containing initial data. */ 46 | size_t len, /**< [in] The length of the initial data. Must be positive. */ 47 | int deterministic /**< [in] If zero, allow RNG to stir in nondeterministic data from RDRAND or RDTSC. */ 48 | ) DECAF_NONNULL DECAF_WARN_UNUSED; 49 | 50 | /** 51 | * @brief Initialize a nondeterministic sponge-based CSPRNG from /dev/urandom. 52 | * @retval DECAF_SUCCESS success. 53 | * @retval DECAF_FAILURE failure. 54 | * @note On failure, errno can be used to determine the cause. 55 | */ 56 | decaf_error_t DECAF_API_VIS decaf_spongerng_init_from_dev_urandom ( 57 | decaf_keccak_prng_t prng /**< [out] sponge The sponge object. */ 58 | ) DECAF_WARN_UNUSED; 59 | 60 | /** Output bytes from a sponge-based CSPRNG. */ 61 | void DECAF_API_VIS decaf_spongerng_next ( 62 | decaf_keccak_prng_t prng, /**< [inout] The PRNG object. */ 63 | uint8_t * __restrict__ out, /**< [out] Output buffer. */ 64 | size_t len /**< [in] Number of bytes to output. */ 65 | ); 66 | 67 | /** Stir entropy data into a sponge-based CSPRNG from a buffer. */ 68 | void DECAF_API_VIS decaf_spongerng_stir ( 69 | decaf_keccak_prng_t prng, /**< [out] The PRNG object. */ 70 | const uint8_t * __restrict__ in, /**< [in] The entropy data. */ 71 | size_t len /**< [in] The length of the initial data. */ 72 | ) DECAF_NONNULL; 73 | 74 | /** Securely destroy a sponge RNG object by overwriting it. */ 75 | static DECAF_INLINE void 76 | decaf_spongerng_destroy ( 77 | decaf_keccak_prng_t doomed /**< [in] The object to destroy. */ 78 | ); 79 | 80 | /** @cond internal */ 81 | /***************************************/ 82 | /* Implementations of inline functions */ 83 | /***************************************/ 84 | void decaf_spongerng_destroy (decaf_keccak_prng_t doomed) { 85 | decaf_sha3_destroy(doomed->sponge); 86 | } 87 | /** @endcond */ /* internal */ 88 | 89 | #ifdef __cplusplus 90 | } /* extern "C" */ 91 | #endif 92 | 93 | #endif /* __DECAF_SPONGERNG_H__ */ 94 | -------------------------------------------------------------------------------- /c_deps/ed448goldilocks/src/public_include/decaf/spongerng.hxx: -------------------------------------------------------------------------------- 1 | /** 2 | * @file decaf/spongerng.hxx 3 | * @copyright 4 | * Based on CC0 code by David Leon Gil, 2015 \n 5 | * Copyright (c) 2015 Cryptography Research, Inc. \n 6 | * Released under the MIT License. See LICENSE.txt for license information. 7 | * @author Mike Hamburg 8 | * @brief Sponge RNG instances, C++ wrapper. 9 | * @warning The guts of this are subject to change. Please don't implement 10 | * anything that depends on the deterministic RNG being stable across versions 11 | * of this library. 12 | */ 13 | 14 | #ifndef __DECAF_SPONGERNG_HXX__ 15 | #define __DECAF_SPONGERNG_HXX__ 16 | 17 | #include 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | /** @cond internal */ 24 | #if __cplusplus >= 201103L 25 | #define DECAF_NOEXCEPT noexcept 26 | #define DECAF_DELETE = delete 27 | #else 28 | #define DECAF_NOEXCEPT throw() 29 | #define DECAF_DELETE 30 | #endif 31 | /** @endcond */ 32 | 33 | namespace decaf { 34 | 35 | /** Sponge-based random-number generator */ 36 | class SpongeRng : public Rng { 37 | private: 38 | /** C wrapped object */ 39 | decaf_keccak_prng_t sp; 40 | 41 | public: 42 | /** Deterministic flag. 43 | * The idea is that DETERMINISTIC is used for testing or for lockstep computations, 44 | * and NONDETERMINISTIC is used in production. 45 | */ 46 | enum Deterministic { RANDOM = 0, DETERMINISTIC = 1 }; 47 | 48 | /** Exception thrown when The RNG fails (to seed itself) */ 49 | class RngException : public std::exception { 50 | private: 51 | /** @cond internal */ 52 | const char *const what_; 53 | /** @endcond */ 54 | public: 55 | const int err_code; /**< errno that caused the reseed to fail. */ 56 | const char *what() const DECAF_NOEXCEPT { return what_; } /**< Description of exception. */ 57 | RngException(int err_code, const char *what_) DECAF_NOEXCEPT : what_(what_), err_code(err_code) {} /**< Construct */ 58 | }; 59 | 60 | /** Initialize, deterministically by default, from block */ 61 | inline SpongeRng( const Block &in, Deterministic det ) { 62 | decaf_spongerng_init_from_buffer(sp,in.data(),in.size(),(int)det); 63 | } 64 | 65 | /** Initialize, non-deterministically by default, from C/C++ filename */ 66 | inline SpongeRng( const std::string &in = "/dev/urandom", size_t len = 32, Deterministic det = RANDOM ) 67 | /*throw(RngException)*/ { 68 | decaf_error_t ret = decaf_spongerng_init_from_file(sp,in.c_str(),len,det); 69 | if (!decaf_successful(ret)) { 70 | throw RngException(errno, "Couldn't load from file"); 71 | } 72 | } 73 | 74 | /** Stir in new data */ 75 | inline void stir( const Block &data ) DECAF_NOEXCEPT { 76 | decaf_spongerng_stir(sp,data.data(),data.size()); 77 | } 78 | 79 | /** Securely destroy by overwriting state. */ 80 | inline ~SpongeRng() DECAF_NOEXCEPT { decaf_spongerng_destroy(sp); } 81 | 82 | using Rng::read; 83 | 84 | /** Read data to a buffer. */ 85 | virtual inline void read(Buffer buffer) DECAF_NOEXCEPT 86 | #if __cplusplus >= 201103L 87 | final 88 | #endif 89 | { decaf_spongerng_next(sp,buffer.data(),buffer.size()); } 90 | 91 | private: 92 | SpongeRng(const SpongeRng &) DECAF_DELETE; 93 | SpongeRng &operator=(const SpongeRng &) DECAF_DELETE; 94 | }; 95 | /**@endcond*/ 96 | 97 | } /* namespace decaf */ 98 | 99 | #undef DECAF_NOEXCEPT 100 | #undef DECAF_DELETE 101 | 102 | #endif /* __DECAF_SPONGERNG_HXX__ */ 103 | -------------------------------------------------------------------------------- /c_deps/ed448goldilocks/src/utils.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2015 Cryptography Research, Inc. 2 | * Released under the MIT License. See LICENSE.txt for license information. 3 | */ 4 | 5 | /** 6 | * @file utils.c 7 | * @author Mike Hamburg 8 | * @brief Decaf utility functions. 9 | */ 10 | 11 | #include 12 | 13 | void decaf_bzero ( 14 | void *s, 15 | size_t size 16 | ) { 17 | #ifdef __STDC_LIB_EXT1__ 18 | memset_s(s, size, 0, size); 19 | #else 20 | const size_t sw = sizeof(decaf_word_t); 21 | volatile uint8_t *destroy = (volatile uint8_t *)s; 22 | for (; size && ((uintptr_t)destroy)%sw; size--, destroy++) 23 | *destroy = 0; 24 | for (; size >= sw; size -= sw, destroy += sw) 25 | *(volatile decaf_word_t *)destroy = 0; 26 | for (; size; size--, destroy++) 27 | *destroy = 0; 28 | #endif 29 | } 30 | 31 | decaf_bool_t decaf_memeq ( 32 | const void *data1_, 33 | const void *data2_, 34 | size_t size 35 | ) { 36 | const unsigned char *data1 = (const unsigned char *)data1_; 37 | const unsigned char *data2 = (const unsigned char *)data2_; 38 | unsigned char ret = 0; 39 | for (; size; size--, data1++, data2++) { 40 | ret |= *data1 ^ *data2; 41 | } 42 | return (((decaf_dword_t)ret) - 1) >> 8; 43 | } 44 | -------------------------------------------------------------------------------- /c_deps/ed448goldilocks/test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | ############################################################################ 2 | # CMakeLists.txt 3 | # 4 | # Released under the MIT License. See LICENSE.txt for license information. 5 | # 6 | ############################################################################ 7 | if(ENABLE_SHARED) 8 | set(DECAF_LIBRARIES_FOR_TESTER decaf) 9 | else() 10 | set(DECAF_LIBRARIES_FOR_TESTER decaf-static) 11 | endif() 12 | 13 | add_executable(decaf_tester test_decaf.cxx) 14 | set_target_properties(decaf_tester PROPERTIES LINKER_LANGUAGE CXX) 15 | target_link_libraries(decaf_tester ${DECAF_LIBRARIES_FOR_TESTER}) 16 | 17 | add_executable(ristretto_tester ristretto.cxx) 18 | set_target_properties(ristretto_tester PROPERTIES LINKER_LANGUAGE CXX) 19 | target_link_libraries(ristretto_tester ${DECAF_LIBRARIES_FOR_TESTER}) 20 | 21 | add_executable(shakesum_tester shakesum.c) 22 | set_target_properties(shakesum_tester PROPERTIES LINKER_LANGUAGE C) 23 | target_link_libraries(shakesum_tester ${DECAF_LIBRARIES_FOR_TESTER}) 24 | 25 | add_executable(bench bench_decaf.cxx) 26 | set_target_properties(bench PROPERTIES LINKER_LANGUAGE CXX) 27 | target_link_libraries(bench ${DECAF_LIBRARIES_FOR_TESTER}) 28 | 29 | add_test(NAME decaf COMMAND decaf_tester) 30 | add_test(NAME bench COMMAND bench) 31 | 32 | -------------------------------------------------------------------------------- /c_deps/ed448goldilocks/test/batarch.map: -------------------------------------------------------------------------------- 1 | neon arch_neon_experimental 2 | arm32 arch_arm_32 3 | 64 arch_ref64 4 | 32 arch_32 5 | amd64 arch_x86_64 6 | -------------------------------------------------------------------------------- /c_deps/ed448goldilocks/test/shakesum.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @cond internal 3 | * @file decaf_shakesum.c 4 | * @copyright 5 | * Copyright (c) 2015 Cryptography Research, Inc. \n 6 | * Released under the MIT License. See LICENSE.txt for license information. 7 | * @author Mike Hamburg 8 | * @brief SHA3 utility, to be combined with test vectors eventually... 9 | */ 10 | 11 | #include 12 | #if defined _MSC_VER // MSVC has not unistd.h 13 | #include 14 | #include 15 | typedef SSIZE_T ssize_t; 16 | #define read _read 17 | #else 18 | #include 19 | #endif 20 | #include 21 | #include 22 | #include 23 | 24 | static void usage(void) { 25 | fprintf( 26 | stderr, 27 | "decaf_shakesum [shake256|shake128|sha3-224|sha3-384|sha3-512|sha512] < infile > outfile\n" 28 | ); 29 | } 30 | 31 | int main(int argc, char **argv) { 32 | (void)argc; (void)argv; 33 | 34 | decaf_keccak_sponge_t sponge; 35 | decaf_sha512_ctx_t decaf_sha512; 36 | unsigned char buf[1024]; 37 | 38 | unsigned int outlen = 512; 39 | decaf_shake256_gen_init(sponge); 40 | 41 | int use_sha512 = 0; 42 | 43 | /* Sloppy. Real utility would parse --algo, --size ... */ 44 | if (argc > 1) { 45 | if (!strcmp(argv[1], "shake256") || !strcmp(argv[1], "SHAKE256")) { 46 | outlen = 512; 47 | decaf_shake256_gen_init(sponge); 48 | } else if (!strcmp(argv[1], "shake128") || !strcmp(argv[1], "SHAKE128")) { 49 | outlen = 512; 50 | decaf_shake128_gen_init(sponge); 51 | } else if (!strcmp(argv[1], "sha3-224") || !strcmp(argv[1], "SHA3-224")) { 52 | outlen = 224/8; 53 | decaf_sha3_224_gen_init(sponge); 54 | } else if (!strcmp(argv[1], "sha3-256") || !strcmp(argv[1], "SHA3-256")) { 55 | outlen = 256/8; 56 | decaf_sha3_256_gen_init(sponge); 57 | } else if (!strcmp(argv[1], "sha3-384") || !strcmp(argv[1], "SHA3-384")) { 58 | outlen = 384/8; 59 | decaf_sha3_384_gen_init(sponge); 60 | } else if (!strcmp(argv[1], "sha3-512") || !strcmp(argv[1], "SHA3-512")) { 61 | outlen = 512/8; 62 | decaf_sha3_512_gen_init(sponge); 63 | } else if (!strcmp(argv[1], "sha512") || !strcmp(argv[1], "SHA512")) { 64 | outlen = 512/8; 65 | use_sha512 = 1; 66 | decaf_sha512_init(decaf_sha512); 67 | } else { 68 | usage(); 69 | return 2; 70 | } 71 | } 72 | 73 | ssize_t red; 74 | do { 75 | red = read(0, buf, sizeof(buf)); 76 | if (red>0) { 77 | if (use_sha512) decaf_sha512_update(decaf_sha512,buf,red); 78 | else decaf_sha3_update(sponge,buf,red); 79 | } 80 | } while (red>0); 81 | 82 | if (use_sha512) { 83 | decaf_sha512_final(decaf_sha512,buf,outlen); 84 | decaf_sha512_destroy(decaf_sha512); 85 | } else { 86 | decaf_sha3_output(sponge,buf,outlen); 87 | decaf_sha3_destroy(sponge); 88 | } 89 | unsigned i; 90 | for (i=0; i 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | using namespace decaf; 20 | using namespace decaf::TOY; 21 | 22 | static const long NTESTS = 10; 23 | 24 | const char *undef_str = "Valgrind thinks this string is undefined."; 25 | const Block undef_block(undef_str); 26 | 27 | static inline void ignore_result(decaf_error_t x) { 28 | (void)x; 29 | } 30 | 31 | template struct Tests { 32 | 33 | typedef typename Group::Scalar Scalar; 34 | typedef typename Group::Point Point; 35 | typedef typename Group::Precomputed Precomputed; 36 | 37 | static void test_arithmetic() { 38 | SpongeRng rng(Block("test_arithmetic"),SpongeRng::DETERMINISTIC); 39 | rng.stir(undef_block); 40 | 41 | Scalar x(rng),y(rng),z; 42 | uint8_t ser[Group::Scalar::SER_BYTES]; 43 | 44 | for (int i=0; i inv; 61 | 62 | for (int i=0; i(ser))); 81 | (void)(p*y); 82 | (void)(p+q); 83 | (void)(p-q); 84 | (void)(-p); 85 | (void)(p.times_two()); 86 | (void)(p==q); 87 | (void)(p.debugging_torque()); 88 | /* (void)(p.non_secret_combo_with_base(y,z)); */ /* Should fail */ 89 | (void)(Precomputed(p)*y); 90 | p.dual_scalarmul(q,r,y,z); 91 | Group::Point::double_scalarmul(p,y,q,z); 92 | 93 | } 94 | } 95 | 96 | static void test_cfrg() { 97 | SpongeRng rng(Block("test_cfrg"),SpongeRng::DETERMINISTIC); 98 | rng.stir(undef_block); 99 | 100 | for (int i=0; i pub(rng); 102 | FixedArrayBuffer priv(rng); 103 | 104 | Group::DhLadder::derive_public_key(priv); 105 | ignore_result(Group::DhLadder::shared_secret_noexcept(pub,pub,priv)); 106 | } 107 | } 108 | 109 | /* Specify the same value as you did when compiling decaf_crypto.c */ 110 | #ifndef DECAF_CRYPTO_SHARED_SECRET_SHORT_CIRUIT 111 | #define DECAF_CRYPTO_SHARED_SECRET_SHORT_CIRUIT DECAF_FALSE 112 | #endif 113 | 114 | static void test_crypto() { 115 | SpongeRng rng(Block("test_crypto"),SpongeRng::DETERMINISTIC); 116 | rng.stir(undef_block); 117 | 118 | #if DECAF_CRYPTO_SHARED_SECRET_SHORT_CIRUIT 119 | SpongeRng defrng(Block("test_crypto_defined")); 120 | #endif 121 | 122 | FixedArrayBuffer shared; 123 | 124 | for (int i=0; i sk1(rng); 126 | SecureBuffer sig = sk1.sign(undef_block); 127 | 128 | #if DECAF_CRYPTO_SHARED_SECRET_SHORT_CIRUIT 129 | PrivateKey sk2(defrng); 130 | ignore_result(sk1.shared_secret_noexcept(shared,sk2.pub(),i&1)); 131 | #else 132 | PrivateKey sk3(rng); 133 | ignore_result(sk1.shared_secret_noexcept(shared,sk3.pub(),i&1)); 134 | #endif 135 | } 136 | } 137 | 138 | static void run() { 139 | printf("Testing %s:\n",Group::name()); 140 | test_arithmetic(); 141 | test_elligator(); 142 | test_ec(); 143 | test_cfrg(); 144 | test_crypto(); 145 | printf("\n"); 146 | } 147 | 148 | }; /* template struct Tests */ 149 | 150 | int main(int argc, char **argv) { 151 | (void) argc; (void) argv; 152 | VALGRIND_MAKE_MEM_UNDEFINED(undef_str, strlen(undef_str)); 153 | run_for_all_curves(); 154 | return 0; 155 | } 156 | -------------------------------------------------------------------------------- /c_deps/ed448goldilocks/test/test_templates.cxx: -------------------------------------------------------------------------------- 1 | #include "decaf/expr.hxx" 2 | 3 | class Foo { 4 | private: 5 | template friend class BinExpr; 6 | template friend class UnExpr; 7 | template friend struct Reify; 8 | Foo(const NOINIT&) {} 9 | public: 10 | int x; 11 | Foo(int x) : x(x) {} 12 | }; 13 | 14 | namespace decaf { namespace internal { 15 | DECLARE_BINOP(ADD,Foo,Foo,Foo,out.x = l.x+r.x) 16 | DECLARE_BINOP(SUB,Foo,Foo,Foo,out.x = l.x-r.x) 17 | DECLARE_BINOP(MUL,Foo,Foo,Foo,out.x = l.x*r.x) 18 | DECLARE_BINOP(EQ,Foo,Foo,bool,out = l.x==r.x) 19 | DECLARE_PARTIAL_UNOP(INV,Foo,Foo,out.x = 1/r.x; return (r.x!=0)) 20 | }} 21 | 22 | Foo frobble() { 23 | Foo a(1); 24 | a = a+a+a; 25 | a = a*a; 26 | a = a/a; 27 | (void)(a==(a+a)); 28 | return a; 29 | } 30 | -------------------------------------------------------------------------------- /c_src/.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | Language: Cpp 3 | BasedOnStyle: LLVM 4 | AllowShortFunctionsOnASingleLine: None 5 | AlwaysBreakAfterDefinitionReturnType: true 6 | BreakBeforeBraces: Linux 7 | ColumnLimit: 132 8 | IndentWidth: 4 9 | SortIncludes: false 10 | ... 11 | -------------------------------------------------------------------------------- /c_src/nif/csprng.h: -------------------------------------------------------------------------------- 1 | // -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; st-rulers: [132] -*- 2 | // vim: ts=4 sw=4 ft=c++ et 3 | 4 | #ifndef LIBDECAF_NIF_CSPRNG_H 5 | #define LIBDECAF_NIF_CSPRNG_H 6 | 7 | #include "libdecaf_nif.h" 8 | 9 | #include 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | typedef struct libdecaf_nif_csprng_ctx_s libdecaf_nif_csprng_ctx_t; 16 | 17 | struct libdecaf_nif_csprng_ctx_s { 18 | decaf_keccak_prng_s state; 19 | }; 20 | 21 | extern ERL_NIF_TERM libdecaf_nif_spongerng_csprng_init_from_buffer_2(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); 22 | extern ERL_NIF_TERM libdecaf_nif_spongerng_csprng_init_from_file_3(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); 23 | extern ERL_NIF_TERM libdecaf_nif_spongerng_csprng_init_from_dev_urandom_0(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); 24 | extern ERL_NIF_TERM libdecaf_nif_spongerng_csprng_next_2(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); 25 | extern ERL_NIF_TERM libdecaf_nif_spongerng_csprng_stir_2(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); 26 | 27 | #ifdef __cplusplus 28 | } 29 | #endif 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /c_src/nif/ed25519.c: -------------------------------------------------------------------------------- 1 | // -*- mode: c; tab-width: 4; indent-tabs-mode: nil; st-rulers: [132] -*- 2 | // vim: ts=4 sw=4 ft=c et 3 | 4 | #include "ed25519.h" 5 | 6 | /* Function Definitions */ 7 | 8 | /* libdecaf_nif:ed25519_derive_keypair/1 */ 9 | 10 | ERL_NIF_TERM 11 | libdecaf_nif_ed25519_derive_keypair_1(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) 12 | { 13 | ERL_NIF_TERM out_term; 14 | ErlNifBinary privkey; 15 | libdecaf_nif_ed25519_keypair_t *keypair = NULL; 16 | 17 | if (argc != 1) { 18 | return EXCP_BADARG(env, "argc must be 1"); 19 | } 20 | 21 | if (!enif_inspect_binary(env, argv[0], &privkey) || privkey.size != DECAF_EDDSA_25519_PRIVATE_BYTES) { 22 | return EXCP_BADARG_F(env, "Privkey must be a binary of size %d-bytes", DECAF_EDDSA_25519_PRIVATE_BYTES); 23 | } 24 | 25 | keypair = (libdecaf_nif_ed25519_keypair_t *)(enif_alloc_resource(libdecaf_nif_ed25519_keypair_resource_type, 26 | sizeof(libdecaf_nif_ed25519_keypair_t))); 27 | if (keypair == NULL) { 28 | return EXCP_ERROR(env, "Failed to allocate libdecaf_nif_ed25519_keypair_t"); 29 | } 30 | (void)decaf_ed25519_derive_keypair(keypair->inner, privkey.data); 31 | 32 | out_term = enif_make_resource(env, (void *)keypair); 33 | (void)enif_release_resource((void *)keypair); 34 | 35 | return out_term; 36 | } 37 | 38 | /* libdecaf_nif:ed25519_keypair_extract_private_key/1 */ 39 | 40 | ERL_NIF_TERM 41 | libdecaf_nif_ed25519_keypair_extract_private_key_1(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) 42 | { 43 | libdecaf_nif_ed25519_keypair_t *keypair = NULL; 44 | ERL_NIF_TERM out; 45 | uint8_t *privkey = NULL; 46 | 47 | if (argc != 1) { 48 | return EXCP_BADARG(env, "argc must be 1"); 49 | } 50 | 51 | if (!enif_get_resource(env, argv[0], libdecaf_nif_ed25519_keypair_resource_type, (void **)(&keypair))) { 52 | return EXCP_BADARG(env, "Keypair reference is invalid"); 53 | } 54 | 55 | privkey = (uint8_t *)(enif_make_new_binary(env, DECAF_EDDSA_25519_PRIVATE_BYTES, &out)); 56 | (void)decaf_ed25519_keypair_extract_private_key(privkey, keypair->inner); 57 | 58 | return out; 59 | } 60 | 61 | /* libdecaf_nif:ed25519_keypair_extract_public_key/1 */ 62 | 63 | ERL_NIF_TERM 64 | libdecaf_nif_ed25519_keypair_extract_public_key_1(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) 65 | { 66 | libdecaf_nif_ed25519_keypair_t *keypair = NULL; 67 | ERL_NIF_TERM out; 68 | uint8_t *pubkey = NULL; 69 | 70 | if (argc != 1) { 71 | return EXCP_BADARG(env, "argc must be 1"); 72 | } 73 | 74 | if (!enif_get_resource(env, argv[0], libdecaf_nif_ed25519_keypair_resource_type, (void **)(&keypair))) { 75 | return EXCP_BADARG(env, "Keypair reference is invalid"); 76 | } 77 | 78 | pubkey = (uint8_t *)(enif_make_new_binary(env, DECAF_EDDSA_25519_PUBLIC_BYTES, &out)); 79 | (void)decaf_ed25519_keypair_extract_public_key(pubkey, keypair->inner); 80 | 81 | return out; 82 | } 83 | 84 | /* libdecaf_nif:ed25519_keypair_sign/4 */ 85 | 86 | ERL_NIF_TERM 87 | libdecaf_nif_ed25519_keypair_sign_4(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) 88 | { 89 | libdecaf_nif_ed25519_keypair_t *keypair = NULL; 90 | ErlNifBinary message; 91 | unsigned int prehashed; 92 | ErlNifBinary context; 93 | ERL_NIF_TERM out; 94 | uint8_t *signature = NULL; 95 | 96 | if (argc != 4) { 97 | return EXCP_BADARG(env, "argc must be 4"); 98 | } 99 | 100 | if (!enif_get_resource(env, argv[0], libdecaf_nif_ed25519_keypair_resource_type, (void **)(&keypair))) { 101 | return EXCP_BADARG(env, "Keypair reference is invalid"); 102 | } 103 | if (!enif_inspect_binary(env, argv[1], &message)) { 104 | return EXCP_BADARG(env, "Message must be a binary"); 105 | } 106 | if (!enif_get_uint(env, argv[2], &prehashed) || (prehashed != 0 && prehashed != 1)) { 107 | return EXCP_BADARG(env, "Prehashed must be one of {0,1}"); 108 | } 109 | if (enif_compare(ATOM(no_context), argv[3]) == 0) { 110 | context.size = 0; 111 | context.data = (unsigned char *)(DECAF_ED25519_NO_CONTEXT); 112 | } else if (!enif_inspect_binary(env, argv[3], &context) || context.size > 255) { 113 | return EXCP_BADARG(env, "Context must be either the atom 'no_context' or a binary of size <= 255-bytes"); 114 | } 115 | 116 | signature = (uint8_t *)(enif_make_new_binary(env, DECAF_EDDSA_25519_SIGNATURE_BYTES, &out)); 117 | (void)decaf_ed25519_keypair_sign(signature, keypair->inner, message.data, message.size, prehashed, context.data, context.size); 118 | 119 | return out; 120 | } 121 | 122 | /* libdecaf_nif:ed25519_keypair_sign_prehash/3 */ 123 | 124 | ERL_NIF_TERM 125 | libdecaf_nif_ed25519_keypair_sign_prehash_3(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) 126 | { 127 | libdecaf_nif_ed25519_keypair_t *keypair = NULL; 128 | ErlNifBinary message; 129 | ErlNifBinary context; 130 | decaf_ed25519_prehash_ctx_t hash; 131 | ERL_NIF_TERM out; 132 | uint8_t *signature = NULL; 133 | 134 | if (argc != 3) { 135 | return EXCP_BADARG(env, "argc must be 3"); 136 | } 137 | 138 | if (!enif_get_resource(env, argv[0], libdecaf_nif_ed25519_keypair_resource_type, (void **)(&keypair))) { 139 | return EXCP_BADARG(env, "Keypair reference is invalid"); 140 | } 141 | if (!enif_inspect_binary(env, argv[1], &message)) { 142 | return EXCP_BADARG(env, "Message must be a binary"); 143 | } 144 | if (enif_compare(ATOM(no_context), argv[2]) == 0) { 145 | context.size = 0; 146 | context.data = (unsigned char *)(DECAF_ED25519_NO_CONTEXT); 147 | } else if (!enif_inspect_binary(env, argv[2], &context) || context.size > 255) { 148 | return EXCP_BADARG(env, "Context must be either the atom 'no_context' or a binary of size <= 255-bytes"); 149 | } 150 | 151 | (void)decaf_ed25519_prehash_init(hash); 152 | (void)decaf_ed25519_prehash_update(hash, message.data, message.size); 153 | signature = (uint8_t *)(enif_make_new_binary(env, DECAF_EDDSA_25519_SIGNATURE_BYTES, &out)); 154 | (void)decaf_ed25519_keypair_sign_prehash(signature, keypair->inner, hash, context.data, context.size); 155 | (void)decaf_ed25519_prehash_destroy(hash); 156 | 157 | return out; 158 | } 159 | -------------------------------------------------------------------------------- /c_src/nif/ed25519.h: -------------------------------------------------------------------------------- 1 | // -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; st-rulers: [132] -*- 2 | // vim: ts=4 sw=4 ft=c++ et 3 | 4 | #ifndef LIBDECAF_NIF_ED25519_H 5 | #define LIBDECAF_NIF_ED25519_H 6 | 7 | #include "libdecaf_nif.h" 8 | 9 | #include 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | typedef struct libdecaf_nif_ed25519_keypair_s libdecaf_nif_ed25519_keypair_t; 16 | 17 | struct libdecaf_nif_ed25519_keypair_s { 18 | decaf_eddsa_25519_keypair_t inner; 19 | }; 20 | 21 | extern ERL_NIF_TERM libdecaf_nif_ed25519_derive_keypair_1(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); 22 | extern ERL_NIF_TERM libdecaf_nif_ed25519_keypair_extract_private_key_1(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); 23 | extern ERL_NIF_TERM libdecaf_nif_ed25519_keypair_extract_public_key_1(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); 24 | extern ERL_NIF_TERM libdecaf_nif_ed25519_keypair_sign_4(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); 25 | extern ERL_NIF_TERM libdecaf_nif_ed25519_keypair_sign_prehash_3(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); 26 | 27 | #ifdef __cplusplus 28 | } 29 | #endif 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /c_src/nif/ed448.c: -------------------------------------------------------------------------------- 1 | // -*- mode: c; tab-width: 4; indent-tabs-mode: nil; st-rulers: [132] -*- 2 | // vim: ts=4 sw=4 ft=c et 3 | 4 | #include "ed448.h" 5 | 6 | /* Function Definitions */ 7 | 8 | /* libdecaf_nif:ed448_derive_keypair/1 */ 9 | 10 | ERL_NIF_TERM 11 | libdecaf_nif_ed448_derive_keypair_1(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) 12 | { 13 | ERL_NIF_TERM out_term; 14 | ErlNifBinary privkey; 15 | libdecaf_nif_ed448_keypair_t *keypair = NULL; 16 | 17 | if (argc != 1) { 18 | return EXCP_BADARG(env, "argc must be 1"); 19 | } 20 | 21 | if (!enif_inspect_binary(env, argv[0], &privkey) || privkey.size != DECAF_EDDSA_448_PRIVATE_BYTES) { 22 | return EXCP_BADARG_F(env, "Privkey must be a binary of size %d-bytes", DECAF_EDDSA_448_PRIVATE_BYTES); 23 | } 24 | 25 | keypair = (libdecaf_nif_ed448_keypair_t *)(enif_alloc_resource(libdecaf_nif_ed448_keypair_resource_type, 26 | sizeof(libdecaf_nif_ed448_keypair_t))); 27 | if (keypair == NULL) { 28 | return EXCP_ERROR(env, "Failed to allocate libdecaf_nif_ed448_keypair_t"); 29 | } 30 | (void)decaf_ed448_derive_keypair(keypair->inner, privkey.data); 31 | 32 | out_term = enif_make_resource(env, (void *)keypair); 33 | (void)enif_release_resource((void *)keypair); 34 | 35 | return out_term; 36 | } 37 | 38 | /* libdecaf_nif:ed448_keypair_extract_private_key/1 */ 39 | 40 | ERL_NIF_TERM 41 | libdecaf_nif_ed448_keypair_extract_private_key_1(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) 42 | { 43 | libdecaf_nif_ed448_keypair_t *keypair = NULL; 44 | ERL_NIF_TERM out; 45 | uint8_t *privkey = NULL; 46 | 47 | if (argc != 1) { 48 | return EXCP_BADARG(env, "argc must be 1"); 49 | } 50 | 51 | if (!enif_get_resource(env, argv[0], libdecaf_nif_ed448_keypair_resource_type, (void **)(&keypair))) { 52 | return EXCP_BADARG(env, "Keypair reference is invalid"); 53 | } 54 | 55 | privkey = (uint8_t *)(enif_make_new_binary(env, DECAF_EDDSA_448_PRIVATE_BYTES, &out)); 56 | (void)decaf_ed448_keypair_extract_private_key(privkey, keypair->inner); 57 | 58 | return out; 59 | } 60 | 61 | /* libdecaf_nif:ed448_keypair_extract_public_key/1 */ 62 | 63 | ERL_NIF_TERM 64 | libdecaf_nif_ed448_keypair_extract_public_key_1(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) 65 | { 66 | libdecaf_nif_ed448_keypair_t *keypair = NULL; 67 | ERL_NIF_TERM out; 68 | uint8_t *pubkey = NULL; 69 | 70 | if (argc != 1) { 71 | return EXCP_BADARG(env, "argc must be 1"); 72 | } 73 | 74 | if (!enif_get_resource(env, argv[0], libdecaf_nif_ed448_keypair_resource_type, (void **)(&keypair))) { 75 | return EXCP_BADARG(env, "Keypair reference is invalid"); 76 | } 77 | 78 | pubkey = (uint8_t *)(enif_make_new_binary(env, DECAF_EDDSA_448_PUBLIC_BYTES, &out)); 79 | (void)decaf_ed448_keypair_extract_public_key(pubkey, keypair->inner); 80 | 81 | return out; 82 | } 83 | 84 | /* libdecaf_nif:ed448_keypair_sign/4 */ 85 | 86 | ERL_NIF_TERM 87 | libdecaf_nif_ed448_keypair_sign_4(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) 88 | { 89 | libdecaf_nif_ed448_keypair_t *keypair = NULL; 90 | ErlNifBinary message; 91 | unsigned int prehashed; 92 | ErlNifBinary context; 93 | ERL_NIF_TERM out; 94 | uint8_t *signature = NULL; 95 | 96 | if (argc != 4) { 97 | return EXCP_BADARG(env, "argc must be 4"); 98 | } 99 | 100 | if (!enif_get_resource(env, argv[0], libdecaf_nif_ed448_keypair_resource_type, (void **)(&keypair))) { 101 | return EXCP_BADARG(env, "Keypair reference is invalid"); 102 | } 103 | if (!enif_inspect_binary(env, argv[1], &message)) { 104 | return EXCP_BADARG(env, "Message must be a binary"); 105 | } 106 | if (!enif_get_uint(env, argv[2], &prehashed) || (prehashed != 0 && prehashed != 1)) { 107 | return EXCP_BADARG(env, "Prehashed must be one of {0,1}"); 108 | } 109 | if (!enif_inspect_binary(env, argv[3], &context) || context.size > 255) { 110 | return EXCP_BADARG(env, "Context must be a binary of size <= 255-bytes"); 111 | } 112 | 113 | signature = (uint8_t *)(enif_make_new_binary(env, DECAF_EDDSA_448_SIGNATURE_BYTES, &out)); 114 | (void)decaf_ed448_keypair_sign(signature, keypair->inner, message.data, message.size, prehashed, context.data, context.size); 115 | 116 | return out; 117 | } 118 | 119 | /* libdecaf_nif:ed448_keypair_sign_prehash/3 */ 120 | 121 | ERL_NIF_TERM 122 | libdecaf_nif_ed448_keypair_sign_prehash_3(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) 123 | { 124 | libdecaf_nif_ed448_keypair_t *keypair = NULL; 125 | ErlNifBinary message; 126 | ErlNifBinary context; 127 | decaf_ed448_prehash_ctx_t hash; 128 | ERL_NIF_TERM out; 129 | uint8_t *signature = NULL; 130 | 131 | if (argc != 3) { 132 | return EXCP_BADARG(env, "argc must be 3"); 133 | } 134 | 135 | if (!enif_get_resource(env, argv[0], libdecaf_nif_ed448_keypair_resource_type, (void **)(&keypair))) { 136 | return EXCP_BADARG(env, "Keypair reference is invalid"); 137 | } 138 | if (!enif_inspect_binary(env, argv[1], &message)) { 139 | return EXCP_BADARG(env, "Message must be a binary"); 140 | } 141 | if (!enif_inspect_binary(env, argv[2], &context) || context.size > 255) { 142 | return EXCP_BADARG(env, "Context must be a binary of size <= 255-bytes"); 143 | } 144 | 145 | (void)decaf_ed448_prehash_init(hash); 146 | (void)decaf_ed448_prehash_update(hash, message.data, message.size); 147 | signature = (uint8_t *)(enif_make_new_binary(env, DECAF_EDDSA_448_SIGNATURE_BYTES, &out)); 148 | (void)decaf_ed448_keypair_sign_prehash(signature, keypair->inner, hash, context.data, context.size); 149 | (void)decaf_ed448_prehash_destroy(hash); 150 | 151 | return out; 152 | } 153 | -------------------------------------------------------------------------------- /c_src/nif/ed448.h: -------------------------------------------------------------------------------- 1 | // -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; st-rulers: [132] -*- 2 | // vim: ts=4 sw=4 ft=c++ et 3 | 4 | #ifndef LIBDECAF_NIF_ED448_H 5 | #define LIBDECAF_NIF_ED448_H 6 | 7 | #include "libdecaf_nif.h" 8 | 9 | #include 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | typedef struct libdecaf_nif_ed448_keypair_s libdecaf_nif_ed448_keypair_t; 16 | 17 | struct libdecaf_nif_ed448_keypair_s { 18 | decaf_eddsa_448_keypair_t inner; 19 | }; 20 | 21 | extern ERL_NIF_TERM libdecaf_nif_ed448_derive_keypair_1(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); 22 | extern ERL_NIF_TERM libdecaf_nif_ed448_keypair_extract_private_key_1(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); 23 | extern ERL_NIF_TERM libdecaf_nif_ed448_keypair_extract_public_key_1(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); 24 | extern ERL_NIF_TERM libdecaf_nif_ed448_keypair_sign_4(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); 25 | extern ERL_NIF_TERM libdecaf_nif_ed448_keypair_sign_prehash_3(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); 26 | 27 | #ifdef __cplusplus 28 | } 29 | #endif 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /c_src/nif/hash.h: -------------------------------------------------------------------------------- 1 | // -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; st-rulers: [132] -*- 2 | // vim: ts=4 sw=4 ft=c++ et 3 | 4 | #ifndef LIBDECAF_NIF_HASH_H 5 | #define LIBDECAF_NIF_HASH_H 6 | 7 | #include "libdecaf_nif.h" 8 | 9 | #include 10 | #include 11 | 12 | #ifdef __cplusplus 13 | extern "C" { 14 | #endif 15 | 16 | typedef struct libdecaf_nif_hash_table_s libdecaf_nif_hash_table_t; 17 | typedef struct libdecaf_nif_hash_s libdecaf_nif_hash_t; 18 | typedef enum libdecaf_nif_hash_type_t libdecaf_nif_hash_type_t; 19 | typedef struct libdecaf_nif_hash_ctx_s libdecaf_nif_hash_ctx_t; 20 | 21 | enum libdecaf_nif_hash_type_t { 22 | LIBDECAF_NIF_HASH_TYPE_SHA2_512, 23 | LIBDECAF_NIF_HASH_TYPE_SHA3_224, 24 | LIBDECAF_NIF_HASH_TYPE_SHA3_256, 25 | LIBDECAF_NIF_HASH_TYPE_SHA3_384, 26 | LIBDECAF_NIF_HASH_TYPE_SHA3_512, 27 | LIBDECAF_NIF_HASH_TYPE_KECCAK_224, 28 | LIBDECAF_NIF_HASH_TYPE_KECCAK_256, 29 | LIBDECAF_NIF_HASH_TYPE_KECCAK_384, 30 | LIBDECAF_NIF_HASH_TYPE_KECCAK_512, 31 | }; 32 | 33 | struct libdecaf_nif_hash_s { 34 | libdecaf_nif_hash_type_t type; 35 | size_t max_output_len; 36 | void (*init)(void *ctx); 37 | void (*update)(void *ctx, const uint8_t *input, size_t input_len); 38 | void (*final)(void *ctx, uint8_t *output, size_t output_len); 39 | void (*destroy)(void *ctx); 40 | }; 41 | 42 | struct libdecaf_nif_hash_ctx_s { 43 | union { 44 | struct decaf_sha512_ctx_s sha2_512; 45 | struct decaf_sha3_224_ctx_s sha3_224; 46 | struct decaf_sha3_256_ctx_s sha3_256; 47 | struct decaf_sha3_384_ctx_s sha3_384; 48 | struct decaf_sha3_512_ctx_s sha3_512; 49 | struct decaf_keccak_224_ctx_s keccak_224; 50 | struct decaf_keccak_256_ctx_s keccak_256; 51 | struct decaf_keccak_384_ctx_s keccak_384; 52 | struct decaf_keccak_512_ctx_s keccak_512; 53 | } u; 54 | libdecaf_nif_hash_type_t type; 55 | }; 56 | 57 | struct libdecaf_nif_hash_table_s { 58 | libdecaf_nif_hash_t sha2_512; 59 | libdecaf_nif_hash_t sha3_224; 60 | libdecaf_nif_hash_t sha3_256; 61 | libdecaf_nif_hash_t sha3_384; 62 | libdecaf_nif_hash_t sha3_512; 63 | libdecaf_nif_hash_t keccak_224; 64 | libdecaf_nif_hash_t keccak_256; 65 | libdecaf_nif_hash_t keccak_384; 66 | libdecaf_nif_hash_t keccak_512; 67 | }; 68 | 69 | extern libdecaf_nif_hash_table_t *libdecaf_nif_hash_table; 70 | 71 | extern ERL_NIF_TERM libdecaf_nif_hash_2(libdecaf_nif_hash_t *hash, ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); 72 | extern ERL_NIF_TERM libdecaf_nif_hash_init_0(libdecaf_nif_hash_t *hash, ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); 73 | extern ERL_NIF_TERM libdecaf_nif_hash_update_2(libdecaf_nif_hash_t *hash, ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); 74 | extern ERL_NIF_TERM libdecaf_nif_hash_final_2(libdecaf_nif_hash_t *hash, ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); 75 | 76 | static libdecaf_nif_hash_t *libdecaf_nif_hash_from_type(libdecaf_nif_hash_type_t type); 77 | 78 | inline libdecaf_nif_hash_t * 79 | libdecaf_nif_hash_from_type(libdecaf_nif_hash_type_t type) 80 | { 81 | libdecaf_nif_hash_t *hash = NULL; 82 | switch (type) { 83 | case LIBDECAF_NIF_HASH_TYPE_SHA2_512: 84 | hash = &libdecaf_nif_hash_table->sha2_512; 85 | break; 86 | case LIBDECAF_NIF_HASH_TYPE_SHA3_224: 87 | hash = &libdecaf_nif_hash_table->sha3_224; 88 | break; 89 | case LIBDECAF_NIF_HASH_TYPE_SHA3_256: 90 | hash = &libdecaf_nif_hash_table->sha3_256; 91 | break; 92 | case LIBDECAF_NIF_HASH_TYPE_SHA3_384: 93 | hash = &libdecaf_nif_hash_table->sha3_384; 94 | break; 95 | case LIBDECAF_NIF_HASH_TYPE_SHA3_512: 96 | hash = &libdecaf_nif_hash_table->sha3_512; 97 | break; 98 | case LIBDECAF_NIF_HASH_TYPE_KECCAK_224: 99 | hash = &libdecaf_nif_hash_table->keccak_224; 100 | break; 101 | case LIBDECAF_NIF_HASH_TYPE_KECCAK_256: 102 | hash = &libdecaf_nif_hash_table->keccak_256; 103 | break; 104 | case LIBDECAF_NIF_HASH_TYPE_KECCAK_384: 105 | hash = &libdecaf_nif_hash_table->keccak_384; 106 | break; 107 | case LIBDECAF_NIF_HASH_TYPE_KECCAK_512: 108 | hash = &libdecaf_nif_hash_table->keccak_512; 109 | break; 110 | default: 111 | break; 112 | } 113 | return hash; 114 | } 115 | 116 | #ifdef __cplusplus 117 | } 118 | #endif 119 | 120 | #endif 121 | -------------------------------------------------------------------------------- /c_src/nif/impl/point_255.c.h: -------------------------------------------------------------------------------- 1 | // -*- mode: c; tab-width: 4; indent-tabs-mode: nil; st-rulers: [132] -*- 2 | // vim: ts=4 sw=4 ft=c et 3 | 4 | #include 5 | 6 | /* 7 | * Erlang NIF functions 8 | */ 9 | 10 | /* libdecaf_nif:x25519_derive_public_key/1 */ 11 | 12 | static ERL_NIF_TERM 13 | libdecaf_nif_x25519_derive_public_key_1(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) 14 | { 15 | ErlNifBinary scalar; 16 | 17 | if (argc != 1 || !enif_inspect_binary(env, argv[0], &scalar) || scalar.size != DECAF_X25519_PRIVATE_BYTES) { 18 | return enif_make_badarg(env); 19 | } 20 | 21 | ERL_NIF_TERM out; 22 | uint8_t *u = (uint8_t *)(enif_make_new_binary(env, DECAF_X25519_PUBLIC_BYTES, &out)); 23 | 24 | (void)decaf_x25519_derive_public_key(u, scalar.data); 25 | 26 | return out; 27 | } 28 | 29 | /* libdecaf_nif:x25519/2 */ 30 | 31 | static ERL_NIF_TERM 32 | libdecaf_nif_x25519_2(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) 33 | { 34 | ErlNifBinary base; 35 | ErlNifBinary scalar; 36 | 37 | if (argc != 2 || !enif_inspect_binary(env, argv[0], &base) || base.size != DECAF_X25519_PUBLIC_BYTES || 38 | !enif_inspect_binary(env, argv[1], &scalar) || scalar.size != DECAF_X25519_PRIVATE_BYTES) { 39 | return enif_make_badarg(env); 40 | } 41 | 42 | ERL_NIF_TERM out; 43 | uint8_t *u = (uint8_t *)(enif_make_new_binary(env, DECAF_X25519_PUBLIC_BYTES, &out)); 44 | 45 | if (decaf_x25519(u, base.data, scalar.data) == DECAF_SUCCESS) { 46 | return out; 47 | } else { 48 | return libdecaf_nif_atom_table->ATOM_error; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /c_src/nif/impl/point_448.c.h: -------------------------------------------------------------------------------- 1 | // -*- mode: c; tab-width: 4; indent-tabs-mode: nil; st-rulers: [132] -*- 2 | // vim: ts=4 sw=4 ft=c et 3 | 4 | #include 5 | 6 | /* 7 | * Erlang NIF functions 8 | */ 9 | 10 | /* libdecaf_nif:x448_derive_public_key/1 */ 11 | 12 | static ERL_NIF_TERM 13 | libdecaf_nif_x448_derive_public_key_1(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) 14 | { 15 | ErlNifBinary scalar; 16 | 17 | if (argc != 1 || !enif_inspect_binary(env, argv[0], &scalar) || scalar.size != DECAF_X448_PRIVATE_BYTES) { 18 | return enif_make_badarg(env); 19 | } 20 | 21 | ERL_NIF_TERM out; 22 | uint8_t *u = (uint8_t *)(enif_make_new_binary(env, DECAF_X448_PUBLIC_BYTES, &out)); 23 | 24 | (void)decaf_x448_derive_public_key(u, scalar.data); 25 | 26 | return out; 27 | } 28 | 29 | /* libdecaf_nif:x448/2 */ 30 | 31 | static ERL_NIF_TERM 32 | libdecaf_nif_x448_2(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) 33 | { 34 | ErlNifBinary base; 35 | ErlNifBinary scalar; 36 | 37 | if (argc != 2 || !enif_inspect_binary(env, argv[0], &base) || base.size != DECAF_X448_PUBLIC_BYTES || 38 | !enif_inspect_binary(env, argv[1], &scalar) || scalar.size != DECAF_X448_PRIVATE_BYTES) { 39 | return enif_make_badarg(env); 40 | } 41 | 42 | ERL_NIF_TERM out; 43 | uint8_t *u = (uint8_t *)(enif_make_new_binary(env, DECAF_X448_PUBLIC_BYTES, &out)); 44 | 45 | if (decaf_x448(u, base.data, scalar.data) == DECAF_SUCCESS) { 46 | return out; 47 | } else { 48 | return libdecaf_nif_atom_table->ATOM_error; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /c_src/nif/libdecaf_nif.h: -------------------------------------------------------------------------------- 1 | // -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; st-rulers: [132] -*- 2 | // vim: ts=4 sw=4 ft=c++ et 3 | 4 | #ifndef LIBDECAF_NIF_H 5 | #define LIBDECAF_NIF_H 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | 16 | #include "xnif_trace.h" 17 | 18 | #ifdef __cplusplus 19 | extern "C" { 20 | #endif 21 | 22 | /* Atom Table */ 23 | 24 | typedef struct libdecaf_nif_atom_table_s libdecaf_nif_atom_table_t; 25 | 26 | struct libdecaf_nif_atom_table_s { 27 | ERL_NIF_TERM ATOM_badarg; 28 | ERL_NIF_TERM ATOM_error; 29 | ERL_NIF_TERM ATOM_false; 30 | ERL_NIF_TERM ATOM_nil; 31 | ERL_NIF_TERM ATOM_no_context; 32 | ERL_NIF_TERM ATOM_notsup; 33 | ERL_NIF_TERM ATOM_ok; 34 | ERL_NIF_TERM ATOM_sha2_512; 35 | ERL_NIF_TERM ATOM_sha3_224; 36 | ERL_NIF_TERM ATOM_sha3_256; 37 | ERL_NIF_TERM ATOM_sha3_384; 38 | ERL_NIF_TERM ATOM_sha3_512; 39 | ERL_NIF_TERM ATOM_keccak_224; 40 | ERL_NIF_TERM ATOM_keccak_256; 41 | ERL_NIF_TERM ATOM_keccak_384; 42 | ERL_NIF_TERM ATOM_keccak_512; 43 | ERL_NIF_TERM ATOM_shake128; 44 | ERL_NIF_TERM ATOM_shake256; 45 | ERL_NIF_TERM ATOM_true; 46 | ERL_NIF_TERM ATOM_undefined; 47 | }; 48 | 49 | extern libdecaf_nif_atom_table_t *libdecaf_nif_atom_table; 50 | 51 | #define ATOM(Id) libdecaf_nif_atom_table->ATOM_##Id 52 | 53 | /* Resource Types and Traps */ 54 | 55 | typedef struct libdecaf_nif_trap_s libdecaf_nif_trap_t; 56 | typedef enum libdecaf_nif_trap_type_t libdecaf_nif_trap_type_t; 57 | 58 | enum libdecaf_nif_trap_type_t { 59 | LIBDECAF_NIF_TRAP_TYPE_CSPRNG_NEXT, 60 | LIBDECAF_NIF_TRAP_TYPE_CSPRNG_STIR, 61 | LIBDECAF_NIF_TRAP_TYPE_HASH, 62 | LIBDECAF_NIF_TRAP_TYPE_HASH_UPDATE, 63 | LIBDECAF_NIF_TRAP_TYPE_XOF_ABSORB, 64 | LIBDECAF_NIF_TRAP_TYPE_XOF_SQUEEZE, 65 | LIBDECAF_NIF_TRAP_TYPE_XOF_UPDATE, 66 | LIBDECAF_NIF_TRAP_TYPE_XOF_OUTPUT, 67 | }; 68 | 69 | struct libdecaf_nif_trap_s { 70 | libdecaf_nif_trap_type_t type; 71 | void (*dtor)(ErlNifEnv *caller_env, void *obj); 72 | ErlNifEnv *work_env; 73 | }; 74 | 75 | extern ErlNifResourceType *libdecaf_nif_trap_resource_type; 76 | extern ErlNifResourceType *libdecaf_nif_csprng_resource_type; 77 | extern ErlNifResourceType *libdecaf_nif_ed25519_keypair_resource_type; 78 | extern ErlNifResourceType *libdecaf_nif_ed448_keypair_resource_type; 79 | extern ErlNifResourceType *libdecaf_nif_hash_resource_type; 80 | extern ErlNifResourceType *libdecaf_nif_xof_resource_type; 81 | 82 | /* NIF Utility Macros and Functions */ 83 | 84 | #ifndef ERL_NIF_NORMAL_JOB_BOUND 85 | #define ERL_NIF_NORMAL_JOB_BOUND (0) 86 | #endif 87 | 88 | #define REDUCTIONS_UNTIL_YCF_YIELD() (20000) 89 | #define BUMP_ALL_REDS(env) \ 90 | do { \ 91 | (void)enif_consume_timeslice((env), 100); \ 92 | } while (0) 93 | #define BUMP_REMAINING_REDS(env, nr_of_reductions) \ 94 | do { \ 95 | (void)enif_consume_timeslice((env), \ 96 | (int)((REDUCTIONS_UNTIL_YCF_YIELD() - (nr_of_reductions)) / REDUCTIONS_UNTIL_YCF_YIELD())); \ 97 | } while (0) 98 | 99 | /* All nif functions return a valid value or throws an exception */ 100 | #define EXCP(Env, Id, Str) \ 101 | enif_raise_exception((Env), enif_make_tuple3((Env), (Id), \ 102 | enif_make_tuple2((Env), enif_make_string((Env), __FILE__, (ERL_NIF_LATIN1)), \ 103 | enif_make_int((Env), __LINE__)), \ 104 | enif_make_string((Env), (Str), (ERL_NIF_LATIN1)))) 105 | 106 | #define EXCP_F(Env, Id, Fmt, ...) \ 107 | enif_raise_exception((Env), enif_make_tuple3((Env), (Id), \ 108 | enif_make_tuple2((Env), enif_make_string((Env), __FILE__, (ERL_NIF_LATIN1)), \ 109 | enif_make_int((Env), __LINE__)), \ 110 | xnif_make_string_printf((Env), (Fmt), __VA_ARGS__))) 111 | 112 | #define EXCP_NOTSUP(Env, Str) EXCP((Env), ATOM(notsup), (Str)) 113 | #define EXCP_BADARG(Env, Str) EXCP((Env), ATOM(badarg), (Str)) 114 | #define EXCP_BADARG_F(Env, Fmt, ...) EXCP_F((Env), ATOM(badarg), Fmt, __VA_ARGS__) 115 | #define EXCP_ERROR(Env, Str) EXCP((Env), ATOM(error), (Str)) 116 | #define EXCP_ERROR_F(Env, Fmt, ...) EXCP_F((Env), ATOM(error), Fmt, __VA_ARGS__) 117 | 118 | #ifdef __cplusplus 119 | } 120 | #endif 121 | 122 | #endif 123 | -------------------------------------------------------------------------------- /c_src/nif/xnif_trace.h: -------------------------------------------------------------------------------- 1 | // -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; st-rulers: [132] -*- 2 | // vim: ts=4 sw=4 ft=c++ et 3 | 4 | #ifndef XNIF_TRACE_H 5 | #define XNIF_TRACE_H 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #include 14 | 15 | #ifdef __cplusplus 16 | extern "C" { 17 | #endif 18 | 19 | // #define XNIF_TRACE 1 20 | #ifdef XNIF_TRACE 21 | #define XNIF_TRACE_C(c) \ 22 | do { \ 23 | putchar(c); \ 24 | fflush(stdout); \ 25 | } while (0) 26 | #define XNIF_TRACE_S(s) \ 27 | do { \ 28 | fputs((s), stdout); \ 29 | fflush(stdout); \ 30 | } while (0) 31 | #define XNIF_TRACE_F(...) \ 32 | do { \ 33 | enif_fprintf(stderr, "%p ", (void *)enif_thread_self()); \ 34 | enif_fprintf(stderr, __VA_ARGS__); \ 35 | fflush(stderr); \ 36 | } while (0) 37 | #else 38 | #define XNIF_TRACE_C(c) ((void)(0)) 39 | #define XNIF_TRACE_S(s) ((void)(0)) 40 | #define XNIF_TRACE_F(...) ((void)(0)) 41 | #endif 42 | 43 | static ERL_NIF_TERM xnif_make_string_printf(ErlNifEnv *env, const char *format, ...); 44 | static ERL_NIF_TERM xnif_make_string_vprintf(ErlNifEnv *env, const char *format, va_list ap); 45 | 46 | inline ERL_NIF_TERM 47 | xnif_make_string_printf(ErlNifEnv *env, const char *format, ...) 48 | { 49 | int ret; 50 | va_list arglist; 51 | va_start(arglist, format); 52 | ret = xnif_make_string_vprintf(env, format, arglist); 53 | va_end(arglist); 54 | return ret; 55 | } 56 | 57 | inline ERL_NIF_TERM 58 | xnif_make_string_vprintf(ErlNifEnv *env, const char *format, va_list ap) 59 | { 60 | #define BUF_SZ 1024 61 | char buf[BUF_SZ]; 62 | int res; 63 | 64 | buf[0] = '\0'; 65 | res = enif_vsnprintf(buf, BUF_SZ, format, ap); 66 | if (res < 0) { 67 | return enif_raise_exception(env, enif_make_string(env, "Call to xnif_make_string_vprintf() failed", ERL_NIF_LATIN1)); 68 | } 69 | if (res < BUF_SZ) { 70 | return enif_make_string_len(env, buf, (size_t)res, ERL_NIF_LATIN1); 71 | } 72 | return enif_make_string_len(env, buf, BUF_SZ, ERL_NIF_LATIN1); 73 | #undef BUF_SZ 74 | } 75 | 76 | #ifdef __cplusplus 77 | } 78 | #endif 79 | 80 | #endif 81 | -------------------------------------------------------------------------------- /c_src/nif/xof.h: -------------------------------------------------------------------------------- 1 | // -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; st-rulers: [132] -*- 2 | // vim: ts=4 sw=4 ft=c++ et 3 | 4 | #ifndef LIBDECAF_NIF_XOF_H 5 | #define LIBDECAF_NIF_XOF_H 6 | 7 | #include "libdecaf_nif.h" 8 | 9 | #include 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | typedef struct libdecaf_nif_xof_table_s libdecaf_nif_xof_table_t; 16 | typedef struct libdecaf_nif_xof_s libdecaf_nif_xof_t; 17 | typedef enum libdecaf_nif_xof_type_t libdecaf_nif_xof_type_t; 18 | typedef struct libdecaf_nif_xof_ctx_s libdecaf_nif_xof_ctx_t; 19 | 20 | enum libdecaf_nif_xof_type_t { 21 | LIBDECAF_NIF_XOF_TYPE_SHAKE128, 22 | LIBDECAF_NIF_XOF_TYPE_SHAKE256, 23 | }; 24 | 25 | struct libdecaf_nif_xof_s { 26 | libdecaf_nif_xof_type_t type; 27 | void (*init)(void *ctx); 28 | void (*update)(void *ctx, const uint8_t *input, size_t input_len); 29 | void (*output)(void *ctx, uint8_t *output, size_t output_len); 30 | void (*destroy)(void *ctx); 31 | }; 32 | 33 | struct libdecaf_nif_xof_ctx_s { 34 | union { 35 | struct decaf_shake128_ctx_s shake128; 36 | struct decaf_shake256_ctx_s shake256; 37 | } u; 38 | libdecaf_nif_xof_type_t type; 39 | bool squeezing; 40 | }; 41 | 42 | struct libdecaf_nif_xof_table_s { 43 | libdecaf_nif_xof_t shake128; 44 | libdecaf_nif_xof_t shake256; 45 | }; 46 | 47 | extern libdecaf_nif_xof_table_t *libdecaf_nif_xof_table; 48 | 49 | extern ERL_NIF_TERM libdecaf_nif_xof_2(libdecaf_nif_xof_t *xof, ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); 50 | extern ERL_NIF_TERM libdecaf_nif_xof_init_0(libdecaf_nif_xof_t *xof, ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); 51 | extern ERL_NIF_TERM libdecaf_nif_xof_update_2(libdecaf_nif_xof_t *xof, ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); 52 | extern ERL_NIF_TERM libdecaf_nif_xof_output_2(libdecaf_nif_xof_t *xof, ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); 53 | 54 | static libdecaf_nif_xof_t *libdecaf_nif_xof_from_type(libdecaf_nif_xof_type_t type); 55 | 56 | inline libdecaf_nif_xof_t * 57 | libdecaf_nif_xof_from_type(libdecaf_nif_xof_type_t type) 58 | { 59 | libdecaf_nif_xof_t *xof = NULL; 60 | switch (type) { 61 | case LIBDECAF_NIF_XOF_TYPE_SHAKE128: 62 | xof = &libdecaf_nif_xof_table->shake128; 63 | break; 64 | case LIBDECAF_NIF_XOF_TYPE_SHAKE256: 65 | xof = &libdecaf_nif_xof_table->shake256; 66 | break; 67 | default: 68 | break; 69 | } 70 | return xof; 71 | } 72 | 73 | #ifdef __cplusplus 74 | } 75 | #endif 76 | 77 | #endif 78 | -------------------------------------------------------------------------------- /priv/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/potatosalad/erlang-libdecaf/b1588e47ab3e7790446943cadd531610919e193f/priv/.keep -------------------------------------------------------------------------------- /rebar.config: -------------------------------------------------------------------------------- 1 | %% -*- mode: erlang; tab-width: 4; indent-tabs-mode: 1; st-rulers: [70] -*- 2 | %% vim: ts=4 sw=4 ft=erlang noet 3 | {erl_opts, [ 4 | debug_info, 5 | warnings_as_errors 6 | ]}. 7 | {deps, []}. 8 | 9 | {pre_hooks, [ 10 | {"(linux|darwin|solaris)", compile, "make -C c_src"}, 11 | {"(freebsd)", compile, "gmake -C c_src"}, 12 | {"(win32)", compile, "cd c_src && nmake /F Makefile.win"} 13 | ]}. 14 | {post_hooks, [ 15 | {"(linux|darwin|solaris)", clean, "make -C c_src clean distclean"}, 16 | {"(freebsd)", clean, "gmake -C c_src clean distclean"}, 17 | {"(win32)", compile, "cd c_src && nmake /F Makefile.win clean distclean"} 18 | ]}. 19 | 20 | {hex, [{doc, ex_doc}]}. 21 | -------------------------------------------------------------------------------- /rebar.lock: -------------------------------------------------------------------------------- 1 | []. 2 | -------------------------------------------------------------------------------- /src/libdecaf.app.src: -------------------------------------------------------------------------------- 1 | %% -*- mode: erlang; tab-width: 4; indent-tabs-mode: 1; st-rulers: [70] -*- 2 | %% vim: ts=4 sw=4 ft=erlang noet 3 | {application, libdecaf, [ 4 | {description, "libdecaf NIF for ECDH (X25519, X448), EdDSA (Ed25519, Ed25519ctx, Ed25519ph, Ed448, Ed448ph), curve25519, curve448, spongerng"}, 5 | {vsn, "2.1.1"}, 6 | {id, "git"}, 7 | {registered, []}, 8 | {applications, [ 9 | kernel, 10 | stdlib, 11 | crypto 12 | ]}, 13 | {modules, []}, 14 | {licenses, ["MIT"]}, 15 | {links, [{"Github", "https://github.com/potatosalad/erlang-libdecaf"}]}, 16 | {include_paths, [ 17 | "build.config", 18 | "erlang.mk", 19 | "Makefile", 20 | "c_deps/ed448goldilocks/" 21 | ]} 22 | ]}. 23 | -------------------------------------------------------------------------------- /src/libdecaf_keccak_sha3.erl: -------------------------------------------------------------------------------- 1 | %% -*- mode: erlang; tab-width: 4; indent-tabs-mode: 1; st-rulers: [70] -*- 2 | %% vim: ts=4 sw=4 ft=erlang noet 3 | %%%------------------------------------------------------------------- 4 | %%% @author Andrew Bennett 5 | %%% @copyright 2015-2022, Andrew Bennett 6 | %%% @doc 7 | %%% 8 | %%% @end 9 | %%% Created : 28 Aug 2022 by Andrew Bennett 10 | %%%------------------------------------------------------------------- 11 | -module(libdecaf_keccak_sha3). 12 | 13 | %% API 14 | -export([ 15 | hash/2, 16 | hash/3, 17 | init/1, 18 | update/2, 19 | final/1, 20 | final/2 21 | ]). 22 | 23 | %% Macros 24 | -define(WRAP_STATE(T, R), 25 | case R of 26 | NewState when is_reference(NewState) -> 27 | {T, NewState}; 28 | Other -> 29 | Other 30 | end). 31 | 32 | %%%=================================================================== 33 | %%% API functions 34 | %%%=================================================================== 35 | 36 | hash(keccak_224, In) -> 37 | libdecaf:keccak_224(In); 38 | hash(keccak_256, In) -> 39 | libdecaf:keccak_256(In); 40 | hash(keccak_384, In) -> 41 | libdecaf:keccak_384(In); 42 | hash(keccak_512, In) -> 43 | libdecaf:keccak_512(In); 44 | hash(Type, In) -> 45 | erlang:error({badarg, [Type, In]}). 46 | 47 | hash(keccak_224, In, Outlen) -> 48 | libdecaf:keccak_224(In, Outlen); 49 | hash(keccak_256, In, Outlen) -> 50 | libdecaf:keccak_256(In, Outlen); 51 | hash(keccak_384, In, Outlen) -> 52 | libdecaf:keccak_384(In, Outlen); 53 | hash(keccak_512, In, Outlen) -> 54 | libdecaf:keccak_512(In, Outlen); 55 | hash(Type, In, Outlen) -> 56 | erlang:error({badarg, [Type, In, Outlen]}). 57 | 58 | init(keccak_224) -> 59 | ?WRAP_STATE(keccak_224, libdecaf:keccak_224_init()); 60 | init(keccak_256) -> 61 | ?WRAP_STATE(keccak_256, libdecaf:keccak_256_init()); 62 | init(keccak_384) -> 63 | ?WRAP_STATE(keccak_384, libdecaf:keccak_384_init()); 64 | init(keccak_512) -> 65 | ?WRAP_STATE(keccak_512, libdecaf:keccak_512_init()); 66 | init(Type) -> 67 | erlang:error({badarg, [Type]}). 68 | 69 | update({T = keccak_224, State}, In) -> 70 | ?WRAP_STATE(T, libdecaf:keccak_224_update(State, In)); 71 | update({T = keccak_256, State}, In) -> 72 | ?WRAP_STATE(T, libdecaf:keccak_256_update(State, In)); 73 | update({T = keccak_384, State}, In) -> 74 | ?WRAP_STATE(T, libdecaf:keccak_384_update(State, In)); 75 | update({T = keccak_512, State}, In) -> 76 | ?WRAP_STATE(T, libdecaf:keccak_512_update(State, In)); 77 | update(State, In) -> 78 | erlang:error({badarg, [State, In]}). 79 | 80 | final({keccak_224, State}) -> 81 | libdecaf:keccak_224_final(State); 82 | final({keccak_256, State}) -> 83 | libdecaf:keccak_256_final(State); 84 | final({keccak_384, State}) -> 85 | libdecaf:keccak_384_final(State); 86 | final({keccak_512, State}) -> 87 | libdecaf:keccak_512_final(State); 88 | final(State) -> 89 | erlang:error({badarg, [State]}). 90 | 91 | final({keccak_224, State}, Outlen) -> 92 | libdecaf:keccak_224_final(State, Outlen); 93 | final({keccak_256, State}, Outlen) -> 94 | libdecaf:keccak_256_final(State, Outlen); 95 | final({keccak_384, State}, Outlen) -> 96 | libdecaf:keccak_384_final(State, Outlen); 97 | final({keccak_512, State}, Outlen) -> 98 | libdecaf:keccak_512_final(State, Outlen); 99 | final(State, Outlen) -> 100 | erlang:error({badarg, [State, Outlen]}). 101 | 102 | %%%------------------------------------------------------------------- 103 | %%% Internal functions 104 | %%%------------------------------------------------------------------- 105 | -------------------------------------------------------------------------------- /src/libdecaf_sha2.erl: -------------------------------------------------------------------------------- 1 | %% -*- mode: erlang; tab-width: 4; indent-tabs-mode: 1; st-rulers: [70] -*- 2 | %% vim: ts=4 sw=4 ft=erlang noet 3 | %%%------------------------------------------------------------------- 4 | %%% @author Andrew Bennett 5 | %%% @copyright 2015-2022, Andrew Bennett 6 | %%% @doc 7 | %%% 8 | %%% @end 9 | %%% Created : 29 Feb 2016 by Andrew Bennett 10 | %%%------------------------------------------------------------------- 11 | -module(libdecaf_sha2). 12 | 13 | %% API 14 | -export([ 15 | hash/2, 16 | hash/3, 17 | init/1, 18 | update/2, 19 | final/1, 20 | final/2 21 | ]). 22 | 23 | %% Macros 24 | -define(WRAP_STATE(T, R), 25 | case R of 26 | NewState when is_reference(NewState) -> 27 | {T, NewState}; 28 | Other -> 29 | Other 30 | end). 31 | -define(SHA2_512_OUTPUT_BYTES, 64). 32 | 33 | %%%=================================================================== 34 | %%% API functions 35 | %%%=================================================================== 36 | 37 | hash(sha2_512, In) -> 38 | libdecaf:sha2_512(In, ?SHA2_512_OUTPUT_BYTES); 39 | hash(Type, In) -> 40 | erlang:error({badarg, [Type, In]}). 41 | 42 | hash(sha2_512, In, Outlen) -> 43 | libdecaf:sha2_512(In, Outlen); 44 | hash(Type, In, Outlen) -> 45 | erlang:error({badarg, [Type, In, Outlen]}). 46 | 47 | init(sha2_512) -> 48 | ?WRAP_STATE(sha2_512, libdecaf:sha2_512_init()); 49 | init(Type) -> 50 | erlang:error({badarg, [Type]}). 51 | 52 | update({sha2_512, State}, In) -> 53 | ?WRAP_STATE(sha2_512, libdecaf:sha2_512_update(State, In)); 54 | update(State, In) -> 55 | erlang:error({badarg, [State, In]}). 56 | 57 | final({sha2_512, State}) -> 58 | libdecaf:sha2_512_final(State, ?SHA2_512_OUTPUT_BYTES); 59 | final(State) -> 60 | erlang:error({badarg, [State]}). 61 | 62 | final({sha2_512, State}, Outlen) -> 63 | libdecaf:sha2_512_final(State, Outlen); 64 | final(State, Outlen) -> 65 | erlang:error({badarg, [State, Outlen]}). 66 | 67 | %%%------------------------------------------------------------------- 68 | %%% Internal functions 69 | %%%------------------------------------------------------------------- 70 | -------------------------------------------------------------------------------- /src/libdecaf_sha3.erl: -------------------------------------------------------------------------------- 1 | %% -*- mode: erlang; tab-width: 4; indent-tabs-mode: 1; st-rulers: [70] -*- 2 | %% vim: ts=4 sw=4 ft=erlang noet 3 | %%%------------------------------------------------------------------- 4 | %%% @author Andrew Bennett 5 | %%% @copyright 2015-2022, Andrew Bennett 6 | %%% @doc 7 | %%% 8 | %%% @end 9 | %%% Created : 29 Feb 2016 by Andrew Bennett 10 | %%%------------------------------------------------------------------- 11 | -module(libdecaf_sha3). 12 | 13 | %% API 14 | -export([ 15 | hash/2, 16 | hash/3, 17 | xof/3, 18 | init/1, 19 | update/2, 20 | final/1, 21 | final/2 22 | ]). 23 | 24 | %% Macros 25 | -define(WRAP_STATE(T, R), 26 | case R of 27 | NewState when is_reference(NewState) -> 28 | {T, NewState}; 29 | Other -> 30 | Other 31 | end). 32 | 33 | %%%=================================================================== 34 | %%% API functions 35 | %%%=================================================================== 36 | 37 | hash(sha3_224, In) -> 38 | libdecaf:sha3_224(In); 39 | hash(sha3_256, In) -> 40 | libdecaf:sha3_256(In); 41 | hash(sha3_384, In) -> 42 | libdecaf:sha3_384(In); 43 | hash(sha3_512, In) -> 44 | libdecaf:sha3_512(In); 45 | hash(Type, In) -> 46 | erlang:error({badarg, [Type, In]}). 47 | 48 | hash(sha3_224, In, Outlen) -> 49 | libdecaf:sha3_224(In, Outlen); 50 | hash(sha3_256, In, Outlen) -> 51 | libdecaf:sha3_256(In, Outlen); 52 | hash(sha3_384, In, Outlen) -> 53 | libdecaf:sha3_384(In, Outlen); 54 | hash(sha3_512, In, Outlen) -> 55 | libdecaf:sha3_512(In, Outlen); 56 | hash(shake128, In, Outlen) -> 57 | libdecaf:shake128(In, Outlen); 58 | hash(shake256, In, Outlen) -> 59 | libdecaf:shake256(In, Outlen); 60 | hash(Type, In, Outlen) -> 61 | erlang:error({badarg, [Type, In, Outlen]}). 62 | 63 | xof(shake128, In, Outlen) -> 64 | libdecaf:shake128(In, Outlen); 65 | xof(shake256, In, Outlen) -> 66 | libdecaf:shake256(In, Outlen); 67 | xof(Type, In, Outlen) -> 68 | erlang:error({badarg, [Type, In, Outlen]}). 69 | 70 | init(sha3_224) -> 71 | ?WRAP_STATE(sha3_224, libdecaf:sha3_224_init()); 72 | init(sha3_256) -> 73 | ?WRAP_STATE(sha3_256, libdecaf:sha3_256_init()); 74 | init(sha3_384) -> 75 | ?WRAP_STATE(sha3_384, libdecaf:sha3_384_init()); 76 | init(sha3_512) -> 77 | ?WRAP_STATE(sha3_512, libdecaf:sha3_512_init()); 78 | init(shake128) -> 79 | ?WRAP_STATE(shake128, libdecaf:shake128_init()); 80 | init(shake256) -> 81 | ?WRAP_STATE(shake256, libdecaf:shake256_init()); 82 | init(Type) -> 83 | erlang:error({badarg, [Type]}). 84 | 85 | update({T = sha3_224, State}, In) -> 86 | ?WRAP_STATE(T, libdecaf:sha3_224_update(State, In)); 87 | update({T = sha3_256, State}, In) -> 88 | ?WRAP_STATE(T, libdecaf:sha3_256_update(State, In)); 89 | update({T = sha3_384, State}, In) -> 90 | ?WRAP_STATE(T, libdecaf:sha3_384_update(State, In)); 91 | update({T = sha3_512, State}, In) -> 92 | ?WRAP_STATE(T, libdecaf:sha3_512_update(State, In)); 93 | update({T = shake128, State}, In) -> 94 | ?WRAP_STATE(T, libdecaf:shake128_update(State, In)); 95 | update({T = shake256, State}, In) -> 96 | ?WRAP_STATE(T, libdecaf:shake256_update(State, In)); 97 | update(State, In) -> 98 | erlang:error({badarg, [State, In]}). 99 | 100 | final({sha3_224, State}) -> 101 | libdecaf:sha3_224_final(State); 102 | final({sha3_256, State}) -> 103 | libdecaf:sha3_256_final(State); 104 | final({sha3_384, State}) -> 105 | libdecaf:sha3_384_final(State); 106 | final({sha3_512, State}) -> 107 | libdecaf:sha3_512_final(State); 108 | final(State) -> 109 | erlang:error({badarg, [State]}). 110 | 111 | final({sha3_224, State}, Outlen) -> 112 | libdecaf:sha3_224_final(State, Outlen); 113 | final({sha3_256, State}, Outlen) -> 114 | libdecaf:sha3_256_final(State, Outlen); 115 | final({sha3_384, State}, Outlen) -> 116 | libdecaf:sha3_384_final(State, Outlen); 117 | final({sha3_512, State}, Outlen) -> 118 | libdecaf:sha3_512_final(State, Outlen); 119 | final({shake128, State}, Outlen) -> 120 | libdecaf:shake128_final(State, Outlen); 121 | final({shake256, State}, Outlen) -> 122 | libdecaf:shake256_final(State, Outlen); 123 | final(State, Outlen) -> 124 | erlang:error({badarg, [State, Outlen]}). 125 | 126 | %%%------------------------------------------------------------------- 127 | %%% Internal functions 128 | %%%------------------------------------------------------------------- 129 | -------------------------------------------------------------------------------- /src/libdecaf_spongerng.erl: -------------------------------------------------------------------------------- 1 | %% -*- mode: erlang; tab-width: 4; indent-tabs-mode: 1; st-rulers: [70] -*- 2 | %% vim: ts=4 sw=4 ft=erlang noet 3 | %%%------------------------------------------------------------------- 4 | %%% @author Andrew Bennett 5 | %%% @copyright 2015-2022, Andrew Bennett 6 | %%% @doc 7 | %%% 8 | %%% @end 9 | %%% Created : 30 Nov 2018 by Andrew Bennett 10 | %%%------------------------------------------------------------------- 11 | -module(libdecaf_spongerng). 12 | 13 | %% API 14 | -export([ 15 | init_from_buffer/2, 16 | init_from_file/3, 17 | init_from_dev_urandom/0, 18 | next/2, 19 | stir/2 20 | ]). 21 | 22 | %% Macros 23 | -define(WRAP_STATE(T, R), 24 | case R of 25 | {NewState, Result} when is_reference(NewState) -> 26 | {{T, NewState}, Result}; 27 | NewState when is_reference(NewState) -> 28 | {T, NewState}; 29 | Other -> 30 | Other 31 | end). 32 | 33 | %%%=================================================================== 34 | %%% API functions 35 | %%%=================================================================== 36 | 37 | init_from_buffer(In, Deterministic) when is_boolean(Deterministic) -> 38 | ?WRAP_STATE(spongerng, libdecaf:spongerng_init_from_buffer(In, Deterministic)). 39 | 40 | init_from_file(Filename, Inlen, Deterministic) when is_boolean(Deterministic) -> 41 | ?WRAP_STATE(spongerng, libdecaf:spongerng_init_from_file(Filename, Inlen, Deterministic)). 42 | 43 | init_from_dev_urandom() -> 44 | ?WRAP_STATE(spongerng, libdecaf:spongerng_init_from_dev_urandom()). 45 | 46 | next({spongerng, State}, Outlen) -> 47 | ?WRAP_STATE(spongerng, libdecaf:spongerng_next(State, Outlen)). 48 | 49 | stir({spongerng, State}, In) -> 50 | ?WRAP_STATE(spongerng, libdecaf:spongerng_stir(State, In)). 51 | 52 | %%%------------------------------------------------------------------- 53 | %%% Internal functions 54 | %%%------------------------------------------------------------------- 55 | -------------------------------------------------------------------------------- /test/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG OTP_VERSION 2 | FROM hexpm/erlang:${OTP_VERSION} 3 | 4 | # Setup environment 5 | ENV LANG=C.UTF-8 TERM=xterm 6 | 7 | # Add dependencies 8 | RUN apk upgrade --update musl && \ 9 | apk add --no-cache autoconf automake bash bc build-base cmake curl git libtool make openssl python3 rsync unzip && \ 10 | rm -rf /var/cache/apk/* && \ 11 | ln -s /usr/bin/python3 /usr/bin/python 12 | 13 | RUN mkdir /build 14 | WORKDIR /build 15 | -------------------------------------------------------------------------------- /test/fetch.erl: -------------------------------------------------------------------------------- 1 | %% -*- mode: erlang; tab-width: 4; indent-tabs-mode: 1; st-rulers: [70] -*- 2 | %% vim: ts=4 sw=4 ft=erlang noet 3 | %%%------------------------------------------------------------------- 4 | %%% @author Andrew Bennett 5 | %%% @copyright 2014-2022, Andrew Bennett 6 | %%% @doc Based on core_http_get.erl 7 | %%% See [https://github.com/ninenines/erlang.mk/blob/0eb54a71605a955df14c5df793ebe676c86259f9/core/core.mk] 8 | %%% @end 9 | %%% Created : 13 Aug 2015 by Andrew Bennett 10 | %%%------------------------------------------------------------------- 11 | -module(fetch). 12 | 13 | %% API 14 | -export([fetch/2]). 15 | 16 | %%==================================================================== 17 | %% API functions 18 | %%==================================================================== 19 | 20 | fetch(URL = "ftp" ++ _, OutputFile) -> 21 | ssl:start(), 22 | inets:start(), 23 | << "ftp://", HostPath/binary >> = list_to_binary(URL), 24 | [Host | Paths] = binary:split(HostPath, << $/ >>, [global]), 25 | [File | RevPath] = lists:reverse(Paths), 26 | Path = lists:reverse(RevPath), 27 | HostString = binary_to_list(Host), 28 | FileString = binary_to_list(File), 29 | PathString = lists:flatten([[binary_to_list(P), $/] || P <- Path]), 30 | case ftp:open(HostString) of 31 | {ok, Pid} -> 32 | case ftp:user(Pid, "anonymous", "") of 33 | ok -> 34 | case ftp:type(Pid, binary) of 35 | ok -> 36 | case ftp:cd(Pid, PathString) of 37 | ok -> 38 | case ftp:recv_bin(Pid, FileString) of 39 | {ok, Body} -> 40 | _ = (catch ftp:close(Pid)), 41 | file:write_file(OutputFile, Body); 42 | RecvError -> 43 | _ = (catch ftp:close(Pid)), 44 | RecvError 45 | end; 46 | CdError -> 47 | _ = (catch ftp:close(Pid)), 48 | CdError 49 | end; 50 | TypeError -> 51 | _ = (catch ftp:close(Pid)), 52 | TypeError 53 | end; 54 | UserError -> 55 | _ = (catch ftp:close(Pid)), 56 | UserError 57 | end; 58 | OpenError -> 59 | OpenError 60 | end; 61 | fetch(URL = "http" ++ _, File) -> 62 | ssl:start(), 63 | inets:start(), 64 | case httpc:request(get, {URL, []}, [{autoredirect, true}], []) of 65 | {ok, {{_, 200, _}, _, Body}} -> 66 | file:write_file(File, Body); 67 | Error -> 68 | Error 69 | end. 70 | 71 | %%%------------------------------------------------------------------- 72 | %%% Internal functions 73 | %%%------------------------------------------------------------------- 74 | -------------------------------------------------------------------------------- /test/fips180_4_SUITE.erl: -------------------------------------------------------------------------------- 1 | %% -*- mode: erlang; tab-width: 4; indent-tabs-mode: 1; st-rulers: [70] -*- 2 | %% vim: ts=4 sw=4 ft=erlang noet 3 | %%%------------------------------------------------------------------- 4 | %%% @author Andrew Bennett 5 | %%% @copyright 2014-2022, Andrew Bennett 6 | %%% @doc 7 | %%% 8 | %%% @end 9 | %%% Created : 29 Feb 2016 by Andrew Bennett 10 | %%%------------------------------------------------------------------- 11 | -module(fips180_4_SUITE). 12 | 13 | -include_lib("common_test/include/ct.hrl"). 14 | 15 | -include_lib("public_key/include/public_key.hrl"). 16 | -include_lib("stdlib/include/zip.hrl"). 17 | 18 | %% ct. 19 | -export([all/0]). 20 | -export([groups/0]). 21 | -export([init_per_suite/1]). 22 | -export([end_per_suite/1]). 23 | -export([init_per_group/2]). 24 | -export([end_per_group/2]). 25 | 26 | %% Tests. 27 | -export([fips180_4/1]). 28 | 29 | %% Macros. 30 | -define(tv_ok(T, M, F, A, E), 31 | case erlang:apply(M, F, A) of 32 | E -> 33 | ok; 34 | T -> 35 | ct:fail({{M, F, A}, {expected, E}, {got, T}}) 36 | end). 37 | 38 | all() -> 39 | [ 40 | {group, 'shabytetestvectors'} 41 | ]. 42 | 43 | groups() -> 44 | [ 45 | {'shabytetestvectors', [], [ 46 | fips180_4 47 | ]} 48 | ]. 49 | 50 | init_per_suite(Config) -> 51 | _ = application:ensure_all_started(libdecaf), 52 | data_setup(Config). 53 | 54 | end_per_suite(_Config) -> 55 | _ = application:stop(libdecaf), 56 | ok. 57 | 58 | init_per_group(G='shabytetestvectors', Config) -> 59 | Folder = data_file("shabytetestvectors", Config), 60 | {ok, Entries} = file:list_dir(Folder), 61 | Files = [filename:join([Folder, Entry]) || Entry <- Entries], 62 | [{'fips180-4_files', Files} | libdecaf_ct:start(G, Config)]. 63 | 64 | end_per_group(_Group, Config) -> 65 | libdecaf_ct:stop(Config), 66 | ok. 67 | 68 | %%==================================================================== 69 | %% Tests 70 | %%==================================================================== 71 | 72 | fips180_4(Config) -> 73 | Files = [File || File <- ?config('fips180-4_files', Config)], 74 | lists:foldl(fun fips180_4/2, Config, Files). 75 | 76 | %%%------------------------------------------------------------------- 77 | %%% Internal functions 78 | %%%------------------------------------------------------------------- 79 | 80 | %% @private 81 | data_file(File, Config) -> 82 | filename:join([?config(data_dir, Config), File]). 83 | 84 | %% @private 85 | data_setup(Config) -> 86 | lists:foldl(fun(F, C) -> 87 | io:format(user, "\e[0;36m[FETCH] ~s\e[0m", [F]), 88 | {ok, Progress} = libdecaf_ct:progress_start(), 89 | NewC = data_setup(F, C), 90 | ok = libdecaf_ct:progress_stop(Progress), 91 | NewC 92 | end, Config, [ 93 | "shabytetestvectors" 94 | ]). 95 | 96 | %% @private 97 | data_setup(F = "shabytetestvectors", Config) -> 98 | BaseURL = "https://raw.github.com/coruus/nist-testvectors/2841a2d486a155c8c79c1e6b2fe5a653e7276d96/csrc.nist.gov/groups/STM/cavp/documents/shs/shabytetestvectors/", 99 | Files = [ 100 | "SHA512LongMsg.rsp", 101 | "SHA512ShortMsg.rsp" 102 | ], 103 | URLs = [BaseURL ++ File || File <- Files], 104 | Directory = data_file(F, Config), 105 | DataFiles = [data_file(filename:join(F, File), Config) || File <- Files], 106 | ok = data_setup_multiple(DataFiles, Directory, URLs), 107 | Config. 108 | 109 | %% @private 110 | data_setup_multiple([DataFile | DataFiles], Directory, [URL | URLs]) -> 111 | case filelib:is_dir(Directory) of 112 | true -> 113 | ok; 114 | false -> 115 | ok = file:make_dir(Directory) 116 | end, 117 | case filelib:is_file(DataFile) of 118 | true -> 119 | ok; 120 | false -> 121 | ok = fetch:fetch(URL, DataFile) 122 | end, 123 | data_setup_multiple(DataFiles, Directory, URLs); 124 | data_setup_multiple([], _Directory, []) -> 125 | ok. 126 | 127 | %% @private 128 | fips180_4(File, Config) -> 129 | Vectors = fips_testvector:from_file(File), 130 | io:format("~s", [filename:basename(File)]), 131 | fips180_4_test(Vectors, Config). 132 | 133 | %% @private 134 | fips180_4_test([ 135 | {option, {<<"L">>, LBin}} 136 | | Vectors 137 | ], Config) -> 138 | LInt = binary_to_integer(LBin), 139 | fips180_4_test(Vectors, LInt, Config); 140 | fips180_4_test([Vector | _Vectors], _Config) -> 141 | ct:fail("Unhandled test vector: ~p~n", [Vector]). 142 | 143 | %% @private 144 | fips180_4_test([ 145 | {vector, {<<"Len">>, Len}, _}, 146 | {vector, {<<"Msg">>, Msg}, _}, 147 | {vector, {<<"MD">>, MD}, _} 148 | | Vectors 149 | ], OutputByteLen, Config) when Len rem 8 =:= 0 -> 150 | InputBytes = binary:part(Msg, 0, Len div 8), 151 | ?tv_ok(T0, libdecaf_sha2, hash, [sha2_512, InputBytes, OutputByteLen], MD), 152 | Context0 = libdecaf_sha2:init(sha2_512), 153 | Context1 = libdecaf_sha2:update(Context0, InputBytes), 154 | ?tv_ok(T1, libdecaf_sha2, final, [Context1, OutputByteLen], MD), 155 | fips180_4_test(Vectors, OutputByteLen, Config); 156 | % fips180_4_test([ 157 | % {vector, {<<"Seed">>, Seed}, _} 158 | % | Vectors 159 | % ], OutputByteLen, Config) -> 160 | % fips180_4_test(Vectors, Seed, OutputByteLen, Config); 161 | fips180_4_test([], _OutputByteLen, _Config) -> 162 | ok; 163 | fips180_4_test(Vectors, _Opts, _Config) -> 164 | ct:fail("Unhandled test vectors: ~p~n", [Vectors]), 165 | ok. 166 | 167 | % %% @private 168 | % fips180_4_test([ 169 | % {vector, {<<"COUNT">>, Count}, _}, 170 | % {vector, {<<"MD">>, MD}, _} 171 | % | Vectors 172 | % ], InputBytes, OutputByteLen, Config) -> 173 | % io:format("\tCOUNT = ~w", [Count]), 174 | % ?tv_ok(T0, libdecaf_sha2, hash, [sha2_512, InputBytes, OutputByteLen], MD), 175 | % Context0 = libdecaf_sha2:init(sha2_512), 176 | % Context1 = libdecaf_sha2:update(Context0, InputBytes), 177 | % ?tv_ok(T1, libdecaf_sha2, final, [Context1, OutputByteLen], MD), 178 | % fips180_4_test(Vectors, MD, OutputByteLen, Config); 179 | % fips180_4_test([], _Seed, _OutputByteLen, _Config) -> 180 | % ok; 181 | % fips180_4_test(Vectors, _Seed, _OutputByteLen, _Config) -> 182 | % ct:fail("Unhandled test vectors: ~p~n", [Vectors]). 183 | -------------------------------------------------------------------------------- /test/fips180_4_SUITE_data/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/potatosalad/erlang-libdecaf/b1588e47ab3e7790446943cadd531610919e193f/test/fips180_4_SUITE_data/.keep -------------------------------------------------------------------------------- /test/fips202_SUITE.erl: -------------------------------------------------------------------------------- 1 | %% -*- mode: erlang; tab-width: 4; indent-tabs-mode: 1; st-rulers: [70] -*- 2 | %% vim: ts=4 sw=4 ft=erlang noet 3 | %%%------------------------------------------------------------------- 4 | %%% @author Andrew Bennett 5 | %%% @copyright 2014-2022, Andrew Bennett 6 | %%% @doc 7 | %%% 8 | %%% @end 9 | %%% Created : 29 Feb 2016 by Andrew Bennett 10 | %%%------------------------------------------------------------------- 11 | -module(fips202_SUITE). 12 | 13 | -include_lib("common_test/include/ct.hrl"). 14 | 15 | -include_lib("public_key/include/public_key.hrl"). 16 | -include_lib("stdlib/include/zip.hrl"). 17 | 18 | %% ct. 19 | -export([all/0]). 20 | -export([groups/0]). 21 | -export([init_per_suite/1]). 22 | -export([end_per_suite/1]). 23 | -export([init_per_group/2]). 24 | -export([end_per_group/2]). 25 | 26 | %% Tests. 27 | -export([fips202/1]). 28 | 29 | %% Macros. 30 | -define(tv_ok(T, M, F, A, E), 31 | case erlang:apply(M, F, A) of 32 | E -> 33 | ok; 34 | T -> 35 | ct:fail({{M, F, A}, {expected, E}, {got, T}}) 36 | end). 37 | 38 | all() -> 39 | [ 40 | {group, 'keccaktestvectors'} 41 | ]. 42 | 43 | groups() -> 44 | [ 45 | {'keccaktestvectors', [], [ 46 | fips202 47 | ]} 48 | ]. 49 | 50 | init_per_suite(Config) -> 51 | _ = application:ensure_all_started(libdecaf), 52 | data_setup(Config). 53 | 54 | end_per_suite(_Config) -> 55 | _ = application:stop(libdecaf), 56 | ok. 57 | 58 | init_per_group(G='keccaktestvectors', Config) -> 59 | Folder = data_file("keccaktestvectors", Config), 60 | {ok, Entries} = file:list_dir(Folder), 61 | Files = [filename:join([Folder, Entry]) || Entry <- Entries], 62 | [{fips202_files, Files} | libdecaf_ct:start(G, Config)]. 63 | 64 | end_per_group(_Group, Config) -> 65 | libdecaf_ct:stop(Config), 66 | ok. 67 | 68 | %%==================================================================== 69 | %% Tests 70 | %%==================================================================== 71 | 72 | fips202(Config) -> 73 | Files = [File || File <- ?config(fips202_files, Config)], 74 | lists:foldl(fun fips202/2, Config, Files). 75 | 76 | %%%------------------------------------------------------------------- 77 | %%% Internal functions 78 | %%%------------------------------------------------------------------- 79 | 80 | %% @private 81 | data_file(File, Config) -> 82 | filename:join([?config(data_dir, Config), File]). 83 | 84 | %% @private 85 | data_setup(Config) -> 86 | lists:foldl(fun(F, C) -> 87 | io:format(user, "\e[0;36m[FETCH] ~s\e[0m", [F]), 88 | {ok, Progress} = libdecaf_ct:progress_start(), 89 | NewC = data_setup(F, C), 90 | ok = libdecaf_ct:progress_stop(Progress), 91 | NewC 92 | end, Config, [ 93 | "keccaktestvectors" 94 | ]). 95 | 96 | %% @private 97 | data_setup(F = "keccaktestvectors", Config) -> 98 | BaseURL = "https://raw.github.com/XKCP/XKCP/fc23735511f06ff57d47f9c47dc950eaf913c83b/tests/TestVectors/", 99 | Files = [ 100 | "ShortMsgKAT_SHA3-224.txt", 101 | "ShortMsgKAT_SHA3-256.txt", 102 | "ShortMsgKAT_SHA3-384.txt", 103 | "ShortMsgKAT_SHA3-512.txt", 104 | "ShortMsgKAT_SHAKE128.txt", 105 | "ShortMsgKAT_SHAKE256.txt" 106 | ], 107 | URLs = [BaseURL ++ File || File <- Files], 108 | Directory = data_file(F, Config), 109 | DataFiles = [data_file(filename:join(F, File), Config) || File <- Files], 110 | ok = data_setup_multiple(DataFiles, Directory, URLs), 111 | Config. 112 | 113 | %% @private 114 | data_setup_multiple([DataFile | DataFiles], Directory, [URL | URLs]) -> 115 | case filelib:is_dir(Directory) of 116 | true -> 117 | ok; 118 | false -> 119 | ok = file:make_dir(Directory) 120 | end, 121 | case filelib:is_file(DataFile) of 122 | true -> 123 | ok; 124 | false -> 125 | ok = fetch:fetch(URL, DataFile) 126 | end, 127 | data_setup_multiple(DataFiles, Directory, URLs); 128 | data_setup_multiple([], _Directory, []) -> 129 | ok. 130 | 131 | %% @private 132 | fips202(File, Config) -> 133 | Options = case iolist_to_binary(filename:basename(File)) of 134 | << "ShortMsgKAT_SHA3-", BitsBin:3/binary, _/binary >> -> 135 | Bits = binary_to_integer(BitsBin), 136 | Bytes = (Bits + 7) div 8, 137 | Type = list_to_atom("sha3_" ++ integer_to_list(Bits)), 138 | Arity = 1, 139 | {Type, Arity, Bytes}; 140 | << "ShortMsgKAT_SHAKE", BitsBin:3/binary, _/binary >> -> 141 | Bits = binary_to_integer(BitsBin), 142 | Bytes = 512, 143 | Type = list_to_atom("shake" ++ integer_to_list(Bits)), 144 | Arity = 2, 145 | {Type, Arity, Bytes} 146 | end, 147 | Vectors = fips_testvector:from_file(File), 148 | io:format("~s", [filename:basename(File)]), 149 | fips202(Vectors, Options, Config). 150 | 151 | %% @private 152 | fips202([ 153 | {vector, {<<"Len">>, Len}, _}, 154 | {vector, {<<"Msg">>, Msg}, _}, 155 | {vector, {<<"MD">>, MD}, _} 156 | | Vectors 157 | ], {Type, Arity=1, OutputByteLen}, Config) when Len rem 8 =:= 0 -> 158 | InputBytes = binary:part(Msg, 0, Len div 8), 159 | ?tv_ok(T0, libdecaf_sha3, hash, [Type, InputBytes], MD), 160 | Sponge0 = libdecaf_sha3:init(Type), 161 | Sponge1 = libdecaf_sha3:update(Sponge0, InputBytes), 162 | ?tv_ok(T1, libdecaf_sha3, final, [Sponge1], MD), 163 | fips202(Vectors, {Type, Arity, OutputByteLen}, Config); 164 | fips202([ 165 | {vector, {<<"Len">>, Len}, _}, 166 | {vector, {<<"Msg">>, Msg}, _}, 167 | {vector, {<<"Squeezed">>, Squeezed}, _} 168 | | Vectors 169 | ], {Type, Arity=2, OutputByteLen}, Config) when Len rem 8 =:= 0 -> 170 | InputBytes = binary:part(Msg, 0, Len div 8), 171 | ?tv_ok(T0, libdecaf_sha3, xof, [Type, InputBytes, OutputByteLen], Squeezed), 172 | Sponge0 = libdecaf_sha3:init(Type), 173 | Sponge1 = libdecaf_sha3:update(Sponge0, InputBytes), 174 | ?tv_ok(T1, libdecaf_sha3, final, [Sponge1, OutputByteLen], Squeezed), 175 | fips202(Vectors, {Type, Arity, OutputByteLen}, Config); 176 | fips202([ 177 | {vector, {<<"Len">>, _Len}, _}, 178 | {vector, {<<"Msg">>, _Msg}, _}, 179 | {vector, {<<"MD">>, _MD}, _} 180 | | Vectors 181 | ], Options, Config) -> 182 | fips202(Vectors, Options, Config); 183 | fips202([ 184 | {vector, {<<"Len">>, _Len}, _}, 185 | {vector, {<<"Msg">>, _Msg}, _}, 186 | {vector, {<<"Squeezed">>, _Squeezed}, _} 187 | | Vectors 188 | ], Options, Config) -> 189 | fips202(Vectors, Options, Config); 190 | fips202([], _Opts, _Config) -> 191 | ok. 192 | -------------------------------------------------------------------------------- /test/fips202_SUITE_data/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/potatosalad/erlang-libdecaf/b1588e47ab3e7790446943cadd531610919e193f/test/fips202_SUITE_data/.keep -------------------------------------------------------------------------------- /test/hex.erl: -------------------------------------------------------------------------------- 1 | %% -*- mode: erlang; tab-width: 4; indent-tabs-mode: 1; st-rulers: [70] -*- 2 | %% vim: ts=4 sw=4 ft=erlang noet 3 | %%%------------------------------------------------------------------- 4 | %%% @author Andrew Bennett 5 | %%% @copyright 2014-2022, Andrew Bennett 6 | %%% @doc 7 | %%% 8 | %%% @end 9 | %%% Created : 12 Aug 2015 by Andrew Bennett 10 | %%%------------------------------------------------------------------- 11 | -module(hex). 12 | 13 | %% API 14 | -export([bin_to_hex/1]). 15 | -export([hex_to_bin/1]). 16 | 17 | -define(HEX_TO_INT(C), 18 | case C of 19 | $0 -> 16#0; 20 | $1 -> 16#1; 21 | $2 -> 16#2; 22 | $3 -> 16#3; 23 | $4 -> 16#4; 24 | $5 -> 16#5; 25 | $6 -> 16#6; 26 | $7 -> 16#7; 27 | $8 -> 16#8; 28 | $9 -> 16#9; 29 | $a -> 16#A; 30 | $b -> 16#B; 31 | $c -> 16#C; 32 | $d -> 16#D; 33 | $e -> 16#E; 34 | $f -> 16#F; 35 | $A -> 16#A; 36 | $B -> 16#B; 37 | $C -> 16#C; 38 | $D -> 16#D; 39 | $E -> 16#E; 40 | $F -> 16#F 41 | end). 42 | 43 | -define(INT_TO_HEX(C), 44 | case C of 45 | 16#0 -> $0; 46 | 16#1 -> $1; 47 | 16#2 -> $2; 48 | 16#3 -> $3; 49 | 16#4 -> $4; 50 | 16#5 -> $5; 51 | 16#6 -> $6; 52 | 16#7 -> $7; 53 | 16#8 -> $8; 54 | 16#9 -> $9; 55 | 16#A -> $a; 56 | 16#B -> $b; 57 | 16#C -> $c; 58 | 16#D -> $d; 59 | 16#E -> $e; 60 | 16#F -> $f 61 | end). 62 | 63 | %%==================================================================== 64 | %% API functions 65 | %%==================================================================== 66 | 67 | bin_to_hex(Bin) -> 68 | << << (?INT_TO_HEX(V bsr 4)), (?INT_TO_HEX(V band 16#F)) >> || << V >> <= Bin >>. 69 | 70 | hex_to_bin(Hex) -> 71 | << << ((?HEX_TO_INT(X) bsl 4) + ?HEX_TO_INT(Y)) >> || << X, Y >> <= Hex >>. 72 | 73 | %%%------------------------------------------------------------------- 74 | %%% Internal functions 75 | %%%------------------------------------------------------------------- 76 | -------------------------------------------------------------------------------- /test/legacy_keccak_SUITE.erl: -------------------------------------------------------------------------------- 1 | %% -*- mode: erlang; tab-width: 4; indent-tabs-mode: 1; st-rulers: [70] -*- 2 | %% vim: ts=4 sw=4 ft=erlang noet 3 | -module(legacy_keccak_SUITE). 4 | 5 | -include_lib("common_test/include/ct.hrl"). 6 | 7 | -include_lib("public_key/include/public_key.hrl"). 8 | -include_lib("stdlib/include/zip.hrl"). 9 | 10 | %% ct. 11 | -export([all/0]). 12 | -export([groups/0]). 13 | -export([init_per_suite/1]). 14 | -export([end_per_suite/1]). 15 | -export([init_per_group/2]). 16 | -export([end_per_group/2]). 17 | 18 | %% Tests. 19 | -export([legacy_keccak/1]). 20 | 21 | %% Macros. 22 | -define(tv_ok(T, M, F, A, E), 23 | case erlang:apply(M, F, A) of 24 | E -> 25 | ok; 26 | T -> 27 | ct:fail({{M, F, A}, {expected, E}, {got, T}}) 28 | end). 29 | 30 | all() -> 31 | [ 32 | {group, 'keccaktestvectors'} 33 | ]. 34 | 35 | groups() -> 36 | [ 37 | {'keccaktestvectors', [], [ 38 | legacy_keccak 39 | ]} 40 | ]. 41 | 42 | init_per_suite(Config) -> 43 | _ = application:ensure_all_started(libdecaf), 44 | data_setup(Config). 45 | 46 | end_per_suite(_Config) -> 47 | _ = application:stop(libdecaf), 48 | ok. 49 | 50 | init_per_group(G='keccaktestvectors', Config) -> 51 | Folder = data_file("keccaktestvectors", Config), 52 | {ok, Entries} = file:list_dir(Folder), 53 | Files = [filename:join([Folder, Entry]) || Entry <- Entries], 54 | [{test_data_files, Files} | libdecaf_ct:start(G, Config)]. 55 | 56 | end_per_group(_Group, Config) -> 57 | libdecaf_ct:stop(Config), 58 | ok. 59 | 60 | %%==================================================================== 61 | %% Tests 62 | %%==================================================================== 63 | 64 | legacy_keccak(Config) -> 65 | Files = [File || File <- ?config(test_data_files, Config)], 66 | lists:foldl(fun legacy_keccak/2, Config, Files). 67 | 68 | %%%------------------------------------------------------------------- 69 | %%% Internal functions 70 | %%%------------------------------------------------------------------- 71 | 72 | %% @private 73 | data_file(File, Config) -> 74 | filename:join([?config(data_dir, Config), File]). 75 | 76 | %% @private 77 | data_setup(Config) -> 78 | lists:foldl(fun(F, C) -> 79 | io:format(user, "\e[0;36m[FETCH] ~s\e[0m", [F]), 80 | {ok, Progress} = libdecaf_ct:progress_start(), 81 | NewC = data_setup(F, C), 82 | ok = libdecaf_ct:progress_stop(Progress), 83 | NewC 84 | end, Config, [ 85 | "keccaktestvectors" 86 | ]). 87 | 88 | %% @private 89 | data_setup(F = "keccaktestvectors", Config) -> 90 | ArchiveURL = "https://keccak.team/obsolete/KeccakKAT-3.zip", 91 | 92 | Files = [ 93 | "ShortMsgKAT_224.txt", 94 | "ShortMsgKAT_256.txt", 95 | "ShortMsgKAT_384.txt", 96 | "ShortMsgKAT_512.txt" 97 | ], 98 | 99 | TempDirectory = data_file("temp", Config), 100 | ArchiveFile = filename:join(TempDirectory, "KeccakKAT-3.zip"), 101 | ok = download_archive(ArchiveURL, TempDirectory, ArchiveFile), 102 | FileList = [filename:join("KeccakKAT", File) || File <- Files], 103 | UnzipOpts = [{file_list, FileList}, {cwd, TempDirectory}, keep_old_files], 104 | {ok, ExtractedFileList} = zip:unzip(ArchiveFile, UnzipOpts), 105 | 106 | Directory = data_file(F, Config), 107 | ok = copy_files_to_dir(ExtractedFileList, Directory), 108 | 109 | Config. 110 | 111 | %% @private 112 | download_archive(ArchiveURL, Directory, ArchiveFile) -> 113 | mkdir_p(Directory), 114 | case filelib:is_file(ArchiveFile) of 115 | true -> 116 | ok; 117 | false -> 118 | ok = fetch:fetch(ArchiveURL, ArchiveFile) 119 | end. 120 | 121 | %% @private 122 | mkdir_p(Directory) -> 123 | case filelib:is_dir(Directory) of 124 | true -> 125 | ok; 126 | false -> 127 | ok = file:make_dir(Directory) 128 | end. 129 | 130 | %% @private 131 | copy_files_to_dir([File | FileList], Directory) -> 132 | mkdir_p(Directory), 133 | Destination = filename:join(Directory, filename:basename(File)), 134 | case filelib:is_file(Destination) of 135 | true -> 136 | ok; 137 | false -> 138 | {ok, _} = file:copy(File, Destination) 139 | end, 140 | copy_files_to_dir(FileList, Directory); 141 | copy_files_to_dir([], _Directory) -> 142 | ok. 143 | 144 | %% @private 145 | legacy_keccak(File, Config) -> 146 | << "ShortMsgKAT_", BitsBin:3/binary, _/binary >> = iolist_to_binary(filename:basename(File)), 147 | Bits = binary_to_integer(BitsBin), 148 | Bytes = (Bits + 7) div 8, 149 | Type = list_to_atom("keccak_" ++ integer_to_list(Bits)), 150 | Arity = 1, 151 | 152 | Options = {Type, Arity, Bytes}, 153 | Vectors = fips_testvector:from_file(File), 154 | io:format("~s", [filename:basename(File)]), 155 | legacy_keccak(Vectors, Options, Config). 156 | 157 | %% @private 158 | legacy_keccak([ 159 | {vector, {<<"Len">>, Len}, _}, 160 | {vector, {<<"Msg">>, Msg}, _}, 161 | {vector, {<<"MD">>, MD}, _} 162 | | Vectors 163 | ], {Type, Arity=1, OutputByteLen}, Config) when Len rem 8 =:= 0 -> 164 | InputBytes = binary:part(Msg, 0, Len div 8), 165 | ?tv_ok(T0, libdecaf_keccak_sha3, hash, [Type, InputBytes], MD), 166 | Sponge0 = libdecaf_keccak_sha3:init(Type), 167 | Sponge1 = libdecaf_keccak_sha3:update(Sponge0, InputBytes), 168 | ?tv_ok(T1, libdecaf_keccak_sha3, final, [Sponge1], MD), 169 | legacy_keccak(Vectors, {Type, Arity, OutputByteLen}, Config); 170 | legacy_keccak([ 171 | {vector, {<<"Len">>, _Len}, _}, 172 | {vector, {<<"Msg">>, _Msg}, _}, 173 | {vector, {<<"MD">>, _MD}, _} 174 | | Vectors 175 | ], Options, Config) -> 176 | legacy_keccak(Vectors, Options, Config); 177 | legacy_keccak([], _Opts, _Config) -> 178 | ok. 179 | -------------------------------------------------------------------------------- /test/legacy_keccak_SUITE_data/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/potatosalad/erlang-libdecaf/b1588e47ab3e7790446943cadd531610919e193f/test/legacy_keccak_SUITE_data/.keep -------------------------------------------------------------------------------- /test/libdecaf_ct.erl: -------------------------------------------------------------------------------- 1 | %% -*- mode: erlang; tab-width: 4; indent-tabs-mode: 1; st-rulers: [70] -*- 2 | %% vim: ts=4 sw=4 ft=erlang noet 3 | -module(libdecaf_ct). 4 | 5 | -include_lib("common_test/include/ct.hrl"). 6 | 7 | %% API 8 | -export([start/2]). 9 | -export([stop/1]). 10 | -export([progress_start/0]). 11 | -export([progress_stop/1]). 12 | 13 | %% Internal API 14 | -export([init/1]). 15 | 16 | %% Macros 17 | -define(RED, "\e[0;31m"). 18 | -define(GREEN, "\e[0;32m"). 19 | -define(YELLOW, "\e[0;33m"). 20 | -define(WHITE, "\e[0;37m"). 21 | -define(CYAN, "\e[0;36m"). 22 | -define(RESET, "\e[0m"). 23 | -define(TIME, 1000). % timer:seconds(1) 24 | 25 | start(Group, Config) -> 26 | Now = os:timestamp(), 27 | io:format(user, "~s[ ] ~s :: ~s~s", [?WHITE, format_utc_timestamp(Now), Group, ?RESET]), 28 | {ok, Progress} = progress_start(), 29 | [{libdecaf_ct, {Progress, Now}} | Config]. 30 | 31 | stop(Config) -> 32 | Now = os:timestamp(), 33 | {Progress, Old} = ?config(libdecaf_ct, Config), 34 | ok = progress_stop(Progress), 35 | Diff = timer:now_diff(Now, Old), 36 | io:format(user, "~s[OK] ~s :: ~s elapsed~s~n", [?GREEN, format_utc_timestamp(Now), format_elapsed_time(Diff), ?RESET]), 37 | ok. 38 | 39 | progress_start() -> 40 | Ref = erlang:make_ref(), 41 | {ok, Pid} = proc_lib:start(?MODULE, init, [{self(), Ref}]), 42 | {ok, {Ref, Pid}}. 43 | 44 | progress_stop({Ref, Pid}) -> 45 | Pid ! {stop, self(), Ref}, 46 | receive 47 | Ref -> 48 | ok 49 | after 50 | 1000 -> 51 | ok 52 | end. 53 | 54 | %% @private 55 | format_elapsed_time(USec) -> 56 | Micro = USec rem 1000000, 57 | Second = ((USec - Micro) div 1000000) rem 60, 58 | Minute = ((USec - (Second * 1000000)) div 6000000) rem 60, 59 | Hour = ((USec - (Minute * 6000000)) div 360000000) rem 24, 60 | io_lib:format("~2..0w:~2..0w:~2..0w.~6..0w", [Hour,Minute,Second,Micro]). 61 | 62 | %% @private 63 | format_utc_timestamp(TS = {_, _, Micro}) -> 64 | {{Year,Month,Day},{Hour,Minute,Second}} = calendar:now_to_universal_time(TS), 65 | io_lib:format("~4..0w-~2..0w-~2..0w ~2..0w:~2..0w:~2..0w.~6..0w", [Year,Month,Day,Hour,Minute,Second,Micro]). 66 | 67 | %% @private 68 | init({Parent, Ref}) -> 69 | process_flag(trap_exit, true), 70 | ok = proc_lib:init_ack(Parent, {ok, self()}), 71 | {ok, TRef} = timer:send_interval(?TIME, {tick, Ref}), 72 | loop(Ref, TRef). 73 | 74 | %% @private 75 | loop(Ref, TRef) -> 76 | receive 77 | {tick, Ref} -> 78 | io:format(user, "~s.~s", [?WHITE, ?RESET]), 79 | loop(Ref, TRef); 80 | {stop, Parent, Ref} when is_pid(Parent) -> 81 | io:format(user, "~n", []), 82 | catch timer:cancel(TRef), 83 | Parent ! Ref, 84 | exit(normal); 85 | Info -> 86 | io:format(user, "~n~s[~s] received unhandled message:~n~p~s~n", [?RED, ?MODULE, Info, ?RESET]), 87 | loop(Ref, TRef) 88 | end. 89 | -------------------------------------------------------------------------------- /test/spongerng_SUITE_data/seed.txt: -------------------------------------------------------------------------------- 1 | To be, or not to be, that is the question: 2 | Whether 'tis nobler in the mind to suffer 3 | The slings and arrows of outrageous fortune, 4 | Or to take arms against a sea of troubles 5 | And by opposing end them. To die—to sleep, 6 | No more; and by a sleep to say we end 7 | The heart-ache and the thousand natural shocks 8 | That flesh is heir to: 'tis a consummation 9 | Devoutly to be wish'd. To die, to sleep; 10 | To sleep, perchance to dream—ay, there's the rub: 11 | For in that sleep of death what dreams may come, 12 | When we have shuffled off this mortal coil, 13 | Must give us pause—there's the respect 14 | That makes calamity of so long life. 15 | For who would bear the whips and scorns of time, 16 | Th'oppressor's wrong, the proud man's contumely, 17 | The pangs of dispriz'd love, the law's delay, 18 | The insolence of office, and the spurns 19 | That patient merit of th'unworthy takes, 20 | When he himself might his quietus make 21 | With a bare bodkin? Who would fardels bear, 22 | To grunt and sweat under a weary life, 23 | But that the dread of something after death, 24 | The undiscovere'd country, from whose bourn 25 | No traveller returns, puzzles the will, 26 | And makes us rather bear those ills we have 27 | Than fly to others that we know not of? 28 | Thus conscience does make cowards of us all, 29 | And thus the native hue of resolution 30 | Is sicklied o'er with the pale cast of thought, 31 | And enterprises of great pitch and moment 32 | With this regard their currents turn awry 33 | And lose the name of action. --------------------------------------------------------------------------------