├── .gitattributes ├── .gitignore ├── CMakeLists.txt ├── CMakeModules ├── BlackBerry.toolchain.cmake ├── FindCheck.cmake └── iOS.toolchain.cmake ├── ISSUE_TEMPLATE.md ├── LICENSE ├── README.md ├── protobuf ├── FingerprintProtocol.proto ├── LocalStorageProtocol.proto ├── Makefile └── WhisperTextProtocol.proto ├── src ├── CMakeLists.txt ├── FingerprintProtocol.pb-c.c ├── FingerprintProtocol.pb-c.h ├── LocalStorageProtocol.pb-c.c ├── LocalStorageProtocol.pb-c.h ├── WhisperTextProtocol.pb-c.c ├── WhisperTextProtocol.pb-c.h ├── curve.c ├── curve.h ├── curve25519 │ ├── CMakeLists.txt │ ├── curve25519-donna.c │ ├── curve25519-donna.h │ └── ed25519 │ │ ├── additions │ │ ├── compare.c │ │ ├── compare.h │ │ ├── crypto_additions.h │ │ ├── crypto_hash_sha512.h │ │ ├── curve_sigs.c │ │ ├── curve_sigs.h │ │ ├── elligator.c │ │ ├── fe_isequal.c │ │ ├── fe_isreduced.c │ │ ├── fe_mont_rhs.c │ │ ├── fe_montx_to_edy.c │ │ ├── fe_sqrt.c │ │ ├── ge_isneutral.c │ │ ├── ge_montx_to_p3.c │ │ ├── ge_neg.c │ │ ├── ge_p3_to_montx.c │ │ ├── ge_scalarmult.c │ │ ├── ge_scalarmult_cofactor.c │ │ ├── generalized │ │ │ ├── ge_p3_add.c │ │ │ ├── gen_constants.h │ │ │ ├── gen_crypto_additions.h │ │ │ ├── gen_eddsa.c │ │ │ ├── gen_eddsa.h │ │ │ ├── gen_labelset.c │ │ │ ├── gen_labelset.h │ │ │ ├── gen_veddsa.c │ │ │ ├── gen_veddsa.h │ │ │ ├── gen_x.c │ │ │ ├── gen_x.h │ │ │ ├── point_isreduced.c │ │ │ └── sc_isreduced.c │ │ ├── keygen.c │ │ ├── keygen.h │ │ ├── open_modified.c │ │ ├── sc_clamp.c │ │ ├── sc_cmov.c │ │ ├── sc_neg.c │ │ ├── sign_modified.c │ │ ├── utility.c │ │ ├── utility.h │ │ ├── xeddsa.c │ │ ├── xeddsa.h │ │ ├── zeroize.c │ │ └── zeroize.h │ │ ├── base.h │ │ ├── base2.h │ │ ├── d.h │ │ ├── d2.h │ │ ├── fe.h │ │ ├── fe_0.c │ │ ├── fe_1.c │ │ ├── fe_add.c │ │ ├── fe_cmov.c │ │ ├── fe_copy.c │ │ ├── fe_frombytes.c │ │ ├── fe_invert.c │ │ ├── fe_isnegative.c │ │ ├── fe_isnonzero.c │ │ ├── fe_mul.c │ │ ├── fe_neg.c │ │ ├── fe_pow22523.c │ │ ├── fe_sq.c │ │ ├── fe_sq2.c │ │ ├── fe_sub.c │ │ ├── fe_tobytes.c │ │ ├── ge.h │ │ ├── ge_add.c │ │ ├── ge_add.h │ │ ├── ge_double_scalarmult.c │ │ ├── ge_frombytes.c │ │ ├── ge_madd.c │ │ ├── ge_madd.h │ │ ├── ge_msub.c │ │ ├── ge_msub.h │ │ ├── ge_p1p1_to_p2.c │ │ ├── ge_p1p1_to_p3.c │ │ ├── ge_p2_0.c │ │ ├── ge_p2_dbl.c │ │ ├── ge_p2_dbl.h │ │ ├── ge_p3_0.c │ │ ├── ge_p3_dbl.c │ │ ├── ge_p3_to_cached.c │ │ ├── ge_p3_to_p2.c │ │ ├── ge_p3_tobytes.c │ │ ├── ge_precomp_0.c │ │ ├── ge_scalarmult_base.c │ │ ├── ge_sub.c │ │ ├── ge_sub.h │ │ ├── ge_tobytes.c │ │ ├── nacl_includes │ │ ├── crypto_int32.h │ │ ├── crypto_int64.h │ │ ├── crypto_sign.h │ │ ├── crypto_sign_edwards25519sha512batch.h │ │ ├── crypto_uint32.h │ │ ├── crypto_uint64.h │ │ └── crypto_verify_32.h │ │ ├── nacl_sha512 │ │ ├── blocks.c │ │ └── hash.c │ │ ├── open.c │ │ ├── pow22523.h │ │ ├── pow225521.h │ │ ├── sc.h │ │ ├── sc_muladd.c │ │ ├── sc_reduce.c │ │ ├── sign.c │ │ ├── sqrtm1.h │ │ └── tests │ │ ├── internal_fast_tests.c │ │ ├── internal_fast_tests.h │ │ ├── internal_slow_tests.c │ │ └── internal_slow_tests.h ├── device_consistency.c ├── device_consistency.h ├── fingerprint.c ├── fingerprint.h ├── group_cipher.c ├── group_cipher.h ├── group_session_builder.c ├── group_session_builder.h ├── hkdf.c ├── hkdf.h ├── key_helper.c ├── key_helper.h ├── libsignal-protocol-c.pc.in ├── protobuf-c │ ├── CMakeLists.txt │ ├── protobuf-c.c │ └── protobuf-c.h ├── protocol.c ├── protocol.h ├── ratchet.c ├── ratchet.h ├── sender_key.c ├── sender_key.h ├── sender_key_record.c ├── sender_key_record.h ├── sender_key_state.c ├── sender_key_state.h ├── session_builder.c ├── session_builder.h ├── session_builder_internal.h ├── session_cipher.c ├── session_cipher.h ├── session_pre_key.c ├── session_pre_key.h ├── session_record.c ├── session_record.h ├── session_state.c ├── session_state.h ├── signal_protocol.c ├── signal_protocol.h ├── signal_protocol_internal.h ├── signal_protocol_types.h ├── signal_utarray.h ├── utarray.h ├── uthash.h ├── utlist.h ├── vpool.c └── vpool.h └── tests ├── CMakeLists.txt ├── test_common.c ├── test_common.h ├── test_common_ccrypto.c ├── test_common_openssl.c ├── test_curve25519.c ├── test_device_consistency.c ├── test_fingerprint.c ├── test_group_cipher.c ├── test_hkdf.c ├── test_key_helper.c ├── test_protocol.c ├── test_ratchet.c ├── test_sender_key_record.c ├── test_session_builder.c ├── test_session_cipher.c ├── test_session_record.c ├── test_simultaneous_initiate.c └── test_utarray.h /.gitattributes: -------------------------------------------------------------------------------- 1 | # Set default behaviour, in case users don't have core.autocrlf set. 2 | * text=auto 3 | 4 | # Explicitly declare text files we want to always be normalized and converted 5 | # to native line endings on checkout. 6 | *.txt text 7 | *.c text 8 | *.cpp text 9 | *.h text 10 | *.hpp text 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled source 2 | build/ 3 | *.o 4 | *.so 5 | *.so.* 6 | *.a 7 | 8 | # IDE-related files 9 | 10 | # OS generated files 11 | .DS_Store* 12 | Thumbs.db 13 | 14 | # Other 15 | *~ 16 | .* 17 | *.swp 18 | core 19 | *.log 20 | *.zip 21 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8.4) 2 | set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/CMakeModules/") 3 | project(signal-protocol-c) 4 | 5 | if(POLICY CMP0042) 6 | cmake_policy(SET CMP0042 NEW) 7 | endif() 8 | 9 | SET(SIGNAL_PROTOCOL_C_VERSION_MAJOR 2) 10 | SET(SIGNAL_PROTOCOL_C_VERSION_MINOR 3) 11 | SET(SIGNAL_PROTOCOL_C_VERSION_PATCH 3) 12 | SET(SIGNAL_PROTOCOL_C_VERSION ${SIGNAL_PROTOCOL_C_VERSION_MAJOR}.${SIGNAL_PROTOCOL_C_VERSION_MINOR}.${SIGNAL_PROTOCOL_C_VERSION_PATCH}) 13 | 14 | SET(LIB_SUFFIX "" CACHE STRING "Define suffix of directory name (32/64)") 15 | SET(BIN_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/bin" CACHE STRING "The directory the binaries are installed in") 16 | SET(LIB_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}" CACHE STRING "The directory the libraries are installed in") 17 | SET(INCLUDE_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/include" CACHE PATH "The directory the headers are installed in") 18 | SET(INSTALL_PKGCONFIG_DIR "${LIB_INSTALL_DIR}/pkgconfig" CACHE PATH "Installation directory for pkgconfig (.pc) files") 19 | 20 | INCLUDE(CheckSymbolExists) 21 | INCLUDE(CheckCCompilerFlag) 22 | INCLUDE(TestBigEndian) 23 | 24 | CHECK_SYMBOL_EXISTS(memset_s "string.h" HAVE_MEMSET_S) 25 | 26 | IF(CMAKE_SYSTEM_NAME MATCHES "Windows") 27 | CHECK_SYMBOL_EXISTS(SecureZeroMemory "Windows.h;WinBase.h" HAVE_SECUREZEROMEMORY) 28 | ENDIF(CMAKE_SYSTEM_NAME MATCHES "Windows") 29 | 30 | IF(BUILD_TESTING) 31 | enable_testing() 32 | ENDIF(BUILD_TESTING) 33 | 34 | IF(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang") 35 | SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fmessage-length=0 -Wall -Wmissing-field-initializers -Wno-missing-braces -Wparentheses") 36 | ENDIF(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang") 37 | 38 | IF(CMAKE_COMPILER_IS_GNUCC) 39 | CHECK_C_COMPILER_FLAG("-Wsign-conversion" GCC_WARN_SIGN_CONVERSION) 40 | SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wsign-compare") 41 | IF(GCC_WARN_SIGN_CONVERSION) 42 | SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wsign-conversion") 43 | ENDIF(GCC_WARN_SIGN_CONVERSION) 44 | ENDIF(CMAKE_COMPILER_IS_GNUCC) 45 | 46 | IF(CMAKE_C_COMPILER_ID MATCHES "Clang") 47 | SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wswitch -Wunused-variable -Wunused-value -Wshadow -Wint-conversion -Wpointer-sign -Wprotocol -Wshorten-64-to-32") 48 | ENDIF(CMAKE_C_COMPILER_ID MATCHES "Clang") 49 | 50 | IF(HAVE_MEMSET_S) 51 | SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DHAVE_MEMSET_S=1") 52 | ENDIF(HAVE_MEMSET_S) 53 | 54 | TEST_BIG_ENDIAN(WORDS_BIGENDIAN) 55 | IF(WORDS_BIGENDIAN) 56 | ADD_DEFINITIONS(-DWORDS_BIGENDIAN) 57 | ENDIF(WORDS_BIGENDIAN) 58 | 59 | IF(COVERAGE) 60 | SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs -ftest-coverage") 61 | SET(LINK_FLAGS "${LINK_FLAGS} -fprofile-arcs -ftest-coverage") 62 | 63 | add_custom_command(OUTPUT run_coverage 64 | COMMAND ctest 65 | COMMAND lcov -q --capture --directory src --output-file coverage.info.total 66 | COMMAND lcov -q --remove coverage.info.total 'vpool.*' 'ut*.h' '*.pb-c.*' 'protobuf-c/*' 'curve25519/*' --output-file coverage.info 67 | COMMAND genhtml -q coverage.info --output-directory coverage 68 | COMMENT Collecting and creating coverage information 69 | ) 70 | add_custom_target( coverage DEPENDS run_coverage ) 71 | ENDIF(COVERAGE) 72 | 73 | add_subdirectory(src) 74 | 75 | IF(BUILD_TESTING) 76 | add_subdirectory(tests) 77 | ENDIF(BUILD_TESTING) 78 | -------------------------------------------------------------------------------- /CMakeModules/FindCheck.cmake: -------------------------------------------------------------------------------- 1 | # - Try to find the CHECK libraries 2 | # Once done this will define 3 | # 4 | # CHECK_FOUND - system has check 5 | # CHECK_INCLUDE_DIRS - the check include directory 6 | # CHECK_LIBRARIES - check library 7 | # 8 | # Copyright (c) 2007 Daniel Gollub 9 | # Copyright (c) 2007-2009 Bjoern Ricks 10 | # 11 | # Redistribution and use is allowed according to the terms of the New 12 | # BSD license. 13 | # For details see the accompanying COPYING-CMAKE-SCRIPTS file. 14 | 15 | 16 | INCLUDE( FindPkgConfig ) 17 | 18 | IF ( Check_FIND_REQUIRED ) 19 | SET( _pkgconfig_REQUIRED "REQUIRED" ) 20 | ELSE( Check_FIND_REQUIRED ) 21 | SET( _pkgconfig_REQUIRED "" ) 22 | ENDIF ( Check_FIND_REQUIRED ) 23 | 24 | IF ( CHECK_MIN_VERSION ) 25 | PKG_SEARCH_MODULE( CHECK ${_pkgconfig_REQUIRED} check>=${CHECK_MIN_VERSION} ) 26 | ELSE ( CHECK_MIN_VERSION ) 27 | PKG_SEARCH_MODULE( CHECK ${_pkgconfig_REQUIRED} check ) 28 | ENDIF ( CHECK_MIN_VERSION ) 29 | 30 | # Look for CHECK include dir and libraries 31 | IF( NOT CHECK_FOUND AND NOT PKG_CONFIG_FOUND ) 32 | 33 | FIND_PATH( CHECK_INCLUDE_DIRS check.h ) 34 | 35 | FIND_LIBRARY( CHECK_LIBRARIES NAMES check ) 36 | 37 | IF ( CHECK_INCLUDE_DIRS AND CHECK_LIBRARIES ) 38 | SET( CHECK_FOUND 1 ) 39 | IF ( NOT Check_FIND_QUIETLY ) 40 | MESSAGE ( STATUS "Found CHECK: ${CHECK_LIBRARIES}" ) 41 | ENDIF ( NOT Check_FIND_QUIETLY ) 42 | ELSE ( CHECK_INCLUDE_DIRS AND CHECK_LIBRARIES ) 43 | IF ( Check_FIND_REQUIRED ) 44 | MESSAGE( FATAL_ERROR "Could NOT find CHECK" ) 45 | ELSE ( Check_FIND_REQUIRED ) 46 | IF ( NOT Check_FIND_QUIETLY ) 47 | MESSAGE( STATUS "Could NOT find CHECK" ) 48 | ENDIF ( NOT Check_FIND_QUIETLY ) 49 | ENDIF ( Check_FIND_REQUIRED ) 50 | ENDIF ( CHECK_INCLUDE_DIRS AND CHECK_LIBRARIES ) 51 | ENDIF( NOT CHECK_FOUND AND NOT PKG_CONFIG_FOUND ) 52 | 53 | # Hide advanced variables from CMake GUIs 54 | MARK_AS_ADVANCED( CHECK_INCLUDE_DIRS CHECK_LIBRARIES ) 55 | 56 | -------------------------------------------------------------------------------- /ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 13 | 14 | I have: 15 | - [ ] searched open and closed issues for duplicates 16 | 17 | ---------------------------------------- 18 | 19 | ### Bug description 20 | Describe here the issue that you are experiencing. 21 | 22 | ### Steps to reproduce 23 | - using hyphens as bullet points 24 | - list the steps 25 | - that reproduce the bug 26 | 27 | **Actual result:** Describe here what happens after you run the steps above (i.e. the buggy behaviour) 28 | **Expected result:** Describe here what should happen after you run the steps above (i.e. what would be the correct behaviour) 29 | 30 | ### Device info 31 | 32 | **Device:** Manufacturer Model XVI 33 | **Android version:** 0.0.0 34 | **Signal version:** 0.0.0 35 | 36 | ### Link to logs 37 | 38 | 39 | -------------------------------------------------------------------------------- /protobuf/FingerprintProtocol.proto: -------------------------------------------------------------------------------- 1 | package textsecure; 2 | 3 | option java_package = "org.whispersystems.libsignal.fingerprint"; 4 | option java_outer_classname = "FingerprintProtos"; 5 | 6 | message LogicalFingerprint { 7 | optional bytes content = 1; 8 | optional bytes identifier = 2; // Version 0 9 | } 10 | 11 | message CombinedFingerprints { 12 | optional uint32 version = 1; 13 | optional LogicalFingerprint localFingerprint = 2; 14 | optional LogicalFingerprint remoteFingerprint = 3; 15 | } 16 | -------------------------------------------------------------------------------- /protobuf/LocalStorageProtocol.proto: -------------------------------------------------------------------------------- 1 | package textsecure; 2 | 3 | option java_package = "org.whispersystems.libsignal.state"; 4 | option java_outer_classname = "StorageProtos"; 5 | 6 | message SessionStructure { 7 | message Chain { 8 | optional bytes senderRatchetKey = 1; 9 | optional bytes senderRatchetKeyPrivate = 2; 10 | 11 | message ChainKey { 12 | optional uint32 index = 1; 13 | optional bytes key = 2; 14 | } 15 | 16 | optional ChainKey chainKey = 3; 17 | 18 | message MessageKey { 19 | optional uint32 index = 1; 20 | optional bytes cipherKey = 2; 21 | optional bytes macKey = 3; 22 | optional bytes iv = 4; 23 | } 24 | 25 | repeated MessageKey messageKeys = 4; 26 | } 27 | 28 | message PendingKeyExchange { 29 | optional uint32 sequence = 1; 30 | optional bytes localBaseKey = 2; 31 | optional bytes localBaseKeyPrivate = 3; 32 | optional bytes localRatchetKey = 4; 33 | optional bytes localRatchetKeyPrivate = 5; 34 | optional bytes localIdentityKey = 7; 35 | optional bytes localIdentityKeyPrivate = 8; 36 | } 37 | 38 | message PendingPreKey { 39 | optional uint32 preKeyId = 1; 40 | optional int32 signedPreKeyId = 3; 41 | optional bytes baseKey = 2; 42 | } 43 | 44 | optional uint32 sessionVersion = 1; 45 | optional bytes localIdentityPublic = 2; 46 | optional bytes remoteIdentityPublic = 3; 47 | 48 | optional bytes rootKey = 4; 49 | optional uint32 previousCounter = 5; 50 | 51 | optional Chain senderChain = 6; 52 | repeated Chain receiverChains = 7; 53 | 54 | optional PendingKeyExchange pendingKeyExchange = 8; 55 | optional PendingPreKey pendingPreKey = 9; 56 | 57 | optional uint32 remoteRegistrationId = 10; 58 | optional uint32 localRegistrationId = 11; 59 | 60 | optional bool needsRefresh = 12; 61 | optional bytes aliceBaseKey = 13; 62 | } 63 | 64 | message RecordStructure { 65 | optional SessionStructure currentSession = 1; 66 | repeated SessionStructure previousSessions = 2; 67 | } 68 | 69 | message PreKeyRecordStructure { 70 | optional uint32 id = 1; 71 | optional bytes publicKey = 2; 72 | optional bytes privateKey = 3; 73 | } 74 | 75 | message SignedPreKeyRecordStructure { 76 | optional uint32 id = 1; 77 | optional bytes publicKey = 2; 78 | optional bytes privateKey = 3; 79 | optional bytes signature = 4; 80 | optional fixed64 timestamp = 5; 81 | } 82 | 83 | message IdentityKeyPairStructure { 84 | optional bytes publicKey = 1; 85 | optional bytes privateKey = 2; 86 | } 87 | 88 | message SenderKeyStateStructure { 89 | message SenderChainKey { 90 | optional uint32 iteration = 1; 91 | optional bytes seed = 2; 92 | } 93 | 94 | message SenderMessageKey { 95 | optional uint32 iteration = 1; 96 | optional bytes seed = 2; 97 | } 98 | 99 | message SenderSigningKey { 100 | optional bytes public = 1; 101 | optional bytes private = 2; 102 | } 103 | 104 | optional uint32 senderKeyId = 1; 105 | optional SenderChainKey senderChainKey = 2; 106 | optional SenderSigningKey senderSigningKey = 3; 107 | repeated SenderMessageKey senderMessageKeys = 4; 108 | } 109 | 110 | message SenderKeyRecordStructure { 111 | repeated SenderKeyStateStructure senderKeyStates = 1; 112 | } -------------------------------------------------------------------------------- /protobuf/Makefile: -------------------------------------------------------------------------------- 1 | 2 | all: 3 | protoc-c --c_out=../src/ WhisperTextProtocol.proto LocalStorageProtocol.proto FingerprintProtocol.proto 4 | -------------------------------------------------------------------------------- /protobuf/WhisperTextProtocol.proto: -------------------------------------------------------------------------------- 1 | package textsecure; 2 | 3 | option java_package = "org.whispersystems.libsignal.protocol"; 4 | option java_outer_classname = "SignalProtos"; 5 | 6 | message SignalMessage { 7 | optional bytes ratchetKey = 1; 8 | optional uint32 counter = 2; 9 | optional uint32 previousCounter = 3; 10 | optional bytes ciphertext = 4; 11 | } 12 | 13 | message PreKeySignalMessage { 14 | optional uint32 registrationId = 5; 15 | optional uint32 preKeyId = 1; 16 | optional uint32 signedPreKeyId = 6; 17 | optional bytes baseKey = 2; 18 | optional bytes identityKey = 3; 19 | optional bytes message = 4; // SignalMessage 20 | } 21 | 22 | message KeyExchangeMessage { 23 | optional uint32 id = 1; 24 | optional bytes baseKey = 2; 25 | optional bytes ratchetKey = 3; 26 | optional bytes identityKey = 4; 27 | optional bytes baseKeySignature = 5; 28 | } 29 | 30 | message SenderKeyMessage { 31 | optional uint32 id = 1; 32 | optional uint32 iteration = 2; 33 | optional bytes ciphertext = 3; 34 | } 35 | 36 | message SenderKeyDistributionMessage { 37 | optional uint32 id = 1; 38 | optional uint32 iteration = 2; 39 | optional bytes chainKey = 3; 40 | optional bytes signingKey = 4; 41 | } 42 | 43 | message DeviceConsistencyCodeMessage { 44 | optional uint32 generation = 1; 45 | optional bytes signature = 2; 46 | } -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | if(BUILD_SHARED_LIBS) 2 | find_library(M_LIB m) 3 | endif() 4 | 5 | include_directories( 6 | . 7 | curve25519/ed25519/nacl_includes 8 | curve25519/ed25519/additions 9 | curve25519/ed25519/sha512 10 | curve25519/ed25519 11 | curve25519 12 | ) 13 | 14 | set(protobuf_SRCS 15 | LocalStorageProtocol.pb-c.c 16 | WhisperTextProtocol.pb-c.c 17 | FingerprintProtocol.pb-c.c 18 | ) 19 | 20 | set(signal_protocol_SRCS 21 | vpool.c 22 | vpool.h 23 | signal_protocol.c 24 | signal_protocol.h 25 | signal_protocol_types.h 26 | signal_protocol_internal.h 27 | curve.c 28 | curve.h 29 | hkdf.c 30 | hkdf.h 31 | ratchet.c 32 | ratchet.h 33 | protocol.c 34 | protocol.h 35 | session_state.c 36 | session_state.h 37 | session_record.c 38 | session_record.h 39 | session_pre_key.c 40 | session_pre_key.h 41 | session_builder.c 42 | session_builder.h 43 | session_builder_internal.h 44 | session_cipher.c 45 | session_cipher.h 46 | key_helper.c 47 | key_helper.h 48 | sender_key.c 49 | sender_key.h 50 | sender_key_state.c 51 | sender_key_state.h 52 | sender_key_record.c 53 | sender_key_record.h 54 | group_session_builder.c 55 | group_session_builder.h 56 | group_cipher.c 57 | group_cipher.h 58 | fingerprint.c 59 | fingerprint.h 60 | device_consistency.c 61 | device_consistency.h 62 | ) 63 | 64 | add_subdirectory(curve25519) 65 | add_subdirectory(protobuf-c) 66 | 67 | add_library(signal-protocol-c 68 | ${protobuf_SRCS} 69 | ${signal_protocol_SRCS} 70 | $ 71 | $ 72 | ) 73 | 74 | if(BUILD_SHARED_LIBS) 75 | target_link_libraries(signal-protocol-c ${M_LIB}) 76 | set_target_properties(signal-protocol-c PROPERTIES 77 | VERSION ${SIGNAL_PROTOCOL_C_VERSION} 78 | SOVERSION ${SIGNAL_PROTOCOL_C_VERSION_MAJOR} 79 | ) 80 | endif() 81 | 82 | INSTALL( 83 | FILES 84 | signal_protocol.h 85 | signal_protocol_types.h 86 | curve.h 87 | hkdf.h 88 | ratchet.h 89 | protocol.h 90 | session_state.h 91 | session_record.h 92 | session_pre_key.h 93 | session_builder.h 94 | session_cipher.h 95 | key_helper.h 96 | sender_key.h 97 | sender_key_state.h 98 | sender_key_record.h 99 | group_session_builder.h 100 | group_cipher.h 101 | fingerprint.h 102 | device_consistency.h 103 | DESTINATION ${INCLUDE_INSTALL_DIR}/signal 104 | ) 105 | 106 | INSTALL(TARGETS signal-protocol-c 107 | LIBRARY DESTINATION ${LIB_INSTALL_DIR} 108 | RUNTIME DESTINATION ${BIN_INSTALL_DIR} 109 | ARCHIVE DESTINATION ${LIB_INSTALL_DIR} 110 | ) 111 | 112 | configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/libsignal-protocol-c.pc.in 113 | ${CMAKE_CURRENT_BINARY_DIR}/libsignal-protocol-c.pc @ONLY) 114 | 115 | INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/libsignal-protocol-c.pc DESTINATION "${INSTALL_PKGCONFIG_DIR}") 116 | -------------------------------------------------------------------------------- /src/FingerprintProtocol.pb-c.h: -------------------------------------------------------------------------------- 1 | /* Generated by the protocol buffer compiler. DO NOT EDIT! */ 2 | /* Generated from: FingerprintProtocol.proto */ 3 | 4 | #ifndef PROTOBUF_C_FingerprintProtocol_2eproto__INCLUDED 5 | #define PROTOBUF_C_FingerprintProtocol_2eproto__INCLUDED 6 | 7 | #include 8 | 9 | PROTOBUF_C__BEGIN_DECLS 10 | 11 | #if PROTOBUF_C_VERSION_NUMBER < 1000000 12 | # error This file was generated by a newer version of protoc-c which is incompatible with your libprotobuf-c headers. Please update your headers. 13 | #elif 1002001 < PROTOBUF_C_MIN_COMPILER_VERSION 14 | # error This file was generated by an older version of protoc-c which is incompatible with your libprotobuf-c headers. Please regenerate this file with a newer version of protoc-c. 15 | #endif 16 | 17 | 18 | typedef struct _Textsecure__LogicalFingerprint Textsecure__LogicalFingerprint; 19 | typedef struct _Textsecure__CombinedFingerprints Textsecure__CombinedFingerprints; 20 | 21 | 22 | /* --- enums --- */ 23 | 24 | 25 | /* --- messages --- */ 26 | 27 | struct _Textsecure__LogicalFingerprint 28 | { 29 | ProtobufCMessage base; 30 | protobuf_c_boolean has_content; 31 | ProtobufCBinaryData content; 32 | /* 33 | * Version 0 34 | */ 35 | protobuf_c_boolean has_identifier; 36 | ProtobufCBinaryData identifier; 37 | }; 38 | #define TEXTSECURE__LOGICAL_FINGERPRINT__INIT \ 39 | { PROTOBUF_C_MESSAGE_INIT (&textsecure__logical_fingerprint__descriptor) \ 40 | , 0,{0,NULL}, 0,{0,NULL} } 41 | 42 | 43 | struct _Textsecure__CombinedFingerprints 44 | { 45 | ProtobufCMessage base; 46 | protobuf_c_boolean has_version; 47 | uint32_t version; 48 | Textsecure__LogicalFingerprint *localfingerprint; 49 | Textsecure__LogicalFingerprint *remotefingerprint; 50 | }; 51 | #define TEXTSECURE__COMBINED_FINGERPRINTS__INIT \ 52 | { PROTOBUF_C_MESSAGE_INIT (&textsecure__combined_fingerprints__descriptor) \ 53 | , 0,0, NULL, NULL } 54 | 55 | 56 | /* Textsecure__LogicalFingerprint methods */ 57 | void textsecure__logical_fingerprint__init 58 | (Textsecure__LogicalFingerprint *message); 59 | size_t textsecure__logical_fingerprint__get_packed_size 60 | (const Textsecure__LogicalFingerprint *message); 61 | size_t textsecure__logical_fingerprint__pack 62 | (const Textsecure__LogicalFingerprint *message, 63 | uint8_t *out); 64 | size_t textsecure__logical_fingerprint__pack_to_buffer 65 | (const Textsecure__LogicalFingerprint *message, 66 | ProtobufCBuffer *buffer); 67 | Textsecure__LogicalFingerprint * 68 | textsecure__logical_fingerprint__unpack 69 | (ProtobufCAllocator *allocator, 70 | size_t len, 71 | const uint8_t *data); 72 | void textsecure__logical_fingerprint__free_unpacked 73 | (Textsecure__LogicalFingerprint *message, 74 | ProtobufCAllocator *allocator); 75 | /* Textsecure__CombinedFingerprints methods */ 76 | void textsecure__combined_fingerprints__init 77 | (Textsecure__CombinedFingerprints *message); 78 | size_t textsecure__combined_fingerprints__get_packed_size 79 | (const Textsecure__CombinedFingerprints *message); 80 | size_t textsecure__combined_fingerprints__pack 81 | (const Textsecure__CombinedFingerprints *message, 82 | uint8_t *out); 83 | size_t textsecure__combined_fingerprints__pack_to_buffer 84 | (const Textsecure__CombinedFingerprints *message, 85 | ProtobufCBuffer *buffer); 86 | Textsecure__CombinedFingerprints * 87 | textsecure__combined_fingerprints__unpack 88 | (ProtobufCAllocator *allocator, 89 | size_t len, 90 | const uint8_t *data); 91 | void textsecure__combined_fingerprints__free_unpacked 92 | (Textsecure__CombinedFingerprints *message, 93 | ProtobufCAllocator *allocator); 94 | /* --- per-message closures --- */ 95 | 96 | typedef void (*Textsecure__LogicalFingerprint_Closure) 97 | (const Textsecure__LogicalFingerprint *message, 98 | void *closure_data); 99 | typedef void (*Textsecure__CombinedFingerprints_Closure) 100 | (const Textsecure__CombinedFingerprints *message, 101 | void *closure_data); 102 | 103 | /* --- services --- */ 104 | 105 | 106 | /* --- descriptors --- */ 107 | 108 | extern const ProtobufCMessageDescriptor textsecure__logical_fingerprint__descriptor; 109 | extern const ProtobufCMessageDescriptor textsecure__combined_fingerprints__descriptor; 110 | 111 | PROTOBUF_C__END_DECLS 112 | 113 | 114 | #endif /* PROTOBUF_C_FingerprintProtocol_2eproto__INCLUDED */ 115 | -------------------------------------------------------------------------------- /src/curve25519/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | IF(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang") 2 | SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-variable -Wno-unused-function -Wno-shadow") 3 | ENDIF(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang") 4 | 5 | IF(CMAKE_COMPILER_IS_GNUCC) 6 | SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-sign-compare") 7 | IF(GCC_WARN_SIGN_CONVERSION) 8 | SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-sign-conversion") 9 | ENDIF(GCC_WARN_SIGN_CONVERSION) 10 | ENDIF(CMAKE_COMPILER_IS_GNUCC) 11 | 12 | IF(CMAKE_C_COMPILER_ID MATCHES "Clang") 13 | SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-shorten-64-to-32") 14 | ENDIF(CMAKE_C_COMPILER_ID MATCHES "Clang") 15 | 16 | include_directories( 17 | ed25519/nacl_includes 18 | ed25519/additions 19 | ed25519/additions/generalized 20 | ed25519/sha512 21 | ed25519/tests 22 | ed25519 23 | ) 24 | 25 | set(curve25519_SRCS 26 | curve25519-donna.c 27 | ) 28 | 29 | set(ed25519_SRCS 30 | ed25519/fe_0.c 31 | ed25519/fe_1.c 32 | ed25519/fe_add.c 33 | ed25519/fe_cmov.c 34 | ed25519/fe_copy.c 35 | ed25519/fe_frombytes.c 36 | ed25519/fe_invert.c 37 | ed25519/fe_isnegative.c 38 | ed25519/fe_isnonzero.c 39 | ed25519/fe_mul.c 40 | ed25519/fe_neg.c 41 | ed25519/fe_pow22523.c 42 | ed25519/fe_sq.c 43 | ed25519/fe_sq2.c 44 | ed25519/fe_sub.c 45 | ed25519/fe_tobytes.c 46 | ed25519/ge_add.c 47 | ed25519/ge_double_scalarmult.c 48 | ed25519/ge_frombytes.c 49 | ed25519/ge_madd.c 50 | ed25519/ge_msub.c 51 | ed25519/ge_p1p1_to_p2.c 52 | ed25519/ge_p1p1_to_p3.c 53 | ed25519/ge_p2_0.c 54 | ed25519/ge_p2_dbl.c 55 | ed25519/ge_p3_0.c 56 | ed25519/ge_p3_dbl.c 57 | ed25519/ge_p3_to_cached.c 58 | ed25519/ge_p3_to_p2.c 59 | ed25519/ge_p3_tobytes.c 60 | ed25519/ge_precomp_0.c 61 | ed25519/ge_scalarmult_base.c 62 | ed25519/ge_sub.c 63 | ed25519/ge_tobytes.c 64 | ed25519/open.c 65 | ed25519/sc_muladd.c 66 | ed25519/sc_reduce.c 67 | ed25519/sign.c 68 | ed25519/additions/compare.c 69 | ed25519/additions/curve_sigs.c 70 | ed25519/additions/elligator.c 71 | ed25519/additions/fe_isequal.c 72 | ed25519/additions/fe_isreduced.c 73 | ed25519/additions/fe_mont_rhs.c 74 | ed25519/additions/fe_montx_to_edy.c 75 | ed25519/additions/fe_sqrt.c 76 | ed25519/additions/ge_isneutral.c 77 | ed25519/additions/ge_montx_to_p3.c 78 | ed25519/additions/ge_neg.c 79 | ed25519/additions/ge_p3_to_montx.c 80 | ed25519/additions/ge_scalarmult.c 81 | ed25519/additions/ge_scalarmult_cofactor.c 82 | ed25519/additions/keygen.c 83 | ed25519/additions/open_modified.c 84 | ed25519/additions/sc_clamp.c 85 | ed25519/additions/sc_cmov.c 86 | ed25519/additions/sc_neg.c 87 | ed25519/additions/sign_modified.c 88 | ed25519/additions/utility.c 89 | ed25519/additions/generalized/ge_p3_add.c 90 | ed25519/additions/generalized/gen_eddsa.c 91 | ed25519/additions/generalized/gen_labelset.c 92 | ed25519/additions/generalized/gen_veddsa.c 93 | ed25519/additions/generalized/gen_x.c 94 | ed25519/additions/generalized/point_isreduced.c 95 | ed25519/additions/generalized/sc_isreduced.c 96 | ed25519/additions/xeddsa.c 97 | ed25519/additions/zeroize.c 98 | ed25519/nacl_sha512/blocks.c 99 | ed25519/nacl_sha512/hash.c 100 | ed25519/tests/internal_fast_tests.c 101 | ) 102 | 103 | add_library(curve25519 OBJECT ${curve25519_SRCS} ${ed25519_SRCS}) 104 | 105 | # Add -fPIC flag 106 | if(BUILD_SHARED_LIBS) 107 | set_property(TARGET curve25519 PROPERTY POSITION_INDEPENDENT_CODE ON) 108 | endif() 109 | -------------------------------------------------------------------------------- /src/curve25519/curve25519-donna.h: -------------------------------------------------------------------------------- 1 | #ifndef CURVE25519_DONNA_H 2 | #define CURVE25519_DONNA_H 3 | 4 | extern int curve25519_donna(uint8_t *, const uint8_t *, const uint8_t *); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/additions/compare.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "compare.h" 3 | 4 | /* Const-time comparison from SUPERCOP, but here it's only used for 5 | signature verification, so doesn't need to be const-time. But 6 | copied the nacl version anyways. */ 7 | int crypto_verify_32_ref(const unsigned char *x, const unsigned char *y) 8 | { 9 | unsigned int differentbits = 0; 10 | #define F(i) differentbits |= x[i] ^ y[i]; 11 | F(0) 12 | F(1) 13 | F(2) 14 | F(3) 15 | F(4) 16 | F(5) 17 | F(6) 18 | F(7) 19 | F(8) 20 | F(9) 21 | F(10) 22 | F(11) 23 | F(12) 24 | F(13) 25 | F(14) 26 | F(15) 27 | F(16) 28 | F(17) 29 | F(18) 30 | F(19) 31 | F(20) 32 | F(21) 33 | F(22) 34 | F(23) 35 | F(24) 36 | F(25) 37 | F(26) 38 | F(27) 39 | F(28) 40 | F(29) 41 | F(30) 42 | F(31) 43 | return (1 & ((differentbits - 1) >> 8)) - 1; 44 | } 45 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/additions/compare.h: -------------------------------------------------------------------------------- 1 | #ifndef __COMPARE_H__ 2 | #define __COMPARE_H__ 3 | 4 | int crypto_verify_32_ref(const unsigned char *b1, const unsigned char *b2); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/additions/crypto_additions.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef __CRYPTO_ADDITIONS__ 3 | #define __CRYPTO_ADDITIONS__ 4 | 5 | #include "crypto_uint32.h" 6 | #include "fe.h" 7 | #include "ge.h" 8 | 9 | #define MAX_MSG_LEN 256 10 | 11 | void sc_neg(unsigned char *b, const unsigned char *a); 12 | void sc_cmov(unsigned char* f, const unsigned char* g, unsigned char b); 13 | 14 | int fe_isequal(const fe f, const fe g); 15 | int fe_isreduced(const unsigned char* s); 16 | void fe_mont_rhs(fe v2, const fe u); 17 | void fe_montx_to_edy(fe y, const fe u); 18 | void fe_sqrt(fe b, const fe a); 19 | 20 | int ge_isneutral(const ge_p3* q); 21 | void ge_neg(ge_p3* r, const ge_p3 *p); 22 | void ge_montx_to_p3(ge_p3* p, const fe u, const unsigned char ed_sign_bit); 23 | void ge_p3_to_montx(fe u, const ge_p3 *p); 24 | void ge_scalarmult(ge_p3 *h, const unsigned char *a, const ge_p3 *A); 25 | void ge_scalarmult_cofactor(ge_p3 *q, const ge_p3 *p); 26 | 27 | void elligator(fe u, const fe r); 28 | void hash_to_point(ge_p3* p, const unsigned char* msg, const unsigned long in_len); 29 | 30 | int crypto_sign_modified( 31 | unsigned char *sm, 32 | const unsigned char *m,unsigned long long mlen, 33 | const unsigned char *sk, /* Curve/Ed25519 private key */ 34 | const unsigned char *pk, /* Ed25519 public key */ 35 | const unsigned char *random /* 64 bytes random to hash into nonce */ 36 | ); 37 | 38 | int crypto_sign_open_modified( 39 | unsigned char *m, 40 | const unsigned char *sm,unsigned long long smlen, 41 | const unsigned char *pk 42 | ); 43 | 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/additions/crypto_hash_sha512.h: -------------------------------------------------------------------------------- 1 | #ifndef crypto_hash_sha512_H 2 | #define crypto_hash_sha512_H 3 | 4 | extern int crypto_hash_sha512(unsigned char *,const unsigned char *,unsigned long long); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/additions/curve_sigs.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "ge.h" 4 | #include "curve_sigs.h" 5 | #include "crypto_sign.h" 6 | #include "crypto_additions.h" 7 | 8 | int curve25519_sign(unsigned char* signature_out, 9 | const unsigned char* curve25519_privkey, 10 | const unsigned char* msg, const unsigned long msg_len, 11 | const unsigned char* random) 12 | { 13 | ge_p3 ed_pubkey_point; /* Ed25519 pubkey point */ 14 | unsigned char ed_pubkey[32]; /* Ed25519 encoded pubkey */ 15 | unsigned char *sigbuf; /* working buffer */ 16 | unsigned char sign_bit = 0; 17 | 18 | if ((sigbuf = malloc(msg_len + 128)) == 0) { 19 | memset(signature_out, 0, 64); 20 | return -1; 21 | } 22 | 23 | /* Convert the Curve25519 privkey to an Ed25519 public key */ 24 | ge_scalarmult_base(&ed_pubkey_point, curve25519_privkey); 25 | ge_p3_tobytes(ed_pubkey, &ed_pubkey_point); 26 | sign_bit = ed_pubkey[31] & 0x80; 27 | 28 | /* Perform an Ed25519 signature with explicit private key */ 29 | crypto_sign_modified(sigbuf, msg, msg_len, curve25519_privkey, 30 | ed_pubkey, random); 31 | memmove(signature_out, sigbuf, 64); 32 | 33 | /* Encode the sign bit into signature (in unused high bit of S) */ 34 | signature_out[63] &= 0x7F; /* bit should be zero already, but just in case */ 35 | signature_out[63] |= sign_bit; 36 | 37 | free(sigbuf); 38 | return 0; 39 | } 40 | 41 | int curve25519_verify(const unsigned char* signature, 42 | const unsigned char* curve25519_pubkey, 43 | const unsigned char* msg, const unsigned long msg_len) 44 | { 45 | fe u; 46 | fe y; 47 | unsigned char ed_pubkey[32]; 48 | unsigned char *verifybuf = NULL; /* working buffer */ 49 | unsigned char *verifybuf2 = NULL; /* working buffer #2 */ 50 | int result; 51 | 52 | if ((verifybuf = malloc(msg_len + 64)) == 0) { 53 | result = -1; 54 | goto err; 55 | } 56 | 57 | if ((verifybuf2 = malloc(msg_len + 64)) == 0) { 58 | result = -1; 59 | goto err; 60 | } 61 | 62 | /* Convert the Curve25519 public key into an Ed25519 public key. In 63 | particular, convert Curve25519's "montgomery" x-coordinate (u) into an 64 | Ed25519 "edwards" y-coordinate: 65 | 66 | y = (u - 1) / (u + 1) 67 | 68 | NOTE: u=-1 is converted to y=0 since fe_invert is mod-exp 69 | 70 | Then move the sign bit into the pubkey from the signature. 71 | */ 72 | fe_frombytes(u, curve25519_pubkey); 73 | fe_montx_to_edy(y, u); 74 | fe_tobytes(ed_pubkey, y); 75 | 76 | /* Copy the sign bit, and remove it from signature */ 77 | ed_pubkey[31] &= 0x7F; /* bit should be zero already, but just in case */ 78 | ed_pubkey[31] |= (signature[63] & 0x80); 79 | memmove(verifybuf, signature, 64); 80 | verifybuf[63] &= 0x7F; 81 | 82 | memmove(verifybuf+64, msg, msg_len); 83 | 84 | /* Then perform a normal Ed25519 verification, return 0 on success */ 85 | /* The below call has a strange API: */ 86 | /* verifybuf = R || S || message */ 87 | /* verifybuf2 = internal to next call gets a copy of verifybuf, S gets 88 | replaced with pubkey for hashing */ 89 | result = crypto_sign_open_modified(verifybuf2, verifybuf, 64 + msg_len, ed_pubkey); 90 | 91 | err: 92 | 93 | if (verifybuf != NULL) { 94 | free(verifybuf); 95 | } 96 | 97 | if (verifybuf2 != NULL) { 98 | free(verifybuf2); 99 | } 100 | 101 | return result; 102 | } 103 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/additions/curve_sigs.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef __CURVE_SIGS_H__ 3 | #define __CURVE_SIGS_H__ 4 | 5 | /* returns 0 on success */ 6 | int curve25519_sign(unsigned char* signature_out, /* 64 bytes */ 7 | const unsigned char* curve25519_privkey, /* 32 bytes */ 8 | const unsigned char* msg, const unsigned long msg_len, /* <= 256 bytes */ 9 | const unsigned char* random); /* 64 bytes */ 10 | 11 | /* returns 0 on success */ 12 | int curve25519_verify(const unsigned char* signature, /* 64 bytes */ 13 | const unsigned char* curve25519_pubkey, /* 32 bytes */ 14 | const unsigned char* msg, const unsigned long msg_len); /* <= 256 bytes */ 15 | 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/additions/elligator.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "fe.h" 3 | #include "ge.h" 4 | #include "crypto_uint32.h" 5 | #include "crypto_hash_sha512.h" 6 | #include "crypto_additions.h" 7 | 8 | unsigned int legendre_is_nonsquare(fe in) 9 | { 10 | fe temp; 11 | unsigned char bytes[32]; 12 | fe_pow22523(temp, in); /* temp = in^((q-5)/8) */ 13 | fe_sq(temp, temp); /* in^((q-5)/4) */ 14 | fe_sq(temp, temp); /* in^((q-5)/2) */ 15 | fe_mul(temp, temp, in); /* in^((q-3)/2) */ 16 | fe_mul(temp, temp, in); /* in^((q-1)/2) */ 17 | 18 | /* temp is now the Legendre symbol: 19 | * 1 = square 20 | * 0 = input is zero 21 | * -1 = nonsquare 22 | */ 23 | fe_tobytes(bytes, temp); 24 | return 1 & bytes[31]; 25 | } 26 | 27 | void elligator(fe u, const fe r) 28 | { 29 | /* r = input 30 | * x = -A/(1+2r^2) # 2 is nonsquare 31 | * e = (x^3 + Ax^2 + x)^((q-1)/2) # legendre symbol 32 | * if e == 1 (square) or e == 0 (because x == 0 and 2r^2 + 1 == 0) 33 | * u = x 34 | * if e == -1 (nonsquare) 35 | * u = -x - A 36 | */ 37 | fe A, one, twor2, twor2plus1, twor2plus1inv; 38 | fe x, e, Atemp, uneg; 39 | unsigned int nonsquare; 40 | 41 | fe_1(one); 42 | fe_0(A); 43 | A[0] = 486662; /* A = 486662 */ 44 | 45 | fe_sq2(twor2, r); /* 2r^2 */ 46 | fe_add(twor2plus1, twor2, one); /* 1+2r^2 */ 47 | fe_invert(twor2plus1inv, twor2plus1); /* 1/(1+2r^2) */ 48 | fe_mul(x, twor2plus1inv, A); /* A/(1+2r^2) */ 49 | fe_neg(x, x); /* x = -A/(1+2r^2) */ 50 | 51 | fe_mont_rhs(e, x); /* e = x^3 + Ax^2 + x */ 52 | nonsquare = legendre_is_nonsquare(e); 53 | 54 | fe_0(Atemp); 55 | fe_cmov(Atemp, A, nonsquare); /* 0, or A if nonsquare */ 56 | fe_add(u, x, Atemp); /* x, or x+A if nonsquare */ 57 | fe_neg(uneg, u); /* -x, or -x-A if nonsquare */ 58 | fe_cmov(u, uneg, nonsquare); /* x, or -x-A if nonsquare */ 59 | } 60 | 61 | void hash_to_point(ge_p3* p, const unsigned char* in, const unsigned long in_len) 62 | { 63 | unsigned char hash[64]; 64 | fe h, u; 65 | unsigned char sign_bit; 66 | ge_p3 p3; 67 | 68 | crypto_hash_sha512(hash, in, in_len); 69 | 70 | /* take the high bit as Edwards sign bit */ 71 | sign_bit = (hash[31] & 0x80) >> 7; 72 | hash[31] &= 0x7F; 73 | fe_frombytes(h, hash); 74 | elligator(u, h); 75 | 76 | ge_montx_to_p3(&p3, u, sign_bit); 77 | ge_scalarmult_cofactor(p, &p3); 78 | } 79 | 80 | 81 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/additions/fe_isequal.c: -------------------------------------------------------------------------------- 1 | #include "fe.h" 2 | #include "crypto_verify_32.h" 3 | 4 | /* 5 | return 1 if f == g 6 | return 0 if f != g 7 | */ 8 | 9 | int fe_isequal(const fe f, const fe g) 10 | { 11 | fe h; 12 | fe_sub(h, f, g); 13 | return 1 ^ (1 & (fe_isnonzero(h) >> 8)); 14 | } 15 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/additions/fe_isreduced.c: -------------------------------------------------------------------------------- 1 | #include "fe.h" 2 | #include "crypto_verify_32.h" 3 | 4 | int fe_isreduced(const unsigned char* s) 5 | { 6 | fe f; 7 | unsigned char strict[32]; 8 | 9 | fe_frombytes(f, s); 10 | fe_tobytes(strict, f); 11 | if (crypto_verify_32(strict, s) != 0) 12 | return 0; 13 | return 1; 14 | } 15 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/additions/fe_mont_rhs.c: -------------------------------------------------------------------------------- 1 | #include "fe.h" 2 | 3 | void fe_mont_rhs(fe v2, fe u) { 4 | fe A, one; 5 | fe u2, Au, inner; 6 | 7 | fe_1(one); 8 | fe_0(A); 9 | A[0] = 486662; /* A = 486662 */ 10 | 11 | fe_sq(u2, u); /* u^2 */ 12 | fe_mul(Au, A, u); /* Au */ 13 | fe_add(inner, u2, Au); /* u^2 + Au */ 14 | fe_add(inner, inner, one); /* u^2 + Au + 1 */ 15 | fe_mul(v2, u, inner); /* u(u^2 + Au + 1) */ 16 | } 17 | 18 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/additions/fe_montx_to_edy.c: -------------------------------------------------------------------------------- 1 | 2 | #include "fe.h" 3 | #include "crypto_additions.h" 4 | 5 | void fe_montx_to_edy(fe y, const fe u) 6 | { 7 | /* 8 | y = (u - 1) / (u + 1) 9 | 10 | NOTE: u=-1 is converted to y=0 since fe_invert is mod-exp 11 | */ 12 | fe one, um1, up1; 13 | 14 | fe_1(one); 15 | fe_sub(um1, u, one); 16 | fe_add(up1, u, one); 17 | fe_invert(up1, up1); 18 | fe_mul(y, um1, up1); 19 | } 20 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/additions/fe_sqrt.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "fe.h" 3 | #include "crypto_additions.h" 4 | 5 | /* sqrt(-1) */ 6 | static unsigned char i_bytes[32] = { 7 | 0xb0, 0xa0, 0x0e, 0x4a, 0x27, 0x1b, 0xee, 0xc4, 8 | 0x78, 0xe4, 0x2f, 0xad, 0x06, 0x18, 0x43, 0x2f, 9 | 0xa7, 0xd7, 0xfb, 0x3d, 0x99, 0x00, 0x4d, 0x2b, 10 | 0x0b, 0xdf, 0xc1, 0x4f, 0x80, 0x24, 0x83, 0x2b 11 | }; 12 | 13 | /* Preconditions: a is square or zero */ 14 | 15 | void fe_sqrt(fe out, const fe a) 16 | { 17 | fe exp, b, b2, bi, i; 18 | #ifndef NDEBUG 19 | fe legendre, zero, one; 20 | #endif 21 | 22 | fe_frombytes(i, i_bytes); 23 | fe_pow22523(exp, a); /* b = a^(q-5)/8 */ 24 | 25 | /* PRECONDITION: legendre symbol == 1 (square) or 0 (a == zero) */ 26 | #ifndef NDEBUG 27 | fe_sq(legendre, exp); /* in^((q-5)/4) */ 28 | fe_sq(legendre, legendre); /* in^((q-5)/2) */ 29 | fe_mul(legendre, legendre, a); /* in^((q-3)/2) */ 30 | fe_mul(legendre, legendre, a); /* in^((q-1)/2) */ 31 | 32 | fe_0(zero); 33 | fe_1(one); 34 | assert(fe_isequal(legendre, zero) || fe_isequal(legendre, one)); 35 | #endif 36 | 37 | fe_mul(b, a, exp); /* b = a * a^(q-5)/8 */ 38 | fe_sq(b2, b); /* b^2 = a * a^(q-1)/4 */ 39 | 40 | /* note b^4 == a^2, so b^2 == a or -a 41 | * if b^2 != a, multiply it by sqrt(-1) */ 42 | fe_mul(bi, b, i); 43 | fe_cmov(b, bi, 1 ^ fe_isequal(b2, a)); 44 | fe_copy(out, b); 45 | 46 | /* PRECONDITION: out^2 == a */ 47 | #ifndef NDEBUG 48 | fe_sq(b2, out); 49 | assert(fe_isequal(a, b2)); 50 | #endif 51 | } 52 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/additions/ge_isneutral.c: -------------------------------------------------------------------------------- 1 | #include "crypto_additions.h" 2 | #include "ge.h" 3 | 4 | /* 5 | return 1 if p is the neutral point 6 | return 0 otherwise 7 | */ 8 | 9 | int ge_isneutral(const ge_p3 *p) 10 | { 11 | fe zero; 12 | fe_0(zero); 13 | 14 | /* Check if p == neutral element == (0, 1) */ 15 | return (fe_isequal(p->X, zero) & fe_isequal(p->Y, p->Z)); 16 | } 17 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/additions/ge_montx_to_p3.c: -------------------------------------------------------------------------------- 1 | #include "fe.h" 2 | #include "ge.h" 3 | #include "assert.h" 4 | #include "crypto_additions.h" 5 | #include "utility.h" 6 | 7 | /* sqrt(-(A+2)) */ 8 | static unsigned char A_bytes[32] = { 9 | 0x06, 0x7e, 0x45, 0xff, 0xaa, 0x04, 0x6e, 0xcc, 10 | 0x82, 0x1a, 0x7d, 0x4b, 0xd1, 0xd3, 0xa1, 0xc5, 11 | 0x7e, 0x4f, 0xfc, 0x03, 0xdc, 0x08, 0x7b, 0xd2, 12 | 0xbb, 0x06, 0xa0, 0x60, 0xf4, 0xed, 0x26, 0x0f 13 | }; 14 | 15 | void ge_montx_to_p3(ge_p3* p, const fe u, const unsigned char ed_sign_bit) 16 | { 17 | fe x, y, A, v, v2, iv, nx; 18 | 19 | fe_frombytes(A, A_bytes); 20 | 21 | /* given u, recover edwards y */ 22 | /* given u, recover v */ 23 | /* given u and v, recover edwards x */ 24 | 25 | fe_montx_to_edy(y, u); /* y = (u - 1) / (u + 1) */ 26 | 27 | fe_mont_rhs(v2, u); /* v^2 = u(u^2 + Au + 1) */ 28 | fe_sqrt(v, v2); /* v = sqrt(v^2) */ 29 | 30 | fe_mul(x, u, A); /* x = u * sqrt(-(A+2)) */ 31 | fe_invert(iv, v); /* 1/v */ 32 | fe_mul(x, x, iv); /* x = (u/v) * sqrt(-(A+2)) */ 33 | 34 | fe_neg(nx, x); /* negate x to match sign bit */ 35 | fe_cmov(x, nx, fe_isnegative(x) ^ ed_sign_bit); 36 | 37 | fe_copy(p->X, x); 38 | fe_copy(p->Y, y); 39 | fe_1(p->Z); 40 | fe_mul(p->T, p->X, p->Y); 41 | 42 | /* POSTCONDITION: check that p->X and p->Y satisfy the Ed curve equation */ 43 | /* -x^2 + y^2 = 1 + dx^2y^2 */ 44 | #ifndef NDEBUG 45 | { 46 | fe one, d, x2, y2, x2y2, dx2y2; 47 | 48 | unsigned char dbytes[32] = { 49 | 0xa3, 0x78, 0x59, 0x13, 0xca, 0x4d, 0xeb, 0x75, 50 | 0xab, 0xd8, 0x41, 0x41, 0x4d, 0x0a, 0x70, 0x00, 51 | 0x98, 0xe8, 0x79, 0x77, 0x79, 0x40, 0xc7, 0x8c, 52 | 0x73, 0xfe, 0x6f, 0x2b, 0xee, 0x6c, 0x03, 0x52 53 | }; 54 | 55 | fe_frombytes(d, dbytes); 56 | fe_1(one); 57 | fe_sq(x2, p->X); /* x^2 */ 58 | fe_sq(y2, p->Y); /* y^2 */ 59 | 60 | fe_mul(dx2y2, x2, y2); /* x^2y^2 */ 61 | fe_mul(dx2y2, dx2y2, d); /* dx^2y^2 */ 62 | fe_add(dx2y2, dx2y2, one); /* dx^2y^2 + 1 */ 63 | 64 | fe_neg(x2y2, x2); /* -x^2 */ 65 | fe_add(x2y2, x2y2, y2); /* -x^2 + y^2 */ 66 | 67 | assert(fe_isequal(x2y2, dx2y2)); 68 | } 69 | #endif 70 | } 71 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/additions/ge_neg.c: -------------------------------------------------------------------------------- 1 | #include "crypto_additions.h" 2 | #include "ge.h" 3 | 4 | /* 5 | return r = -p 6 | */ 7 | 8 | 9 | void ge_neg(ge_p3* r, const ge_p3 *p) 10 | { 11 | fe_neg(r->X, p->X); 12 | fe_copy(r->Y, p->Y); 13 | fe_copy(r->Z, p->Z); 14 | fe_neg(r->T, p->T); 15 | } 16 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/additions/ge_p3_to_montx.c: -------------------------------------------------------------------------------- 1 | #include "fe.h" 2 | #include "crypto_additions.h" 3 | 4 | void ge_p3_to_montx(fe u, const ge_p3 *ed) 5 | { 6 | /* 7 | u = (y + 1) / (1 - y) 8 | or 9 | u = (y + z) / (z - y) 10 | 11 | NOTE: y=1 is converted to u=0 since fe_invert is mod-exp 12 | */ 13 | 14 | fe y_plus_one, one_minus_y, inv_one_minus_y; 15 | 16 | fe_add(y_plus_one, ed->Y, ed->Z); 17 | fe_sub(one_minus_y, ed->Z, ed->Y); 18 | fe_invert(inv_one_minus_y, one_minus_y); 19 | fe_mul(u, y_plus_one, inv_one_minus_y); 20 | } 21 | 22 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/additions/ge_scalarmult.c: -------------------------------------------------------------------------------- 1 | #include "crypto_uint32.h" 2 | #include "ge.h" 3 | #include "crypto_additions.h" 4 | 5 | static unsigned char equal(signed char b,signed char c) 6 | { 7 | unsigned char ub = b; 8 | unsigned char uc = c; 9 | unsigned char x = ub ^ uc; /* 0: yes; 1..255: no */ 10 | crypto_uint32 y = x; /* 0: yes; 1..255: no */ 11 | y -= 1; /* 4294967295: yes; 0..254: no */ 12 | y >>= 31; /* 1: yes; 0: no */ 13 | return y; 14 | } 15 | 16 | static unsigned char negative(signed char b) 17 | { 18 | unsigned long long x = b; /* 18446744073709551361..18446744073709551615: yes; 0..255: no */ 19 | x >>= 63; /* 1: yes; 0: no */ 20 | return x; 21 | } 22 | 23 | static void cmov(ge_cached *t,const ge_cached *u,unsigned char b) 24 | { 25 | fe_cmov(t->YplusX,u->YplusX,b); 26 | fe_cmov(t->YminusX,u->YminusX,b); 27 | fe_cmov(t->Z,u->Z,b); 28 | fe_cmov(t->T2d,u->T2d,b); 29 | } 30 | 31 | static void select(ge_cached *t,const ge_cached *pre, signed char b) 32 | { 33 | ge_cached minust; 34 | unsigned char bnegative = negative(b); 35 | unsigned char babs = b - (((-bnegative) & b) << 1); 36 | 37 | fe_1(t->YplusX); 38 | fe_1(t->YminusX); 39 | fe_1(t->Z); 40 | fe_0(t->T2d); 41 | 42 | cmov(t,pre+0,equal(babs,1)); 43 | cmov(t,pre+1,equal(babs,2)); 44 | cmov(t,pre+2,equal(babs,3)); 45 | cmov(t,pre+3,equal(babs,4)); 46 | cmov(t,pre+4,equal(babs,5)); 47 | cmov(t,pre+5,equal(babs,6)); 48 | cmov(t,pre+6,equal(babs,7)); 49 | cmov(t,pre+7,equal(babs,8)); 50 | fe_copy(minust.YplusX,t->YminusX); 51 | fe_copy(minust.YminusX,t->YplusX); 52 | fe_copy(minust.Z,t->Z); 53 | fe_neg(minust.T2d,t->T2d); 54 | cmov(t,&minust,bnegative); 55 | } 56 | 57 | /* 58 | h = a * B 59 | where a = a[0]+256*a[1]+...+256^31 a[31] 60 | B is the Ed25519 base point (x,4/5) with x positive. 61 | 62 | Preconditions: 63 | a[31] <= 127 64 | */ 65 | 66 | void ge_scalarmult(ge_p3 *h, const unsigned char *a, const ge_p3 *A) 67 | { 68 | signed char e[64]; 69 | signed char carry; 70 | ge_p1p1 r; 71 | ge_p2 s; 72 | ge_p3 t0, t1, t2; 73 | ge_cached t, pre[8]; 74 | int i; 75 | 76 | for (i = 0;i < 32;++i) { 77 | e[2 * i + 0] = (a[i] >> 0) & 15; 78 | e[2 * i + 1] = (a[i] >> 4) & 15; 79 | } 80 | /* each e[i] is between 0 and 15 */ 81 | /* e[63] is between 0 and 7 */ 82 | 83 | carry = 0; 84 | for (i = 0;i < 63;++i) { 85 | e[i] += carry; 86 | carry = e[i] + 8; 87 | carry >>= 4; 88 | e[i] -= carry << 4; 89 | } 90 | e[63] += carry; 91 | /* each e[i] is between -8 and 8 */ 92 | 93 | // Precomputation: 94 | ge_p3_to_cached(pre+0, A); // A 95 | 96 | ge_p3_dbl(&r, A); 97 | ge_p1p1_to_p3(&t0, &r); 98 | ge_p3_to_cached(pre+1, &t0); // 2A 99 | 100 | ge_add(&r, A, pre+1); 101 | ge_p1p1_to_p3(&t1, &r); 102 | ge_p3_to_cached(pre+2, &t1); // 3A 103 | 104 | ge_p3_dbl(&r, &t0); 105 | ge_p1p1_to_p3(&t0, &r); 106 | ge_p3_to_cached(pre+3, &t0); // 4A 107 | 108 | ge_add(&r, A, pre+3); 109 | ge_p1p1_to_p3(&t2, &r); 110 | ge_p3_to_cached(pre+4, &t2); // 5A 111 | 112 | ge_p3_dbl(&r, &t1); 113 | ge_p1p1_to_p3(&t1, &r); 114 | ge_p3_to_cached(pre+5, &t1); // 6A 115 | 116 | ge_add(&r, A, pre+5); 117 | ge_p1p1_to_p3(&t1, &r); 118 | ge_p3_to_cached(pre+6, &t1); // 7A 119 | 120 | ge_p3_dbl(&r, &t0); 121 | ge_p1p1_to_p3(&t0, &r); 122 | ge_p3_to_cached(pre+7, &t0); // 8A 123 | 124 | ge_p3_0(h); 125 | 126 | for (i = 63;i > 0; i--) { 127 | select(&t,pre,e[i]); 128 | ge_add(&r, h, &t); 129 | ge_p1p1_to_p2(&s,&r); 130 | 131 | ge_p2_dbl(&r,&s); ge_p1p1_to_p2(&s,&r); 132 | ge_p2_dbl(&r,&s); ge_p1p1_to_p2(&s,&r); 133 | ge_p2_dbl(&r,&s); ge_p1p1_to_p2(&s,&r); 134 | ge_p2_dbl(&r,&s); ge_p1p1_to_p3(h,&r); 135 | 136 | } 137 | select(&t,pre,e[0]); 138 | ge_add(&r, h, &t); 139 | ge_p1p1_to_p3(h,&r); 140 | } 141 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/additions/ge_scalarmult_cofactor.c: -------------------------------------------------------------------------------- 1 | #include "crypto_additions.h" 2 | #include "ge.h" 3 | 4 | /* 5 | return 8 * p 6 | */ 7 | 8 | void ge_scalarmult_cofactor(ge_p3 *q, const ge_p3 *p) 9 | { 10 | ge_p1p1 p1p1; 11 | ge_p2 p2; 12 | 13 | ge_p3_dbl(&p1p1, p); 14 | ge_p1p1_to_p2(&p2, &p1p1); 15 | 16 | ge_p2_dbl(&p1p1, &p2); 17 | ge_p1p1_to_p2(&p2, &p1p1); 18 | 19 | ge_p2_dbl(&p1p1, &p2); 20 | ge_p1p1_to_p3(q, &p1p1); 21 | } 22 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/additions/generalized/ge_p3_add.c: -------------------------------------------------------------------------------- 1 | #include "ge.h" 2 | 3 | /* 4 | r = p + q 5 | */ 6 | 7 | void ge_p3_add(ge_p3 *r, const ge_p3 *p, const ge_p3 *q) 8 | { 9 | ge_cached p_cached; 10 | ge_p1p1 r_p1p1; 11 | 12 | ge_p3_to_cached(&p_cached, p); 13 | ge_add(&r_p1p1, q, &p_cached); 14 | ge_p1p1_to_p3(r, &r_p1p1); 15 | } 16 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/additions/generalized/gen_constants.h: -------------------------------------------------------------------------------- 1 | #ifndef _GEN_CONSTANTS_H__ 2 | #define _GEN_CONSTANTS_H__ 3 | 4 | #define LABELSETMAXLEN 512 5 | #define LABELMAXLEN 128 6 | #define BUFLEN 1024 7 | #define BLOCKLEN 128 /* SHA512 */ 8 | #define HASHLEN 64 /* SHA512 */ 9 | #define POINTLEN 32 10 | #define SCALARLEN 32 11 | #define RANDLEN 32 12 | #define SIGNATURELEN 64 13 | #define VRFSIGNATURELEN 96 14 | #define VRFOUTPUTLEN 32 15 | #define MSTART 2048 16 | #define MSGMAXLEN 1048576 17 | 18 | #endif 19 | 20 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/additions/generalized/gen_crypto_additions.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef __GEN_CRYPTO_ADDITIONS__ 3 | #define __GEN_CRYPTO_ADDITIONS__ 4 | 5 | #include "crypto_uint32.h" 6 | #include "fe.h" 7 | #include "ge.h" 8 | 9 | int sc_isreduced(const unsigned char* s); 10 | 11 | int point_isreduced(const unsigned char* p); 12 | 13 | void ge_p3_add(ge_p3 *r, const ge_p3 *p, const ge_p3 *q); 14 | 15 | #endif 16 | 17 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/additions/generalized/gen_eddsa.h: -------------------------------------------------------------------------------- 1 | #ifndef __GEN_EDDSA_H__ 2 | #define __GEN_EDDSA_H__ 3 | 4 | #include "ge.h" 5 | 6 | /* B: base point 7 | R: commitment (point), 8 | r: private nonce (scalar) 9 | K: encoded public key 10 | k: private key (scalar) 11 | Z: 32-bytes random 12 | M: buffer containing message, message starts at M_start, continues for M_len 13 | 14 | r = hash(B || labelset || Z || pad1 || k || pad2 || labelset || K || extra || M) (mod q) 15 | */ 16 | int generalized_commit(unsigned char* R_bytes, unsigned char* r_scalar, 17 | const unsigned char* labelset, const unsigned long labelset_len, 18 | const unsigned char* extra, const unsigned long extra_len, 19 | const unsigned char* K_bytes, const unsigned char* k_scalar, 20 | const unsigned char* Z, 21 | unsigned char* M_buf, const unsigned long M_start, const unsigned long M_len); 22 | 23 | /* if is_labelset_empty(labelset): 24 | return hash(R || K || M) (mod q) 25 | else: 26 | return hash(B || labelset || R || labelset || K || extra || M) (mod q) 27 | */ 28 | int generalized_challenge(unsigned char* h_scalar, 29 | const unsigned char* labelset, const unsigned long labelset_len, 30 | const unsigned char* extra, const unsigned long extra_len, 31 | const unsigned char* R_bytes, 32 | const unsigned char* K_bytes, 33 | unsigned char* M_buf, const unsigned long M_start, const unsigned long M_len); 34 | 35 | /* return r + kh (mod q) */ 36 | int generalized_prove(unsigned char* out_scalar, 37 | const unsigned char* r_scalar, 38 | const unsigned char* k_scalar, 39 | const unsigned char* h_scalar); 40 | 41 | /* R = B^s / K^h */ 42 | int generalized_solve_commitment(unsigned char* R_bytes_out, ge_p3* K_point_out, 43 | const ge_p3* B_point, const unsigned char* s_scalar, 44 | const unsigned char* K_bytes, const unsigned char* h_scalar); 45 | 46 | 47 | int generalized_eddsa_25519_sign( 48 | unsigned char* signature_out, 49 | const unsigned char* eddsa_25519_pubkey_bytes, 50 | const unsigned char* eddsa_25519_privkey_scalar, 51 | const unsigned char* msg, 52 | const unsigned long msg_len, 53 | const unsigned char* random, 54 | const unsigned char* customization_label, 55 | const unsigned long customization_label_len); 56 | 57 | int generalized_eddsa_25519_verify( 58 | const unsigned char* signature, 59 | const unsigned char* eddsa_25519_pubkey, 60 | const unsigned char* msg, 61 | const unsigned long msg_len, 62 | const unsigned char* customization_label, 63 | const unsigned long customization_label_len); 64 | 65 | #endif 66 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/additions/generalized/gen_labelset.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "gen_labelset.h" 4 | #include "gen_constants.h" 5 | 6 | const unsigned char B_bytes[] = { 7 | 0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 8 | 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 9 | 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 10 | 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 11 | }; 12 | 13 | unsigned char* buffer_add(unsigned char* bufptr, const unsigned char* bufend, 14 | const unsigned char* in, const unsigned long in_len) 15 | { 16 | unsigned long count = 0; 17 | 18 | if (bufptr == NULL || bufend == NULL || bufptr > bufend) 19 | return NULL; 20 | if (in == NULL && in_len != 0) 21 | return NULL; 22 | if (bufend - bufptr < in_len) 23 | return NULL; 24 | 25 | for (count=0; count < in_len; count++) { 26 | if (bufptr >= bufend) 27 | return NULL; 28 | *bufptr++ = *in++; 29 | } 30 | return bufptr; 31 | } 32 | 33 | unsigned char* buffer_pad(const unsigned char* buf, unsigned char* bufptr, const unsigned char* bufend) 34 | { 35 | unsigned long count = 0; 36 | unsigned long pad_len = 0; 37 | 38 | if (buf == NULL || bufptr == NULL || bufend == NULL || bufptr >= bufend || bufptr < buf) 39 | return NULL; 40 | 41 | pad_len = (BLOCKLEN - ((bufptr-buf) % BLOCKLEN)) % BLOCKLEN; 42 | if (bufend - bufptr < pad_len) 43 | return NULL; 44 | 45 | for (count=0; count < pad_len; count++) { 46 | if (bufptr >= bufend) 47 | return NULL; 48 | *bufptr++ = 0; 49 | } 50 | return bufptr; 51 | } 52 | 53 | int labelset_new(unsigned char* labelset, unsigned long* labelset_len, const unsigned long labelset_maxlen, 54 | const unsigned char* protocol_name, const unsigned char protocol_name_len, 55 | const unsigned char* customization_label, const unsigned char customization_label_len) 56 | { 57 | unsigned char* bufptr; 58 | 59 | *labelset_len = 0; 60 | if (labelset == NULL) 61 | return -1; 62 | if (labelset_len == NULL) 63 | return -1; 64 | if (labelset_maxlen > LABELSETMAXLEN) 65 | return -1; 66 | if (labelset_maxlen < 3 + protocol_name_len + customization_label_len) 67 | return -1; 68 | if (protocol_name == NULL && protocol_name_len != 0) 69 | return -1; 70 | if (customization_label == NULL && customization_label_len != 0) 71 | return -1; 72 | if (protocol_name_len > LABELMAXLEN) 73 | return -1; 74 | if (customization_label_len > LABELMAXLEN) 75 | return -1; 76 | 77 | bufptr = labelset; 78 | *bufptr++ = 2; 79 | *bufptr++ = protocol_name_len; 80 | bufptr = buffer_add(bufptr, labelset + labelset_maxlen, protocol_name, protocol_name_len); 81 | if (bufptr != NULL && bufptr < labelset + labelset_maxlen) 82 | *bufptr++ = customization_label_len; 83 | bufptr = buffer_add(bufptr, labelset + labelset_maxlen, 84 | customization_label, customization_label_len); 85 | 86 | if (bufptr != NULL && bufptr - labelset == 3 + protocol_name_len + customization_label_len) { 87 | *labelset_len = bufptr - labelset; 88 | return 0; 89 | } 90 | return -1; 91 | } 92 | 93 | 94 | int labelset_add(unsigned char* labelset, unsigned long* labelset_len, const unsigned long labelset_maxlen, 95 | const unsigned char* label, const unsigned char label_len) 96 | { 97 | unsigned char* bufptr; 98 | if (labelset_len == NULL) 99 | return -1; 100 | if (*labelset_len > LABELSETMAXLEN || labelset_maxlen > LABELSETMAXLEN) 101 | return -1; 102 | if (*labelset_len >= labelset_maxlen || *labelset_len + label_len + 1 > labelset_maxlen) 103 | return -1; 104 | if (*labelset_len < 3 || labelset_maxlen < 4) 105 | return -1; 106 | if (label_len > LABELMAXLEN) 107 | return -1; 108 | 109 | labelset[0]++; 110 | labelset[*labelset_len] = label_len; 111 | bufptr = labelset + *labelset_len + 1; 112 | bufptr = buffer_add(bufptr, labelset + labelset_maxlen, label, label_len); 113 | if (bufptr == NULL) 114 | return -1; 115 | if (bufptr - labelset >= labelset_maxlen) 116 | return -1; 117 | if (bufptr - labelset != *labelset_len + 1 + label_len) 118 | return -1; 119 | 120 | *labelset_len += (1 + label_len); 121 | return 0; 122 | } 123 | 124 | int labelset_validate(const unsigned char* labelset, const unsigned long labelset_len) 125 | { 126 | unsigned char num_labels = 0; 127 | unsigned char count = 0; 128 | unsigned long offset = 0; 129 | unsigned char label_len = 0; 130 | 131 | if (labelset == NULL) 132 | return -1; 133 | if (labelset_len < 3 || labelset_len > LABELSETMAXLEN) 134 | return -1; 135 | 136 | num_labels = labelset[0]; 137 | offset = 1; 138 | for (count = 0; count < num_labels; count++) { 139 | label_len = labelset[offset]; 140 | if (label_len > LABELMAXLEN) 141 | return -1; 142 | offset += 1 + label_len; 143 | if (offset > labelset_len) 144 | return -1; 145 | } 146 | if (offset != labelset_len) 147 | return -1; 148 | return 0; 149 | } 150 | 151 | int labelset_is_empty(const unsigned char* labelset, const unsigned long labelset_len) 152 | { 153 | if (labelset_len != 3) 154 | return 0; 155 | return 1; 156 | } 157 | 158 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/additions/generalized/gen_labelset.h: -------------------------------------------------------------------------------- 1 | #ifndef __GEN_LABELSET_H__ 2 | #define __GEN_LABELSET_H__ 3 | 4 | extern const unsigned char B_bytes[]; 5 | 6 | unsigned char* buffer_add(unsigned char* bufptr, const unsigned char* bufend, 7 | const unsigned char* in, const unsigned long in_len); 8 | 9 | unsigned char* buffer_pad(const unsigned char* buf, unsigned char* bufptr, const unsigned char* bufend); 10 | 11 | 12 | int labelset_new(unsigned char* labelset, unsigned long* labelset_len, const unsigned long labelset_maxlen, 13 | const unsigned char* protocol_name, const unsigned char protocol_name_len, 14 | const unsigned char* customization_label, const unsigned char customization_label_len); 15 | 16 | int labelset_add(unsigned char* labelset, unsigned long* labelset_len, const unsigned long labelset_maxlen, 17 | const unsigned char* label, const unsigned char label_len); 18 | 19 | int labelset_validate(const unsigned char* labelset, const unsigned long labelset_len); 20 | 21 | int labelset_is_empty(const unsigned char* labelset, const unsigned long labelset_len); 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/additions/generalized/gen_veddsa.h: -------------------------------------------------------------------------------- 1 | #ifndef __GEN_VEDDSA_H__ 2 | #define __GEN_VEDDSA_H__ 3 | 4 | int generalized_veddsa_25519_sign( 5 | unsigned char* signature_out, 6 | const unsigned char* eddsa_25519_pubkey_bytes, 7 | const unsigned char* eddsa_25519_privkey_scalar, 8 | const unsigned char* msg, 9 | const unsigned long msg_len, 10 | const unsigned char* random, 11 | const unsigned char* customization_label, 12 | const unsigned long customization_label_len); 13 | 14 | int generalized_veddsa_25519_verify( 15 | unsigned char* vrf_out, 16 | const unsigned char* signature, 17 | const unsigned char* eddsa_25519_pubkey_bytes, 18 | const unsigned char* msg, 19 | const unsigned long msg_len, 20 | const unsigned char* customization_label, 21 | const unsigned long customization_label_len); 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/additions/generalized/gen_x.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "crypto_additions.h" 3 | #include "gen_x.h" 4 | #include "gen_constants.h" 5 | #include "gen_eddsa.h" 6 | #include "gen_veddsa.h" 7 | #include "gen_crypto_additions.h" 8 | #include "zeroize.h" 9 | 10 | static int convert_25519_pubkey(unsigned char* ed_pubkey_bytes, const unsigned char* x25519_pubkey_bytes) { 11 | fe u; 12 | fe y; 13 | 14 | /* Convert the X25519 public key into an Ed25519 public key. 15 | 16 | y = (u - 1) / (u + 1) 17 | 18 | NOTE: u=-1 is converted to y=0 since fe_invert is mod-exp 19 | */ 20 | if (!fe_isreduced(x25519_pubkey_bytes)) 21 | return -1; 22 | fe_frombytes(u, x25519_pubkey_bytes); 23 | fe_montx_to_edy(y, u); 24 | fe_tobytes(ed_pubkey_bytes, y); 25 | return 0; 26 | } 27 | 28 | static int calculate_25519_keypair(unsigned char* K_bytes, unsigned char* k_scalar, 29 | const unsigned char* x25519_privkey_scalar) 30 | { 31 | unsigned char kneg[SCALARLEN]; 32 | ge_p3 ed_pubkey_point; 33 | unsigned char sign_bit = 0; 34 | 35 | if (SCALARLEN != 32) 36 | return -1; 37 | 38 | /* Convert the Curve25519 privkey to an Ed25519 public key */ 39 | ge_scalarmult_base(&ed_pubkey_point, x25519_privkey_scalar); 40 | ge_p3_tobytes(K_bytes, &ed_pubkey_point); 41 | 42 | /* Force Edwards sign bit to zero */ 43 | sign_bit = (K_bytes[31] & 0x80) >> 7; 44 | memcpy(k_scalar, x25519_privkey_scalar, 32); 45 | sc_neg(kneg, k_scalar); 46 | sc_cmov(k_scalar, kneg, sign_bit); 47 | K_bytes[31] &= 0x7F; 48 | 49 | zeroize(kneg, SCALARLEN); 50 | return 0; 51 | } 52 | 53 | int generalized_xeddsa_25519_sign(unsigned char* signature_out, 54 | const unsigned char* x25519_privkey_scalar, 55 | const unsigned char* msg, const unsigned long msg_len, 56 | const unsigned char* random, 57 | const unsigned char* customization_label, 58 | const unsigned long customization_label_len) 59 | { 60 | unsigned char K_bytes[POINTLEN]; 61 | unsigned char k_scalar[SCALARLEN]; 62 | int retval = -1; 63 | 64 | if (calculate_25519_keypair(K_bytes, k_scalar, x25519_privkey_scalar) != 0) 65 | return -1; 66 | 67 | retval = generalized_eddsa_25519_sign(signature_out, 68 | K_bytes, k_scalar, 69 | msg, msg_len, random, 70 | customization_label, customization_label_len); 71 | zeroize(k_scalar, SCALARLEN); 72 | return retval; 73 | } 74 | 75 | int generalized_xveddsa_25519_sign( 76 | unsigned char* signature_out, 77 | const unsigned char* x25519_privkey_scalar, 78 | const unsigned char* msg, 79 | const unsigned long msg_len, 80 | const unsigned char* random, 81 | const unsigned char* customization_label, 82 | const unsigned long customization_label_len) 83 | { 84 | unsigned char K_bytes[POINTLEN]; 85 | unsigned char k_scalar[SCALARLEN]; 86 | int retval = -1; 87 | 88 | if (calculate_25519_keypair(K_bytes, k_scalar, x25519_privkey_scalar) != 0) 89 | return -1; 90 | 91 | retval = generalized_veddsa_25519_sign(signature_out, K_bytes, k_scalar, 92 | msg, msg_len, random, 93 | customization_label, customization_label_len); 94 | zeroize(k_scalar, SCALARLEN); 95 | return retval; 96 | } 97 | 98 | int generalized_xeddsa_25519_verify( 99 | const unsigned char* signature, 100 | const unsigned char* x25519_pubkey_bytes, 101 | const unsigned char* msg, 102 | const unsigned long msg_len, 103 | const unsigned char* customization_label, 104 | const unsigned long customization_label_len) 105 | { 106 | unsigned char K_bytes[POINTLEN]; 107 | 108 | if (convert_25519_pubkey(K_bytes, x25519_pubkey_bytes) != 0) 109 | return -1; 110 | 111 | return generalized_eddsa_25519_verify(signature, K_bytes, msg, msg_len, 112 | customization_label, customization_label_len); 113 | } 114 | 115 | int generalized_xveddsa_25519_verify( 116 | unsigned char* vrf_out, 117 | const unsigned char* signature, 118 | const unsigned char* x25519_pubkey_bytes, 119 | const unsigned char* msg, 120 | const unsigned long msg_len, 121 | const unsigned char* customization_label, 122 | const unsigned long customization_label_len) 123 | { 124 | unsigned char K_bytes[POINTLEN]; 125 | 126 | if (convert_25519_pubkey(K_bytes, x25519_pubkey_bytes) != 0) 127 | return -1; 128 | 129 | return generalized_veddsa_25519_verify(vrf_out, signature, K_bytes, msg, msg_len, 130 | customization_label, customization_label_len); 131 | } 132 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/additions/generalized/gen_x.h: -------------------------------------------------------------------------------- 1 | #ifndef __GEN_X_H 2 | #define __GEN_X_H 3 | 4 | int generalized_xeddsa_25519_sign(unsigned char* signature_out, /* 64 bytes */ 5 | const unsigned char* x25519_privkey_scalar, /* 32 bytes */ 6 | const unsigned char* msg, const unsigned long msg_len, 7 | const unsigned char* random, /* 32 bytes */ 8 | const unsigned char* customization_label, 9 | const unsigned long customization_label_len); 10 | 11 | int generalized_xeddsa_25519_verify( 12 | const unsigned char* signature, /* 64 bytes */ 13 | const unsigned char* x25519_pubkey_bytes, /* 32 bytes */ 14 | const unsigned char* msg, 15 | const unsigned long msg_len, 16 | const unsigned char* customization_label, 17 | const unsigned long customization_label_len); 18 | 19 | int generalized_xveddsa_25519_sign( 20 | unsigned char* signature_out, /* 96 bytes */ 21 | const unsigned char* x25519_privkey_scalar, /* 32 bytes */ 22 | const unsigned char* msg, 23 | const unsigned long msg_len, 24 | const unsigned char* random, /* 32 bytes */ 25 | const unsigned char* customization_label, 26 | const unsigned long customization_label_len); 27 | 28 | int generalized_xveddsa_25519_verify( 29 | unsigned char* vrf_out, /* 32 bytes */ 30 | const unsigned char* signature, /* 96 bytes */ 31 | const unsigned char* x25519_pubkey_bytes, /* 32 bytes */ 32 | const unsigned char* msg, 33 | const unsigned long msg_len, 34 | const unsigned char* customization_label, 35 | const unsigned long customization_label_len); 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/additions/generalized/point_isreduced.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "fe.h" 3 | #include "crypto_additions.h" 4 | 5 | int point_isreduced(const unsigned char* p) 6 | { 7 | unsigned char strict[32]; 8 | 9 | memmove(strict, p, 32); 10 | strict[31] &= 0x7F; /* mask off sign bit */ 11 | return fe_isreduced(strict); 12 | } 13 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/additions/generalized/sc_isreduced.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "fe.h" 3 | #include "sc.h" 4 | #include "crypto_additions.h" 5 | #include "crypto_verify_32.h" 6 | 7 | int sc_isreduced(const unsigned char* s) 8 | { 9 | unsigned char strict[64]; 10 | 11 | memset(strict, 0, 64); 12 | memmove(strict, s, 32); 13 | sc_reduce(strict); 14 | if (crypto_verify_32(strict, s) != 0) 15 | return 0; 16 | return 1; 17 | } 18 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/additions/keygen.c: -------------------------------------------------------------------------------- 1 | #include "ge.h" 2 | #include "keygen.h" 3 | #include "crypto_additions.h" 4 | 5 | void curve25519_keygen(unsigned char* curve25519_pubkey_out, 6 | const unsigned char* curve25519_privkey_in) 7 | { 8 | /* Perform a fixed-base multiplication of the Edwards base point, 9 | (which is efficient due to precalculated tables), then convert 10 | to the Curve25519 montgomery-format public key. 11 | 12 | NOTE: y=1 is converted to u=0 since fe_invert is mod-exp 13 | */ 14 | 15 | ge_p3 ed; /* Ed25519 pubkey point */ 16 | fe u; 17 | 18 | ge_scalarmult_base(&ed, curve25519_privkey_in); 19 | ge_p3_to_montx(u, &ed); 20 | fe_tobytes(curve25519_pubkey_out, u); 21 | } 22 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/additions/keygen.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef __KEYGEN_H__ 3 | #define __KEYGEN_H__ 4 | 5 | /* Sets and clears bits to make a random 32 bytes into a private key */ 6 | void sc_clamp(unsigned char* a); 7 | 8 | /* The private key should be 32 random bytes "clamped" by sc_clamp() */ 9 | void curve25519_keygen(unsigned char* curve25519_pubkey_out, /* 32 bytes */ 10 | const unsigned char* curve25519_privkey_in); /* 32 bytes */ 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/additions/open_modified.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "crypto_sign.h" 3 | #include "crypto_hash_sha512.h" 4 | #include "crypto_verify_32.h" 5 | #include "ge.h" 6 | #include "sc.h" 7 | #include "crypto_additions.h" 8 | 9 | int crypto_sign_open_modified( 10 | unsigned char *m, 11 | const unsigned char *sm,unsigned long long smlen, 12 | const unsigned char *pk 13 | ) 14 | { 15 | unsigned char pkcopy[32]; 16 | unsigned char rcopy[32]; 17 | unsigned char scopy[32]; 18 | unsigned char h[64]; 19 | unsigned char rcheck[32]; 20 | ge_p3 A; 21 | ge_p2 R; 22 | 23 | if (smlen < 64) goto badsig; 24 | if (sm[63] & 224) goto badsig; /* strict parsing of s */ 25 | if (ge_frombytes_negate_vartime(&A,pk) != 0) goto badsig; 26 | 27 | memmove(pkcopy,pk,32); 28 | memmove(rcopy,sm,32); 29 | memmove(scopy,sm + 32,32); 30 | 31 | memmove(m,sm,smlen); 32 | memmove(m + 32,pkcopy,32); 33 | crypto_hash_sha512(h,m,smlen); 34 | sc_reduce(h); 35 | 36 | ge_double_scalarmult_vartime(&R,h,&A,scopy); 37 | ge_tobytes(rcheck,&R); 38 | 39 | if (crypto_verify_32(rcheck,rcopy) == 0) { 40 | return 0; 41 | } 42 | 43 | badsig: 44 | return -1; 45 | } 46 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/additions/sc_clamp.c: -------------------------------------------------------------------------------- 1 | #include "crypto_additions.h" 2 | 3 | void sc_clamp(unsigned char* a) 4 | { 5 | a[0] &= 248; 6 | a[31] &= 127; 7 | a[31] |= 64; 8 | } 9 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/additions/sc_cmov.c: -------------------------------------------------------------------------------- 1 | #include "crypto_additions.h" 2 | 3 | /* 4 | Replace (f,g) with (g,g) if b == 1; 5 | replace (f,g) with (f,g) if b == 0. 6 | 7 | Preconditions: b in {0,1}. 8 | */ 9 | 10 | void sc_cmov(unsigned char* f, const unsigned char* g, unsigned char b) 11 | { 12 | int count=32; 13 | unsigned char x[32]; 14 | for (count=0; count < 32; count++) 15 | x[count] = f[count] ^ g[count]; 16 | b = -b; 17 | for (count=0; count < 32; count++) 18 | x[count] &= b; 19 | for (count=0; count < 32; count++) 20 | f[count] = f[count] ^ x[count]; 21 | } 22 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/additions/sc_neg.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "crypto_additions.h" 3 | #include "sc.h" 4 | 5 | /* l = order of base point = 2^252 + 27742317777372353535851937790883648493 */ 6 | 7 | /* 8 | static unsigned char l[32] = {0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 9 | 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, 10 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 11 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0, 0x10}; 12 | */ 13 | 14 | static unsigned char lminus1[32] = {0xec, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 15 | 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, 16 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 17 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}; 18 | 19 | /* b = -a (mod l) */ 20 | void sc_neg(unsigned char *b, const unsigned char *a) 21 | { 22 | unsigned char zero[32]; 23 | memset(zero, 0, 32); 24 | sc_muladd(b, lminus1, a, zero); /* b = (-1)a + 0 (mod l) */ 25 | } 26 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/additions/sign_modified.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "crypto_sign.h" 3 | #include "crypto_hash_sha512.h" 4 | #include "ge.h" 5 | #include "sc.h" 6 | #include "zeroize.h" 7 | #include "crypto_additions.h" 8 | 9 | /* NEW: Compare to pristine crypto_sign() 10 | Uses explicit private key for nonce derivation and as scalar, 11 | instead of deriving both from a master key. 12 | */ 13 | int crypto_sign_modified( 14 | unsigned char *sm, 15 | const unsigned char *m,unsigned long long mlen, 16 | const unsigned char *sk, const unsigned char* pk, 17 | const unsigned char* random 18 | ) 19 | { 20 | unsigned char nonce[64]; 21 | unsigned char hram[64]; 22 | ge_p3 R; 23 | int count=0; 24 | 25 | memmove(sm + 64,m,mlen); 26 | memmove(sm + 32,sk,32); /* NEW: Use privkey directly for nonce derivation */ 27 | 28 | /* NEW : add prefix to separate hash uses - see .h */ 29 | sm[0] = 0xFE; 30 | for (count = 1; count < 32; count++) 31 | sm[count] = 0xFF; 32 | 33 | /* NEW: add suffix of random data */ 34 | memmove(sm + mlen + 64, random, 64); 35 | 36 | crypto_hash_sha512(nonce,sm,mlen + 128); 37 | memmove(sm + 32,pk,32); 38 | 39 | sc_reduce(nonce); 40 | 41 | ge_scalarmult_base(&R,nonce); 42 | ge_p3_tobytes(sm,&R); 43 | 44 | crypto_hash_sha512(hram,sm,mlen + 64); 45 | sc_reduce(hram); 46 | sc_muladd(sm + 32,hram,sk,nonce); /* NEW: Use privkey directly */ 47 | 48 | /* Erase any traces of private scalar or 49 | nonce left in the stack from sc_muladd */ 50 | zeroize_stack(); 51 | zeroize(nonce, 64); 52 | return 0; 53 | } 54 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/additions/utility.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "utility.h" 4 | 5 | void print_vector(const char* name, const unsigned char* v) 6 | { 7 | int count; 8 | printf("%s = \n", name); 9 | for (count = 0; count < 32; count++) 10 | printf("%02x ", v[count]); 11 | printf("\n"); 12 | } 13 | 14 | void print_bytes(const char* name, const unsigned char* v, int numbytes) 15 | { 16 | int count; 17 | printf("%s = \n", name); 18 | for (count = 0; count < numbytes; count++) 19 | printf("%02x ", v[count]); 20 | printf("\n"); 21 | } 22 | 23 | void print_fe(const char* name, const fe in) 24 | { 25 | unsigned char bytes[32]; 26 | fe_tobytes(bytes, in); 27 | print_vector(name, bytes); 28 | } 29 | 30 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/additions/utility.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef __UTILITY_H__ 3 | #define __UTILITY_H__ 4 | 5 | #include "fe.h" 6 | 7 | void print_vector(const char* name, const unsigned char* v); 8 | void print_bytes(const char* name, const unsigned char* v, int numbytes); 9 | void print_fe(const char* name, const fe in); 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/additions/xeddsa.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "ge.h" 3 | #include "crypto_additions.h" 4 | #include "zeroize.h" 5 | #include "xeddsa.h" 6 | #include "crypto_verify_32.h" 7 | 8 | int xed25519_sign(unsigned char* signature_out, 9 | const unsigned char* curve25519_privkey, 10 | const unsigned char* msg, const unsigned long msg_len, 11 | const unsigned char* random) 12 | { 13 | unsigned char a[32], aneg[32]; 14 | unsigned char A[32]; 15 | ge_p3 ed_pubkey_point; 16 | unsigned char *sigbuf; /* working buffer */ 17 | unsigned char sign_bit = 0; 18 | 19 | if ((sigbuf = malloc(msg_len + 128)) == 0) { 20 | memset(signature_out, 0, 64); 21 | return -1; 22 | } 23 | 24 | /* Convert the Curve25519 privkey to an Ed25519 public key */ 25 | ge_scalarmult_base(&ed_pubkey_point, curve25519_privkey); 26 | ge_p3_tobytes(A, &ed_pubkey_point); 27 | 28 | /* Force Edwards sign bit to zero */ 29 | sign_bit = (A[31] & 0x80) >> 7; 30 | memcpy(a, curve25519_privkey, 32); 31 | sc_neg(aneg, a); 32 | sc_cmov(a, aneg, sign_bit); 33 | A[31] &= 0x7F; 34 | 35 | /* Perform an Ed25519 signature with explicit private key */ 36 | crypto_sign_modified(sigbuf, msg, msg_len, a, A, random); 37 | memmove(signature_out, sigbuf, 64); 38 | 39 | zeroize(a, 32); 40 | zeroize(aneg, 32); 41 | free(sigbuf); 42 | return 0; 43 | } 44 | 45 | int xed25519_verify(const unsigned char* signature, 46 | const unsigned char* curve25519_pubkey, 47 | const unsigned char* msg, const unsigned long msg_len) 48 | { 49 | fe u; 50 | fe y; 51 | unsigned char ed_pubkey[32]; 52 | unsigned char verifybuf[MAX_MSG_LEN + 64]; /* working buffer */ 53 | unsigned char verifybuf2[MAX_MSG_LEN + 64]; /* working buffer #2 */ 54 | 55 | if (msg_len > MAX_MSG_LEN) { 56 | return -1; 57 | } 58 | 59 | /* Convert the Curve25519 public key into an Ed25519 public key. 60 | 61 | y = (u - 1) / (u + 1) 62 | 63 | NOTE: u=-1 is converted to y=0 since fe_invert is mod-exp 64 | */ 65 | if (!fe_isreduced(curve25519_pubkey)) 66 | return -1; 67 | fe_frombytes(u, curve25519_pubkey); 68 | fe_montx_to_edy(y, u); 69 | fe_tobytes(ed_pubkey, y); 70 | 71 | memmove(verifybuf, signature, 64); 72 | memmove(verifybuf+64, msg, msg_len); 73 | 74 | /* Then perform a normal Ed25519 verification, return 0 on success */ 75 | /* The below call has a strange API: */ 76 | /* verifybuf = R || S || message */ 77 | /* verifybuf2 = internal to next call gets a copy of verifybuf, S gets 78 | replaced with pubkey for hashing */ 79 | return crypto_sign_open_modified(verifybuf2, verifybuf, 64 + msg_len, ed_pubkey); 80 | } 81 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/additions/xeddsa.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef __XEDDSA_H__ 3 | #define __XEDDSA_H__ 4 | 5 | /* returns 0 on success */ 6 | int xed25519_sign(unsigned char* signature_out, /* 64 bytes */ 7 | const unsigned char* curve25519_privkey, /* 32 bytes */ 8 | const unsigned char* msg, const unsigned long msg_len, /* <= 256 bytes */ 9 | const unsigned char* random); /* 64 bytes */ 10 | 11 | /* returns 0 on success */ 12 | int xed25519_verify(const unsigned char* signature, /* 64 bytes */ 13 | const unsigned char* curve25519_pubkey, /* 32 bytes */ 14 | const unsigned char* msg, const unsigned long msg_len); /* <= 256 bytes */ 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/additions/zeroize.c: -------------------------------------------------------------------------------- 1 | #include "zeroize.h" 2 | 3 | void zeroize(unsigned char* b, size_t len) 4 | { 5 | size_t count = 0; 6 | volatile unsigned char *p = b; 7 | 8 | for (count = 0; count < len; count++) 9 | p[count] = 0; 10 | } 11 | 12 | void zeroize_stack() 13 | { 14 | unsigned char m[ZEROIZE_STACK_SIZE]; 15 | zeroize(m, ZEROIZE_STACK_SIZE); 16 | } 17 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/additions/zeroize.h: -------------------------------------------------------------------------------- 1 | #ifndef __ZEROIZE_H__ 2 | #define __ZEROIZE_H__ 3 | 4 | #include 5 | 6 | #define ZEROIZE_STACK_SIZE 1024 7 | 8 | void zeroize(unsigned char* b, size_t len); 9 | 10 | void zeroize_stack(); 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/base2.h: -------------------------------------------------------------------------------- 1 | { 2 | { 25967493,-14356035,29566456,3660896,-12694345,4014787,27544626,-11754271,-6079156,2047605 }, 3 | { -12545711,934262,-2722910,3049990,-727428,9406986,12720692,5043384,19500929,-15469378 }, 4 | { -8738181,4489570,9688441,-14785194,10184609,-12363380,29287919,11864899,-24514362,-4438546 }, 5 | }, 6 | { 7 | { 15636291,-9688557,24204773,-7912398,616977,-16685262,27787600,-14772189,28944400,-1550024 }, 8 | { 16568933,4717097,-11556148,-1102322,15682896,-11807043,16354577,-11775962,7689662,11199574 }, 9 | { 30464156,-5976125,-11779434,-15670865,23220365,15915852,7512774,10017326,-17749093,-9920357 }, 10 | }, 11 | { 12 | { 10861363,11473154,27284546,1981175,-30064349,12577861,32867885,14515107,-15438304,10819380 }, 13 | { 4708026,6336745,20377586,9066809,-11272109,6594696,-25653668,12483688,-12668491,5581306 }, 14 | { 19563160,16186464,-29386857,4097519,10237984,-4348115,28542350,13850243,-23678021,-15815942 }, 15 | }, 16 | { 17 | { 5153746,9909285,1723747,-2777874,30523605,5516873,19480852,5230134,-23952439,-15175766 }, 18 | { -30269007,-3463509,7665486,10083793,28475525,1649722,20654025,16520125,30598449,7715701 }, 19 | { 28881845,14381568,9657904,3680757,-20181635,7843316,-31400660,1370708,29794553,-1409300 }, 20 | }, 21 | { 22 | { -22518993,-6692182,14201702,-8745502,-23510406,8844726,18474211,-1361450,-13062696,13821877 }, 23 | { -6455177,-7839871,3374702,-4740862,-27098617,-10571707,31655028,-7212327,18853322,-14220951 }, 24 | { 4566830,-12963868,-28974889,-12240689,-7602672,-2830569,-8514358,-10431137,2207753,-3209784 }, 25 | }, 26 | { 27 | { -25154831,-4185821,29681144,7868801,-6854661,-9423865,-12437364,-663000,-31111463,-16132436 }, 28 | { 25576264,-2703214,7349804,-11814844,16472782,9300885,3844789,15725684,171356,6466918 }, 29 | { 23103977,13316479,9739013,-16149481,817875,-15038942,8965339,-14088058,-30714912,16193877 }, 30 | }, 31 | { 32 | { -33521811,3180713,-2394130,14003687,-16903474,-16270840,17238398,4729455,-18074513,9256800 }, 33 | { -25182317,-4174131,32336398,5036987,-21236817,11360617,22616405,9761698,-19827198,630305 }, 34 | { -13720693,2639453,-24237460,-7406481,9494427,-5774029,-6554551,-15960994,-2449256,-14291300 }, 35 | }, 36 | { 37 | { -3151181,-5046075,9282714,6866145,-31907062,-863023,-18940575,15033784,25105118,-7894876 }, 38 | { -24326370,15950226,-31801215,-14592823,-11662737,-5090925,1573892,-2625887,2198790,-15804619 }, 39 | { -3099351,10324967,-2241613,7453183,-5446979,-2735503,-13812022,-16236442,-32461234,-12290683 }, 40 | }, 41 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/d.h: -------------------------------------------------------------------------------- 1 | -10913610,13857413,-15372611,6949391,114729,-8787816,-6275908,-3247719,-18696448,-12055116 2 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/d2.h: -------------------------------------------------------------------------------- 1 | -21827239,-5839606,-30745221,13898782,229458,15978800,-12551817,-6495438,29715968,9444199 2 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/fe.h: -------------------------------------------------------------------------------- 1 | #ifndef FE_H 2 | #define FE_H 3 | 4 | #include "crypto_int32.h" 5 | 6 | typedef crypto_int32 fe[10]; 7 | 8 | /* 9 | fe means field element. 10 | Here the field is \Z/(2^255-19). 11 | An element t, entries t[0]...t[9], represents the integer 12 | t[0]+2^26 t[1]+2^51 t[2]+2^77 t[3]+2^102 t[4]+...+2^230 t[9]. 13 | Bounds on each t[i] vary depending on context. 14 | */ 15 | 16 | #define fe_frombytes crypto_sign_ed25519_ref10_fe_frombytes 17 | #define fe_tobytes crypto_sign_ed25519_ref10_fe_tobytes 18 | #define fe_copy crypto_sign_ed25519_ref10_fe_copy 19 | #define fe_isnonzero crypto_sign_ed25519_ref10_fe_isnonzero 20 | #define fe_isnegative crypto_sign_ed25519_ref10_fe_isnegative 21 | #define fe_0 crypto_sign_ed25519_ref10_fe_0 22 | #define fe_1 crypto_sign_ed25519_ref10_fe_1 23 | #define fe_cswap crypto_sign_ed25519_ref10_fe_cswap 24 | #define fe_cmov crypto_sign_ed25519_ref10_fe_cmov 25 | #define fe_add crypto_sign_ed25519_ref10_fe_add 26 | #define fe_sub crypto_sign_ed25519_ref10_fe_sub 27 | #define fe_neg crypto_sign_ed25519_ref10_fe_neg 28 | #define fe_mul crypto_sign_ed25519_ref10_fe_mul 29 | #define fe_sq crypto_sign_ed25519_ref10_fe_sq 30 | #define fe_sq2 crypto_sign_ed25519_ref10_fe_sq2 31 | #define fe_mul121666 crypto_sign_ed25519_ref10_fe_mul121666 32 | #define fe_invert crypto_sign_ed25519_ref10_fe_invert 33 | #define fe_pow22523 crypto_sign_ed25519_ref10_fe_pow22523 34 | 35 | extern void fe_frombytes(fe,const unsigned char *); 36 | extern void fe_tobytes(unsigned char *,const fe); 37 | 38 | extern void fe_copy(fe,const fe); 39 | extern int fe_isnonzero(const fe); 40 | extern int fe_isnegative(const fe); 41 | extern void fe_0(fe); 42 | extern void fe_1(fe); 43 | extern void fe_cswap(fe,fe,unsigned int); 44 | extern void fe_cmov(fe,const fe,unsigned int); 45 | 46 | extern void fe_add(fe,const fe,const fe); 47 | extern void fe_sub(fe,const fe,const fe); 48 | extern void fe_neg(fe,const fe); 49 | extern void fe_mul(fe,const fe,const fe); 50 | extern void fe_sq(fe,const fe); 51 | extern void fe_sq2(fe,const fe); 52 | extern void fe_mul121666(fe,const fe); 53 | extern void fe_invert(fe,const fe); 54 | extern void fe_pow22523(fe,const fe); 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/fe_0.c: -------------------------------------------------------------------------------- 1 | #include "fe.h" 2 | 3 | /* 4 | h = 0 5 | */ 6 | 7 | void fe_0(fe h) 8 | { 9 | h[0] = 0; 10 | h[1] = 0; 11 | h[2] = 0; 12 | h[3] = 0; 13 | h[4] = 0; 14 | h[5] = 0; 15 | h[6] = 0; 16 | h[7] = 0; 17 | h[8] = 0; 18 | h[9] = 0; 19 | } 20 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/fe_1.c: -------------------------------------------------------------------------------- 1 | #include "fe.h" 2 | 3 | /* 4 | h = 1 5 | */ 6 | 7 | void fe_1(fe h) 8 | { 9 | h[0] = 1; 10 | h[1] = 0; 11 | h[2] = 0; 12 | h[3] = 0; 13 | h[4] = 0; 14 | h[5] = 0; 15 | h[6] = 0; 16 | h[7] = 0; 17 | h[8] = 0; 18 | h[9] = 0; 19 | } 20 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/fe_add.c: -------------------------------------------------------------------------------- 1 | #include "fe.h" 2 | 3 | /* 4 | h = f + g 5 | Can overlap h with f or g. 6 | 7 | Preconditions: 8 | |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. 9 | |g| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. 10 | 11 | Postconditions: 12 | |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. 13 | */ 14 | 15 | void fe_add(fe h,const fe f,const fe g) 16 | { 17 | crypto_int32 f0 = f[0]; 18 | crypto_int32 f1 = f[1]; 19 | crypto_int32 f2 = f[2]; 20 | crypto_int32 f3 = f[3]; 21 | crypto_int32 f4 = f[4]; 22 | crypto_int32 f5 = f[5]; 23 | crypto_int32 f6 = f[6]; 24 | crypto_int32 f7 = f[7]; 25 | crypto_int32 f8 = f[8]; 26 | crypto_int32 f9 = f[9]; 27 | crypto_int32 g0 = g[0]; 28 | crypto_int32 g1 = g[1]; 29 | crypto_int32 g2 = g[2]; 30 | crypto_int32 g3 = g[3]; 31 | crypto_int32 g4 = g[4]; 32 | crypto_int32 g5 = g[5]; 33 | crypto_int32 g6 = g[6]; 34 | crypto_int32 g7 = g[7]; 35 | crypto_int32 g8 = g[8]; 36 | crypto_int32 g9 = g[9]; 37 | crypto_int32 h0 = f0 + g0; 38 | crypto_int32 h1 = f1 + g1; 39 | crypto_int32 h2 = f2 + g2; 40 | crypto_int32 h3 = f3 + g3; 41 | crypto_int32 h4 = f4 + g4; 42 | crypto_int32 h5 = f5 + g5; 43 | crypto_int32 h6 = f6 + g6; 44 | crypto_int32 h7 = f7 + g7; 45 | crypto_int32 h8 = f8 + g8; 46 | crypto_int32 h9 = f9 + g9; 47 | h[0] = h0; 48 | h[1] = h1; 49 | h[2] = h2; 50 | h[3] = h3; 51 | h[4] = h4; 52 | h[5] = h5; 53 | h[6] = h6; 54 | h[7] = h7; 55 | h[8] = h8; 56 | h[9] = h9; 57 | } 58 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/fe_cmov.c: -------------------------------------------------------------------------------- 1 | #include "fe.h" 2 | 3 | /* 4 | Replace (f,g) with (g,g) if b == 1; 5 | replace (f,g) with (f,g) if b == 0. 6 | 7 | Preconditions: b in {0,1}. 8 | */ 9 | 10 | void fe_cmov(fe f,const fe g,unsigned int b) 11 | { 12 | crypto_int32 f0 = f[0]; 13 | crypto_int32 f1 = f[1]; 14 | crypto_int32 f2 = f[2]; 15 | crypto_int32 f3 = f[3]; 16 | crypto_int32 f4 = f[4]; 17 | crypto_int32 f5 = f[5]; 18 | crypto_int32 f6 = f[6]; 19 | crypto_int32 f7 = f[7]; 20 | crypto_int32 f8 = f[8]; 21 | crypto_int32 f9 = f[9]; 22 | crypto_int32 g0 = g[0]; 23 | crypto_int32 g1 = g[1]; 24 | crypto_int32 g2 = g[2]; 25 | crypto_int32 g3 = g[3]; 26 | crypto_int32 g4 = g[4]; 27 | crypto_int32 g5 = g[5]; 28 | crypto_int32 g6 = g[6]; 29 | crypto_int32 g7 = g[7]; 30 | crypto_int32 g8 = g[8]; 31 | crypto_int32 g9 = g[9]; 32 | crypto_int32 x0 = f0 ^ g0; 33 | crypto_int32 x1 = f1 ^ g1; 34 | crypto_int32 x2 = f2 ^ g2; 35 | crypto_int32 x3 = f3 ^ g3; 36 | crypto_int32 x4 = f4 ^ g4; 37 | crypto_int32 x5 = f5 ^ g5; 38 | crypto_int32 x6 = f6 ^ g6; 39 | crypto_int32 x7 = f7 ^ g7; 40 | crypto_int32 x8 = f8 ^ g8; 41 | crypto_int32 x9 = f9 ^ g9; 42 | b = -b; 43 | x0 &= b; 44 | x1 &= b; 45 | x2 &= b; 46 | x3 &= b; 47 | x4 &= b; 48 | x5 &= b; 49 | x6 &= b; 50 | x7 &= b; 51 | x8 &= b; 52 | x9 &= b; 53 | f[0] = f0 ^ x0; 54 | f[1] = f1 ^ x1; 55 | f[2] = f2 ^ x2; 56 | f[3] = f3 ^ x3; 57 | f[4] = f4 ^ x4; 58 | f[5] = f5 ^ x5; 59 | f[6] = f6 ^ x6; 60 | f[7] = f7 ^ x7; 61 | f[8] = f8 ^ x8; 62 | f[9] = f9 ^ x9; 63 | } 64 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/fe_copy.c: -------------------------------------------------------------------------------- 1 | #include "fe.h" 2 | 3 | /* 4 | h = f 5 | */ 6 | 7 | void fe_copy(fe h,const fe f) 8 | { 9 | crypto_int32 f0 = f[0]; 10 | crypto_int32 f1 = f[1]; 11 | crypto_int32 f2 = f[2]; 12 | crypto_int32 f3 = f[3]; 13 | crypto_int32 f4 = f[4]; 14 | crypto_int32 f5 = f[5]; 15 | crypto_int32 f6 = f[6]; 16 | crypto_int32 f7 = f[7]; 17 | crypto_int32 f8 = f[8]; 18 | crypto_int32 f9 = f[9]; 19 | h[0] = f0; 20 | h[1] = f1; 21 | h[2] = f2; 22 | h[3] = f3; 23 | h[4] = f4; 24 | h[5] = f5; 25 | h[6] = f6; 26 | h[7] = f7; 27 | h[8] = f8; 28 | h[9] = f9; 29 | } 30 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/fe_frombytes.c: -------------------------------------------------------------------------------- 1 | #include "fe.h" 2 | #include "crypto_int64.h" 3 | #include "crypto_uint64.h" 4 | 5 | static crypto_uint64 load_3(const unsigned char *in) 6 | { 7 | crypto_uint64 result; 8 | result = (crypto_uint64) in[0]; 9 | result |= ((crypto_uint64) in[1]) << 8; 10 | result |= ((crypto_uint64) in[2]) << 16; 11 | return result; 12 | } 13 | 14 | static crypto_uint64 load_4(const unsigned char *in) 15 | { 16 | crypto_uint64 result; 17 | result = (crypto_uint64) in[0]; 18 | result |= ((crypto_uint64) in[1]) << 8; 19 | result |= ((crypto_uint64) in[2]) << 16; 20 | result |= ((crypto_uint64) in[3]) << 24; 21 | return result; 22 | } 23 | 24 | /* 25 | Ignores top bit of h. 26 | */ 27 | 28 | void fe_frombytes(fe h,const unsigned char *s) 29 | { 30 | crypto_int64 h0 = load_4(s); 31 | crypto_int64 h1 = load_3(s + 4) << 6; 32 | crypto_int64 h2 = load_3(s + 7) << 5; 33 | crypto_int64 h3 = load_3(s + 10) << 3; 34 | crypto_int64 h4 = load_3(s + 13) << 2; 35 | crypto_int64 h5 = load_4(s + 16); 36 | crypto_int64 h6 = load_3(s + 20) << 7; 37 | crypto_int64 h7 = load_3(s + 23) << 5; 38 | crypto_int64 h8 = load_3(s + 26) << 4; 39 | crypto_int64 h9 = (load_3(s + 29) & 8388607) << 2; 40 | crypto_int64 carry0; 41 | crypto_int64 carry1; 42 | crypto_int64 carry2; 43 | crypto_int64 carry3; 44 | crypto_int64 carry4; 45 | crypto_int64 carry5; 46 | crypto_int64 carry6; 47 | crypto_int64 carry7; 48 | crypto_int64 carry8; 49 | crypto_int64 carry9; 50 | 51 | carry9 = (h9 + (crypto_int64) (1<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25; 52 | carry1 = (h1 + (crypto_int64) (1<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25; 53 | carry3 = (h3 + (crypto_int64) (1<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25; 54 | carry5 = (h5 + (crypto_int64) (1<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25; 55 | carry7 = (h7 + (crypto_int64) (1<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25; 56 | 57 | carry0 = (h0 + (crypto_int64) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26; 58 | carry2 = (h2 + (crypto_int64) (1<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26; 59 | carry4 = (h4 + (crypto_int64) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26; 60 | carry6 = (h6 + (crypto_int64) (1<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26; 61 | carry8 = (h8 + (crypto_int64) (1<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26; 62 | 63 | h[0] = h0; 64 | h[1] = h1; 65 | h[2] = h2; 66 | h[3] = h3; 67 | h[4] = h4; 68 | h[5] = h5; 69 | h[6] = h6; 70 | h[7] = h7; 71 | h[8] = h8; 72 | h[9] = h9; 73 | } 74 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/fe_invert.c: -------------------------------------------------------------------------------- 1 | #include "fe.h" 2 | 3 | void fe_invert(fe out,const fe z) 4 | { 5 | fe t0; 6 | fe t1; 7 | fe t2; 8 | fe t3; 9 | int i; 10 | 11 | #include "pow225521.h" 12 | 13 | return; 14 | } 15 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/fe_isnegative.c: -------------------------------------------------------------------------------- 1 | #include "fe.h" 2 | 3 | /* 4 | return 1 if f is in {1,3,5,...,q-2} 5 | return 0 if f is in {0,2,4,...,q-1} 6 | 7 | Preconditions: 8 | |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. 9 | */ 10 | 11 | int fe_isnegative(const fe f) 12 | { 13 | unsigned char s[32]; 14 | fe_tobytes(s,f); 15 | return s[0] & 1; 16 | } 17 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/fe_isnonzero.c: -------------------------------------------------------------------------------- 1 | #include "fe.h" 2 | #include "crypto_verify_32.h" 3 | 4 | /* 5 | return nonzero if f == 0 6 | return 0 if f != 0 7 | 8 | Preconditions: 9 | |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. 10 | */ 11 | 12 | /* TREVOR'S COMMENT 13 | * 14 | * I think the above comment is wrong. Instead: 15 | * 16 | * return 0 if f == 0 17 | * return -1 if f != 0 18 | * 19 | * */ 20 | 21 | static const unsigned char zero[32]; 22 | 23 | int fe_isnonzero(const fe f) 24 | { 25 | unsigned char s[32]; 26 | fe_tobytes(s,f); 27 | return crypto_verify_32(s,zero); 28 | } 29 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/fe_neg.c: -------------------------------------------------------------------------------- 1 | #include "fe.h" 2 | 3 | /* 4 | h = -f 5 | 6 | Preconditions: 7 | |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. 8 | 9 | Postconditions: 10 | |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. 11 | */ 12 | 13 | void fe_neg(fe h,const fe f) 14 | { 15 | crypto_int32 f0 = f[0]; 16 | crypto_int32 f1 = f[1]; 17 | crypto_int32 f2 = f[2]; 18 | crypto_int32 f3 = f[3]; 19 | crypto_int32 f4 = f[4]; 20 | crypto_int32 f5 = f[5]; 21 | crypto_int32 f6 = f[6]; 22 | crypto_int32 f7 = f[7]; 23 | crypto_int32 f8 = f[8]; 24 | crypto_int32 f9 = f[9]; 25 | crypto_int32 h0 = -f0; 26 | crypto_int32 h1 = -f1; 27 | crypto_int32 h2 = -f2; 28 | crypto_int32 h3 = -f3; 29 | crypto_int32 h4 = -f4; 30 | crypto_int32 h5 = -f5; 31 | crypto_int32 h6 = -f6; 32 | crypto_int32 h7 = -f7; 33 | crypto_int32 h8 = -f8; 34 | crypto_int32 h9 = -f9; 35 | h[0] = h0; 36 | h[1] = h1; 37 | h[2] = h2; 38 | h[3] = h3; 39 | h[4] = h4; 40 | h[5] = h5; 41 | h[6] = h6; 42 | h[7] = h7; 43 | h[8] = h8; 44 | h[9] = h9; 45 | } 46 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/fe_pow22523.c: -------------------------------------------------------------------------------- 1 | #include "fe.h" 2 | 3 | void fe_pow22523(fe out,const fe z) 4 | { 5 | fe t0; 6 | fe t1; 7 | fe t2; 8 | int i; 9 | 10 | #include "pow22523.h" 11 | 12 | return; 13 | } 14 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/fe_sub.c: -------------------------------------------------------------------------------- 1 | #include "fe.h" 2 | 3 | /* 4 | h = f - g 5 | Can overlap h with f or g. 6 | 7 | Preconditions: 8 | |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. 9 | |g| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. 10 | 11 | Postconditions: 12 | |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. 13 | */ 14 | 15 | void fe_sub(fe h,const fe f,const fe g) 16 | { 17 | crypto_int32 f0 = f[0]; 18 | crypto_int32 f1 = f[1]; 19 | crypto_int32 f2 = f[2]; 20 | crypto_int32 f3 = f[3]; 21 | crypto_int32 f4 = f[4]; 22 | crypto_int32 f5 = f[5]; 23 | crypto_int32 f6 = f[6]; 24 | crypto_int32 f7 = f[7]; 25 | crypto_int32 f8 = f[8]; 26 | crypto_int32 f9 = f[9]; 27 | crypto_int32 g0 = g[0]; 28 | crypto_int32 g1 = g[1]; 29 | crypto_int32 g2 = g[2]; 30 | crypto_int32 g3 = g[3]; 31 | crypto_int32 g4 = g[4]; 32 | crypto_int32 g5 = g[5]; 33 | crypto_int32 g6 = g[6]; 34 | crypto_int32 g7 = g[7]; 35 | crypto_int32 g8 = g[8]; 36 | crypto_int32 g9 = g[9]; 37 | crypto_int32 h0 = f0 - g0; 38 | crypto_int32 h1 = f1 - g1; 39 | crypto_int32 h2 = f2 - g2; 40 | crypto_int32 h3 = f3 - g3; 41 | crypto_int32 h4 = f4 - g4; 42 | crypto_int32 h5 = f5 - g5; 43 | crypto_int32 h6 = f6 - g6; 44 | crypto_int32 h7 = f7 - g7; 45 | crypto_int32 h8 = f8 - g8; 46 | crypto_int32 h9 = f9 - g9; 47 | h[0] = h0; 48 | h[1] = h1; 49 | h[2] = h2; 50 | h[3] = h3; 51 | h[4] = h4; 52 | h[5] = h5; 53 | h[6] = h6; 54 | h[7] = h7; 55 | h[8] = h8; 56 | h[9] = h9; 57 | } 58 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/fe_tobytes.c: -------------------------------------------------------------------------------- 1 | #include "fe.h" 2 | 3 | /* 4 | Preconditions: 5 | |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. 6 | 7 | Write p=2^255-19; q=floor(h/p). 8 | Basic claim: q = floor(2^(-255)(h + 19 2^(-25)h9 + 2^(-1))). 9 | 10 | Proof: 11 | Have |h|<=p so |q|<=1 so |19^2 2^(-255) q|<1/4. 12 | Also have |h-2^230 h9|<2^231 so |19 2^(-255)(h-2^230 h9)|<1/4. 13 | 14 | Write y=2^(-1)-19^2 2^(-255)q-19 2^(-255)(h-2^230 h9). 15 | Then 0> 25; 53 | q = (h0 + q) >> 26; 54 | q = (h1 + q) >> 25; 55 | q = (h2 + q) >> 26; 56 | q = (h3 + q) >> 25; 57 | q = (h4 + q) >> 26; 58 | q = (h5 + q) >> 25; 59 | q = (h6 + q) >> 26; 60 | q = (h7 + q) >> 25; 61 | q = (h8 + q) >> 26; 62 | q = (h9 + q) >> 25; 63 | 64 | /* Goal: Output h-(2^255-19)q, which is between 0 and 2^255-20. */ 65 | h0 += 19 * q; 66 | /* Goal: Output h-2^255 q, which is between 0 and 2^255-20. */ 67 | 68 | carry0 = h0 >> 26; h1 += carry0; h0 -= carry0 << 26; 69 | carry1 = h1 >> 25; h2 += carry1; h1 -= carry1 << 25; 70 | carry2 = h2 >> 26; h3 += carry2; h2 -= carry2 << 26; 71 | carry3 = h3 >> 25; h4 += carry3; h3 -= carry3 << 25; 72 | carry4 = h4 >> 26; h5 += carry4; h4 -= carry4 << 26; 73 | carry5 = h5 >> 25; h6 += carry5; h5 -= carry5 << 25; 74 | carry6 = h6 >> 26; h7 += carry6; h6 -= carry6 << 26; 75 | carry7 = h7 >> 25; h8 += carry7; h7 -= carry7 << 25; 76 | carry8 = h8 >> 26; h9 += carry8; h8 -= carry8 << 26; 77 | carry9 = h9 >> 25; h9 -= carry9 << 25; 78 | /* h10 = carry9 */ 79 | 80 | /* 81 | Goal: Output h0+...+2^255 h10-2^255 q, which is between 0 and 2^255-20. 82 | Have h0+...+2^230 h9 between 0 and 2^255-1; 83 | evidently 2^255 h10-2^255 q = 0. 84 | Goal: Output h0+...+2^230 h9. 85 | */ 86 | 87 | s[0] = h0 >> 0; 88 | s[1] = h0 >> 8; 89 | s[2] = h0 >> 16; 90 | s[3] = (h0 >> 24) | (h1 << 2); 91 | s[4] = h1 >> 6; 92 | s[5] = h1 >> 14; 93 | s[6] = (h1 >> 22) | (h2 << 3); 94 | s[7] = h2 >> 5; 95 | s[8] = h2 >> 13; 96 | s[9] = (h2 >> 21) | (h3 << 5); 97 | s[10] = h3 >> 3; 98 | s[11] = h3 >> 11; 99 | s[12] = (h3 >> 19) | (h4 << 6); 100 | s[13] = h4 >> 2; 101 | s[14] = h4 >> 10; 102 | s[15] = h4 >> 18; 103 | s[16] = h5 >> 0; 104 | s[17] = h5 >> 8; 105 | s[18] = h5 >> 16; 106 | s[19] = (h5 >> 24) | (h6 << 1); 107 | s[20] = h6 >> 7; 108 | s[21] = h6 >> 15; 109 | s[22] = (h6 >> 23) | (h7 << 3); 110 | s[23] = h7 >> 5; 111 | s[24] = h7 >> 13; 112 | s[25] = (h7 >> 21) | (h8 << 4); 113 | s[26] = h8 >> 4; 114 | s[27] = h8 >> 12; 115 | s[28] = (h8 >> 20) | (h9 << 6); 116 | s[29] = h9 >> 2; 117 | s[30] = h9 >> 10; 118 | s[31] = h9 >> 18; 119 | } 120 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/ge.h: -------------------------------------------------------------------------------- 1 | #ifndef GE_H 2 | #define GE_H 3 | 4 | /* 5 | ge means group element. 6 | 7 | Here the group is the set of pairs (x,y) of field elements (see fe.h) 8 | satisfying -x^2 + y^2 = 1 + d x^2y^2 9 | where d = -121665/121666. 10 | 11 | Representations: 12 | ge_p2 (projective): (X:Y:Z) satisfying x=X/Z, y=Y/Z 13 | ge_p3 (extended): (X:Y:Z:T) satisfying x=X/Z, y=Y/Z, XY=ZT 14 | ge_p1p1 (completed): ((X:Z),(Y:T)) satisfying x=X/Z, y=Y/T 15 | ge_precomp (Duif): (y+x,y-x,2dxy) 16 | */ 17 | 18 | #include "fe.h" 19 | 20 | typedef struct { 21 | fe X; 22 | fe Y; 23 | fe Z; 24 | } ge_p2; 25 | 26 | typedef struct { 27 | fe X; 28 | fe Y; 29 | fe Z; 30 | fe T; 31 | } ge_p3; 32 | 33 | typedef struct { 34 | fe X; 35 | fe Y; 36 | fe Z; 37 | fe T; 38 | } ge_p1p1; 39 | 40 | typedef struct { 41 | fe yplusx; 42 | fe yminusx; 43 | fe xy2d; 44 | } ge_precomp; 45 | 46 | typedef struct { 47 | fe YplusX; 48 | fe YminusX; 49 | fe Z; 50 | fe T2d; 51 | } ge_cached; 52 | 53 | #define ge_frombytes_negate_vartime crypto_sign_ed25519_ref10_ge_frombytes_negate_vartime 54 | #define ge_tobytes crypto_sign_ed25519_ref10_ge_tobytes 55 | #define ge_p3_tobytes crypto_sign_ed25519_ref10_ge_p3_tobytes 56 | 57 | #define ge_p2_0 crypto_sign_ed25519_ref10_ge_p2_0 58 | #define ge_p3_0 crypto_sign_ed25519_ref10_ge_p3_0 59 | #define ge_precomp_0 crypto_sign_ed25519_ref10_ge_precomp_0 60 | #define ge_p3_to_p2 crypto_sign_ed25519_ref10_ge_p3_to_p2 61 | #define ge_p3_to_cached crypto_sign_ed25519_ref10_ge_p3_to_cached 62 | #define ge_p1p1_to_p2 crypto_sign_ed25519_ref10_ge_p1p1_to_p2 63 | #define ge_p1p1_to_p3 crypto_sign_ed25519_ref10_ge_p1p1_to_p3 64 | #define ge_p2_dbl crypto_sign_ed25519_ref10_ge_p2_dbl 65 | #define ge_p3_dbl crypto_sign_ed25519_ref10_ge_p3_dbl 66 | 67 | #define ge_madd crypto_sign_ed25519_ref10_ge_madd 68 | #define ge_msub crypto_sign_ed25519_ref10_ge_msub 69 | #define ge_add crypto_sign_ed25519_ref10_ge_add 70 | #define ge_sub crypto_sign_ed25519_ref10_ge_sub 71 | #define ge_scalarmult_base crypto_sign_ed25519_ref10_ge_scalarmult_base 72 | #define ge_double_scalarmult_vartime crypto_sign_ed25519_ref10_ge_double_scalarmult_vartime 73 | 74 | extern void ge_tobytes(unsigned char *,const ge_p2 *); 75 | extern void ge_p3_tobytes(unsigned char *,const ge_p3 *); 76 | extern int ge_frombytes_negate_vartime(ge_p3 *,const unsigned char *); 77 | 78 | extern void ge_p2_0(ge_p2 *); 79 | extern void ge_p3_0(ge_p3 *); 80 | extern void ge_precomp_0(ge_precomp *); 81 | extern void ge_p3_to_p2(ge_p2 *,const ge_p3 *); 82 | extern void ge_p3_to_cached(ge_cached *,const ge_p3 *); 83 | extern void ge_p1p1_to_p2(ge_p2 *,const ge_p1p1 *); 84 | extern void ge_p1p1_to_p3(ge_p3 *,const ge_p1p1 *); 85 | extern void ge_p2_dbl(ge_p1p1 *,const ge_p2 *); 86 | extern void ge_p3_dbl(ge_p1p1 *,const ge_p3 *); 87 | 88 | extern void ge_madd(ge_p1p1 *,const ge_p3 *,const ge_precomp *); 89 | extern void ge_msub(ge_p1p1 *,const ge_p3 *,const ge_precomp *); 90 | extern void ge_add(ge_p1p1 *,const ge_p3 *,const ge_cached *); 91 | extern void ge_sub(ge_p1p1 *,const ge_p3 *,const ge_cached *); 92 | extern void ge_scalarmult_base(ge_p3 *,const unsigned char *); 93 | extern void ge_double_scalarmult_vartime(ge_p2 *,const unsigned char *,const ge_p3 *,const unsigned char *); 94 | 95 | #endif 96 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/ge_add.c: -------------------------------------------------------------------------------- 1 | #include "ge.h" 2 | 3 | /* 4 | r = p + q 5 | */ 6 | 7 | void ge_add(ge_p1p1 *r,const ge_p3 *p,const ge_cached *q) 8 | { 9 | fe t0; 10 | #include "ge_add.h" 11 | } 12 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/ge_add.h: -------------------------------------------------------------------------------- 1 | 2 | /* qhasm: enter ge_add */ 3 | 4 | /* qhasm: fe X1 */ 5 | 6 | /* qhasm: fe Y1 */ 7 | 8 | /* qhasm: fe Z1 */ 9 | 10 | /* qhasm: fe Z2 */ 11 | 12 | /* qhasm: fe T1 */ 13 | 14 | /* qhasm: fe ZZ */ 15 | 16 | /* qhasm: fe YpX2 */ 17 | 18 | /* qhasm: fe YmX2 */ 19 | 20 | /* qhasm: fe T2d2 */ 21 | 22 | /* qhasm: fe X3 */ 23 | 24 | /* qhasm: fe Y3 */ 25 | 26 | /* qhasm: fe Z3 */ 27 | 28 | /* qhasm: fe T3 */ 29 | 30 | /* qhasm: fe YpX1 */ 31 | 32 | /* qhasm: fe YmX1 */ 33 | 34 | /* qhasm: fe A */ 35 | 36 | /* qhasm: fe B */ 37 | 38 | /* qhasm: fe C */ 39 | 40 | /* qhasm: fe D */ 41 | 42 | /* qhasm: YpX1 = Y1+X1 */ 43 | /* asm 1: fe_add(>YpX1=fe#1,YpX1=r->X,Y,X); */ 45 | fe_add(r->X,p->Y,p->X); 46 | 47 | /* qhasm: YmX1 = Y1-X1 */ 48 | /* asm 1: fe_sub(>YmX1=fe#2,YmX1=r->Y,Y,X); */ 50 | fe_sub(r->Y,p->Y,p->X); 51 | 52 | /* qhasm: A = YpX1*YpX2 */ 53 | /* asm 1: fe_mul(>A=fe#3,A=r->Z,X,YplusX); */ 55 | fe_mul(r->Z,r->X,q->YplusX); 56 | 57 | /* qhasm: B = YmX1*YmX2 */ 58 | /* asm 1: fe_mul(>B=fe#2,B=r->Y,Y,YminusX); */ 60 | fe_mul(r->Y,r->Y,q->YminusX); 61 | 62 | /* qhasm: C = T2d2*T1 */ 63 | /* asm 1: fe_mul(>C=fe#4,C=r->T,T2d,T); */ 65 | fe_mul(r->T,q->T2d,p->T); 66 | 67 | /* qhasm: ZZ = Z1*Z2 */ 68 | /* asm 1: fe_mul(>ZZ=fe#1,ZZ=r->X,Z,Z); */ 70 | fe_mul(r->X,p->Z,q->Z); 71 | 72 | /* qhasm: D = 2*ZZ */ 73 | /* asm 1: fe_add(>D=fe#5,D=t0,X,X); */ 75 | fe_add(t0,r->X,r->X); 76 | 77 | /* qhasm: X3 = A-B */ 78 | /* asm 1: fe_sub(>X3=fe#1,X3=r->X,Z,Y); */ 80 | fe_sub(r->X,r->Z,r->Y); 81 | 82 | /* qhasm: Y3 = A+B */ 83 | /* asm 1: fe_add(>Y3=fe#2,Y3=r->Y,Z,Y); */ 85 | fe_add(r->Y,r->Z,r->Y); 86 | 87 | /* qhasm: Z3 = D+C */ 88 | /* asm 1: fe_add(>Z3=fe#3,Z3=r->Z,T); */ 90 | fe_add(r->Z,t0,r->T); 91 | 92 | /* qhasm: T3 = D-C */ 93 | /* asm 1: fe_sub(>T3=fe#4,T3=r->T,T); */ 95 | fe_sub(r->T,t0,r->T); 96 | 97 | /* qhasm: return */ 98 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/ge_double_scalarmult.c: -------------------------------------------------------------------------------- 1 | #include "ge.h" 2 | 3 | static void slide(signed char *r,const unsigned char *a) 4 | { 5 | int i; 6 | int b; 7 | int k; 8 | 9 | for (i = 0;i < 256;++i) 10 | r[i] = 1 & (a[i >> 3] >> (i & 7)); 11 | 12 | for (i = 0;i < 256;++i) 13 | if (r[i]) { 14 | for (b = 1;b <= 6 && i + b < 256;++b) { 15 | if (r[i + b]) { 16 | if (r[i] + (r[i + b] << b) <= 15) { 17 | r[i] += r[i + b] << b; r[i + b] = 0; 18 | } else if (r[i] - (r[i + b] << b) >= -15) { 19 | r[i] -= r[i + b] << b; 20 | for (k = i + b;k < 256;++k) { 21 | if (!r[k]) { 22 | r[k] = 1; 23 | break; 24 | } 25 | r[k] = 0; 26 | } 27 | } else 28 | break; 29 | } 30 | } 31 | } 32 | 33 | } 34 | 35 | static ge_precomp Bi[8] = { 36 | #include "base2.h" 37 | } ; 38 | 39 | /* 40 | r = a * A + b * B 41 | where a = a[0]+256*a[1]+...+256^31 a[31]. 42 | and b = b[0]+256*b[1]+...+256^31 b[31]. 43 | B is the Ed25519 base point (x,4/5) with x positive. 44 | */ 45 | 46 | void ge_double_scalarmult_vartime(ge_p2 *r,const unsigned char *a,const ge_p3 *A,const unsigned char *b) 47 | { 48 | signed char aslide[256]; 49 | signed char bslide[256]; 50 | ge_cached Ai[8]; /* A,3A,5A,7A,9A,11A,13A,15A */ 51 | ge_p1p1 t; 52 | ge_p3 u; 53 | ge_p3 A2; 54 | int i; 55 | 56 | slide(aslide,a); 57 | slide(bslide,b); 58 | 59 | ge_p3_to_cached(&Ai[0],A); 60 | ge_p3_dbl(&t,A); ge_p1p1_to_p3(&A2,&t); 61 | ge_add(&t,&A2,&Ai[0]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[1],&u); 62 | ge_add(&t,&A2,&Ai[1]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[2],&u); 63 | ge_add(&t,&A2,&Ai[2]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[3],&u); 64 | ge_add(&t,&A2,&Ai[3]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[4],&u); 65 | ge_add(&t,&A2,&Ai[4]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[5],&u); 66 | ge_add(&t,&A2,&Ai[5]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[6],&u); 67 | ge_add(&t,&A2,&Ai[6]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[7],&u); 68 | 69 | ge_p2_0(r); 70 | 71 | for (i = 255;i >= 0;--i) { 72 | if (aslide[i] || bslide[i]) break; 73 | } 74 | 75 | for (;i >= 0;--i) { 76 | ge_p2_dbl(&t,r); 77 | 78 | if (aslide[i] > 0) { 79 | ge_p1p1_to_p3(&u,&t); 80 | ge_add(&t,&u,&Ai[aslide[i]/2]); 81 | } else if (aslide[i] < 0) { 82 | ge_p1p1_to_p3(&u,&t); 83 | ge_sub(&t,&u,&Ai[(-aslide[i])/2]); 84 | } 85 | 86 | if (bslide[i] > 0) { 87 | ge_p1p1_to_p3(&u,&t); 88 | ge_madd(&t,&u,&Bi[bslide[i]/2]); 89 | } else if (bslide[i] < 0) { 90 | ge_p1p1_to_p3(&u,&t); 91 | ge_msub(&t,&u,&Bi[(-bslide[i])/2]); 92 | } 93 | 94 | ge_p1p1_to_p2(r,&t); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/ge_frombytes.c: -------------------------------------------------------------------------------- 1 | #include "ge.h" 2 | 3 | static const fe d = { 4 | #include "d.h" 5 | } ; 6 | 7 | static const fe sqrtm1 = { 8 | #include "sqrtm1.h" 9 | } ; 10 | 11 | int ge_frombytes_negate_vartime(ge_p3 *h,const unsigned char *s) 12 | { 13 | fe u; 14 | fe v; 15 | fe v3; 16 | fe vxx; 17 | fe check; 18 | 19 | fe_frombytes(h->Y,s); 20 | fe_1(h->Z); 21 | fe_sq(u,h->Y); 22 | fe_mul(v,u,d); 23 | fe_sub(u,u,h->Z); /* u = y^2-1 */ 24 | fe_add(v,v,h->Z); /* v = dy^2+1 */ 25 | 26 | fe_sq(v3,v); 27 | fe_mul(v3,v3,v); /* v3 = v^3 */ 28 | fe_sq(h->X,v3); 29 | fe_mul(h->X,h->X,v); 30 | fe_mul(h->X,h->X,u); /* x = uv^7 */ 31 | 32 | fe_pow22523(h->X,h->X); /* x = (uv^7)^((q-5)/8) */ 33 | fe_mul(h->X,h->X,v3); 34 | fe_mul(h->X,h->X,u); /* x = uv^3(uv^7)^((q-5)/8) */ 35 | 36 | fe_sq(vxx,h->X); 37 | fe_mul(vxx,vxx,v); 38 | fe_sub(check,vxx,u); /* vx^2-u */ 39 | if (fe_isnonzero(check)) { 40 | fe_add(check,vxx,u); /* vx^2+u */ 41 | if (fe_isnonzero(check)) return -1; 42 | fe_mul(h->X,h->X,sqrtm1); 43 | } 44 | 45 | if (fe_isnegative(h->X) == (s[31] >> 7)) 46 | fe_neg(h->X,h->X); 47 | 48 | fe_mul(h->T,h->X,h->Y); 49 | return 0; 50 | } 51 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/ge_madd.c: -------------------------------------------------------------------------------- 1 | #include "ge.h" 2 | 3 | /* 4 | r = p + q 5 | */ 6 | 7 | void ge_madd(ge_p1p1 *r,const ge_p3 *p,const ge_precomp *q) 8 | { 9 | fe t0; 10 | #include "ge_madd.h" 11 | } 12 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/ge_madd.h: -------------------------------------------------------------------------------- 1 | 2 | /* qhasm: enter ge_madd */ 3 | 4 | /* qhasm: fe X1 */ 5 | 6 | /* qhasm: fe Y1 */ 7 | 8 | /* qhasm: fe Z1 */ 9 | 10 | /* qhasm: fe T1 */ 11 | 12 | /* qhasm: fe ypx2 */ 13 | 14 | /* qhasm: fe ymx2 */ 15 | 16 | /* qhasm: fe xy2d2 */ 17 | 18 | /* qhasm: fe X3 */ 19 | 20 | /* qhasm: fe Y3 */ 21 | 22 | /* qhasm: fe Z3 */ 23 | 24 | /* qhasm: fe T3 */ 25 | 26 | /* qhasm: fe YpX1 */ 27 | 28 | /* qhasm: fe YmX1 */ 29 | 30 | /* qhasm: fe A */ 31 | 32 | /* qhasm: fe B */ 33 | 34 | /* qhasm: fe C */ 35 | 36 | /* qhasm: fe D */ 37 | 38 | /* qhasm: YpX1 = Y1+X1 */ 39 | /* asm 1: fe_add(>YpX1=fe#1,YpX1=r->X,Y,X); */ 41 | fe_add(r->X,p->Y,p->X); 42 | 43 | /* qhasm: YmX1 = Y1-X1 */ 44 | /* asm 1: fe_sub(>YmX1=fe#2,YmX1=r->Y,Y,X); */ 46 | fe_sub(r->Y,p->Y,p->X); 47 | 48 | /* qhasm: A = YpX1*ypx2 */ 49 | /* asm 1: fe_mul(>A=fe#3,A=r->Z,X,yplusx); */ 51 | fe_mul(r->Z,r->X,q->yplusx); 52 | 53 | /* qhasm: B = YmX1*ymx2 */ 54 | /* asm 1: fe_mul(>B=fe#2,B=r->Y,Y,yminusx); */ 56 | fe_mul(r->Y,r->Y,q->yminusx); 57 | 58 | /* qhasm: C = xy2d2*T1 */ 59 | /* asm 1: fe_mul(>C=fe#4,C=r->T,xy2d,T); */ 61 | fe_mul(r->T,q->xy2d,p->T); 62 | 63 | /* qhasm: D = 2*Z1 */ 64 | /* asm 1: fe_add(>D=fe#5,D=t0,Z,Z); */ 66 | fe_add(t0,p->Z,p->Z); 67 | 68 | /* qhasm: X3 = A-B */ 69 | /* asm 1: fe_sub(>X3=fe#1,X3=r->X,Z,Y); */ 71 | fe_sub(r->X,r->Z,r->Y); 72 | 73 | /* qhasm: Y3 = A+B */ 74 | /* asm 1: fe_add(>Y3=fe#2,Y3=r->Y,Z,Y); */ 76 | fe_add(r->Y,r->Z,r->Y); 77 | 78 | /* qhasm: Z3 = D+C */ 79 | /* asm 1: fe_add(>Z3=fe#3,Z3=r->Z,T); */ 81 | fe_add(r->Z,t0,r->T); 82 | 83 | /* qhasm: T3 = D-C */ 84 | /* asm 1: fe_sub(>T3=fe#4,T3=r->T,T); */ 86 | fe_sub(r->T,t0,r->T); 87 | 88 | /* qhasm: return */ 89 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/ge_msub.c: -------------------------------------------------------------------------------- 1 | #include "ge.h" 2 | 3 | /* 4 | r = p - q 5 | */ 6 | 7 | void ge_msub(ge_p1p1 *r,const ge_p3 *p,const ge_precomp *q) 8 | { 9 | fe t0; 10 | #include "ge_msub.h" 11 | } 12 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/ge_msub.h: -------------------------------------------------------------------------------- 1 | 2 | /* qhasm: enter ge_msub */ 3 | 4 | /* qhasm: fe X1 */ 5 | 6 | /* qhasm: fe Y1 */ 7 | 8 | /* qhasm: fe Z1 */ 9 | 10 | /* qhasm: fe T1 */ 11 | 12 | /* qhasm: fe ypx2 */ 13 | 14 | /* qhasm: fe ymx2 */ 15 | 16 | /* qhasm: fe xy2d2 */ 17 | 18 | /* qhasm: fe X3 */ 19 | 20 | /* qhasm: fe Y3 */ 21 | 22 | /* qhasm: fe Z3 */ 23 | 24 | /* qhasm: fe T3 */ 25 | 26 | /* qhasm: fe YpX1 */ 27 | 28 | /* qhasm: fe YmX1 */ 29 | 30 | /* qhasm: fe A */ 31 | 32 | /* qhasm: fe B */ 33 | 34 | /* qhasm: fe C */ 35 | 36 | /* qhasm: fe D */ 37 | 38 | /* qhasm: YpX1 = Y1+X1 */ 39 | /* asm 1: fe_add(>YpX1=fe#1,YpX1=r->X,Y,X); */ 41 | fe_add(r->X,p->Y,p->X); 42 | 43 | /* qhasm: YmX1 = Y1-X1 */ 44 | /* asm 1: fe_sub(>YmX1=fe#2,YmX1=r->Y,Y,X); */ 46 | fe_sub(r->Y,p->Y,p->X); 47 | 48 | /* qhasm: A = YpX1*ymx2 */ 49 | /* asm 1: fe_mul(>A=fe#3,A=r->Z,X,yminusx); */ 51 | fe_mul(r->Z,r->X,q->yminusx); 52 | 53 | /* qhasm: B = YmX1*ypx2 */ 54 | /* asm 1: fe_mul(>B=fe#2,B=r->Y,Y,yplusx); */ 56 | fe_mul(r->Y,r->Y,q->yplusx); 57 | 58 | /* qhasm: C = xy2d2*T1 */ 59 | /* asm 1: fe_mul(>C=fe#4,C=r->T,xy2d,T); */ 61 | fe_mul(r->T,q->xy2d,p->T); 62 | 63 | /* qhasm: D = 2*Z1 */ 64 | /* asm 1: fe_add(>D=fe#5,D=t0,Z,Z); */ 66 | fe_add(t0,p->Z,p->Z); 67 | 68 | /* qhasm: X3 = A-B */ 69 | /* asm 1: fe_sub(>X3=fe#1,X3=r->X,Z,Y); */ 71 | fe_sub(r->X,r->Z,r->Y); 72 | 73 | /* qhasm: Y3 = A+B */ 74 | /* asm 1: fe_add(>Y3=fe#2,Y3=r->Y,Z,Y); */ 76 | fe_add(r->Y,r->Z,r->Y); 77 | 78 | /* qhasm: Z3 = D-C */ 79 | /* asm 1: fe_sub(>Z3=fe#3,Z3=r->Z,T); */ 81 | fe_sub(r->Z,t0,r->T); 82 | 83 | /* qhasm: T3 = D+C */ 84 | /* asm 1: fe_add(>T3=fe#4,T3=r->T,T); */ 86 | fe_add(r->T,t0,r->T); 87 | 88 | /* qhasm: return */ 89 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/ge_p1p1_to_p2.c: -------------------------------------------------------------------------------- 1 | #include "ge.h" 2 | 3 | /* 4 | r = p 5 | */ 6 | 7 | extern void ge_p1p1_to_p2(ge_p2 *r,const ge_p1p1 *p) 8 | { 9 | fe_mul(r->X,p->X,p->T); 10 | fe_mul(r->Y,p->Y,p->Z); 11 | fe_mul(r->Z,p->Z,p->T); 12 | } 13 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/ge_p1p1_to_p3.c: -------------------------------------------------------------------------------- 1 | #include "ge.h" 2 | 3 | /* 4 | r = p 5 | */ 6 | 7 | extern void ge_p1p1_to_p3(ge_p3 *r,const ge_p1p1 *p) 8 | { 9 | fe_mul(r->X,p->X,p->T); 10 | fe_mul(r->Y,p->Y,p->Z); 11 | fe_mul(r->Z,p->Z,p->T); 12 | fe_mul(r->T,p->X,p->Y); 13 | } 14 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/ge_p2_0.c: -------------------------------------------------------------------------------- 1 | #include "ge.h" 2 | 3 | void ge_p2_0(ge_p2 *h) 4 | { 5 | fe_0(h->X); 6 | fe_1(h->Y); 7 | fe_1(h->Z); 8 | } 9 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/ge_p2_dbl.c: -------------------------------------------------------------------------------- 1 | #include "ge.h" 2 | 3 | /* 4 | r = 2 * p 5 | */ 6 | 7 | void ge_p2_dbl(ge_p1p1 *r,const ge_p2 *p) 8 | { 9 | fe t0; 10 | #include "ge_p2_dbl.h" 11 | } 12 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/ge_p2_dbl.h: -------------------------------------------------------------------------------- 1 | 2 | /* qhasm: enter ge_p2_dbl */ 3 | 4 | /* qhasm: fe X1 */ 5 | 6 | /* qhasm: fe Y1 */ 7 | 8 | /* qhasm: fe Z1 */ 9 | 10 | /* qhasm: fe A */ 11 | 12 | /* qhasm: fe AA */ 13 | 14 | /* qhasm: fe XX */ 15 | 16 | /* qhasm: fe YY */ 17 | 18 | /* qhasm: fe B */ 19 | 20 | /* qhasm: fe X3 */ 21 | 22 | /* qhasm: fe Y3 */ 23 | 24 | /* qhasm: fe Z3 */ 25 | 26 | /* qhasm: fe T3 */ 27 | 28 | /* qhasm: XX=X1^2 */ 29 | /* asm 1: fe_sq(>XX=fe#1,XX=r->X,X); */ 31 | fe_sq(r->X,p->X); 32 | 33 | /* qhasm: YY=Y1^2 */ 34 | /* asm 1: fe_sq(>YY=fe#3,YY=r->Z,Y); */ 36 | fe_sq(r->Z,p->Y); 37 | 38 | /* qhasm: B=2*Z1^2 */ 39 | /* asm 1: fe_sq2(>B=fe#4,B=r->T,Z); */ 41 | fe_sq2(r->T,p->Z); 42 | 43 | /* qhasm: A=X1+Y1 */ 44 | /* asm 1: fe_add(>A=fe#2,A=r->Y,X,Y); */ 46 | fe_add(r->Y,p->X,p->Y); 47 | 48 | /* qhasm: AA=A^2 */ 49 | /* asm 1: fe_sq(>AA=fe#5,AA=t0,Y); */ 51 | fe_sq(t0,r->Y); 52 | 53 | /* qhasm: Y3=YY+XX */ 54 | /* asm 1: fe_add(>Y3=fe#2,Y3=r->Y,Z,X); */ 56 | fe_add(r->Y,r->Z,r->X); 57 | 58 | /* qhasm: Z3=YY-XX */ 59 | /* asm 1: fe_sub(>Z3=fe#3,Z3=r->Z,Z,X); */ 61 | fe_sub(r->Z,r->Z,r->X); 62 | 63 | /* qhasm: X3=AA-Y3 */ 64 | /* asm 1: fe_sub(>X3=fe#1,X3=r->X,Y); */ 66 | fe_sub(r->X,t0,r->Y); 67 | 68 | /* qhasm: T3=B-Z3 */ 69 | /* asm 1: fe_sub(>T3=fe#4,T3=r->T,T,Z); */ 71 | fe_sub(r->T,r->T,r->Z); 72 | 73 | /* qhasm: return */ 74 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/ge_p3_0.c: -------------------------------------------------------------------------------- 1 | #include "ge.h" 2 | 3 | void ge_p3_0(ge_p3 *h) 4 | { 5 | fe_0(h->X); 6 | fe_1(h->Y); 7 | fe_1(h->Z); 8 | fe_0(h->T); 9 | } 10 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/ge_p3_dbl.c: -------------------------------------------------------------------------------- 1 | #include "ge.h" 2 | 3 | /* 4 | r = 2 * p 5 | */ 6 | 7 | void ge_p3_dbl(ge_p1p1 *r,const ge_p3 *p) 8 | { 9 | ge_p2 q; 10 | ge_p3_to_p2(&q,p); 11 | ge_p2_dbl(r,&q); 12 | } 13 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/ge_p3_to_cached.c: -------------------------------------------------------------------------------- 1 | #include "ge.h" 2 | 3 | /* 4 | r = p 5 | */ 6 | 7 | static const fe d2 = { 8 | #include "d2.h" 9 | } ; 10 | 11 | extern void ge_p3_to_cached(ge_cached *r,const ge_p3 *p) 12 | { 13 | fe_add(r->YplusX,p->Y,p->X); 14 | fe_sub(r->YminusX,p->Y,p->X); 15 | fe_copy(r->Z,p->Z); 16 | fe_mul(r->T2d,p->T,d2); 17 | } 18 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/ge_p3_to_p2.c: -------------------------------------------------------------------------------- 1 | #include "ge.h" 2 | 3 | /* 4 | r = p 5 | */ 6 | 7 | extern void ge_p3_to_p2(ge_p2 *r,const ge_p3 *p) 8 | { 9 | fe_copy(r->X,p->X); 10 | fe_copy(r->Y,p->Y); 11 | fe_copy(r->Z,p->Z); 12 | } 13 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/ge_p3_tobytes.c: -------------------------------------------------------------------------------- 1 | #include "ge.h" 2 | 3 | void ge_p3_tobytes(unsigned char *s,const ge_p3 *h) 4 | { 5 | fe recip; 6 | fe x; 7 | fe y; 8 | 9 | fe_invert(recip,h->Z); 10 | fe_mul(x,h->X,recip); 11 | fe_mul(y,h->Y,recip); 12 | fe_tobytes(s,y); 13 | s[31] ^= fe_isnegative(x) << 7; 14 | } 15 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/ge_precomp_0.c: -------------------------------------------------------------------------------- 1 | #include "ge.h" 2 | 3 | void ge_precomp_0(ge_precomp *h) 4 | { 5 | fe_1(h->yplusx); 6 | fe_1(h->yminusx); 7 | fe_0(h->xy2d); 8 | } 9 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/ge_scalarmult_base.c: -------------------------------------------------------------------------------- 1 | #include "ge.h" 2 | #include "crypto_uint32.h" 3 | 4 | static unsigned char equal(signed char b,signed char c) 5 | { 6 | unsigned char ub = b; 7 | unsigned char uc = c; 8 | unsigned char x = ub ^ uc; /* 0: yes; 1..255: no */ 9 | crypto_uint32 y = x; /* 0: yes; 1..255: no */ 10 | y -= 1; /* 4294967295: yes; 0..254: no */ 11 | y >>= 31; /* 1: yes; 0: no */ 12 | return y; 13 | } 14 | 15 | static unsigned char negative(signed char b) 16 | { 17 | unsigned long long x = b; /* 18446744073709551361..18446744073709551615: yes; 0..255: no */ 18 | x >>= 63; /* 1: yes; 0: no */ 19 | return x; 20 | } 21 | 22 | static void cmov(ge_precomp *t,ge_precomp *u,unsigned char b) 23 | { 24 | fe_cmov(t->yplusx,u->yplusx,b); 25 | fe_cmov(t->yminusx,u->yminusx,b); 26 | fe_cmov(t->xy2d,u->xy2d,b); 27 | } 28 | 29 | /* base[i][j] = (j+1)*256^i*B */ 30 | static ge_precomp base[32][8] = { 31 | #include "base.h" 32 | } ; 33 | 34 | static void select(ge_precomp *t,int pos,signed char b) 35 | { 36 | ge_precomp minust; 37 | unsigned char bnegative = negative(b); 38 | unsigned char babs = b - (((-bnegative) & b) << 1); 39 | 40 | ge_precomp_0(t); 41 | cmov(t,&base[pos][0],equal(babs,1)); 42 | cmov(t,&base[pos][1],equal(babs,2)); 43 | cmov(t,&base[pos][2],equal(babs,3)); 44 | cmov(t,&base[pos][3],equal(babs,4)); 45 | cmov(t,&base[pos][4],equal(babs,5)); 46 | cmov(t,&base[pos][5],equal(babs,6)); 47 | cmov(t,&base[pos][6],equal(babs,7)); 48 | cmov(t,&base[pos][7],equal(babs,8)); 49 | fe_copy(minust.yplusx,t->yminusx); 50 | fe_copy(minust.yminusx,t->yplusx); 51 | fe_neg(minust.xy2d,t->xy2d); 52 | cmov(t,&minust,bnegative); 53 | } 54 | 55 | /* 56 | h = a * B 57 | where a = a[0]+256*a[1]+...+256^31 a[31] 58 | B is the Ed25519 base point (x,4/5) with x positive. 59 | 60 | Preconditions: 61 | a[31] <= 127 62 | */ 63 | 64 | void ge_scalarmult_base(ge_p3 *h,const unsigned char *a) 65 | { 66 | signed char e[64]; 67 | signed char carry; 68 | ge_p1p1 r; 69 | ge_p2 s; 70 | ge_precomp t; 71 | int i; 72 | 73 | for (i = 0;i < 32;++i) { 74 | e[2 * i + 0] = (a[i] >> 0) & 15; 75 | e[2 * i + 1] = (a[i] >> 4) & 15; 76 | } 77 | /* each e[i] is between 0 and 15 */ 78 | /* e[63] is between 0 and 7 */ 79 | 80 | carry = 0; 81 | for (i = 0;i < 63;++i) { 82 | e[i] += carry; 83 | carry = e[i] + 8; 84 | carry >>= 4; 85 | e[i] -= carry << 4; 86 | } 87 | e[63] += carry; 88 | /* each e[i] is between -8 and 8 */ 89 | 90 | ge_p3_0(h); 91 | for (i = 1;i < 64;i += 2) { 92 | select(&t,i / 2,e[i]); 93 | ge_madd(&r,h,&t); ge_p1p1_to_p3(h,&r); 94 | } 95 | 96 | ge_p3_dbl(&r,h); ge_p1p1_to_p2(&s,&r); 97 | ge_p2_dbl(&r,&s); ge_p1p1_to_p2(&s,&r); 98 | ge_p2_dbl(&r,&s); ge_p1p1_to_p2(&s,&r); 99 | ge_p2_dbl(&r,&s); ge_p1p1_to_p3(h,&r); 100 | 101 | for (i = 0;i < 64;i += 2) { 102 | select(&t,i / 2,e[i]); 103 | ge_madd(&r,h,&t); ge_p1p1_to_p3(h,&r); 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/ge_sub.c: -------------------------------------------------------------------------------- 1 | #include "ge.h" 2 | 3 | /* 4 | r = p - q 5 | */ 6 | 7 | void ge_sub(ge_p1p1 *r,const ge_p3 *p,const ge_cached *q) 8 | { 9 | fe t0; 10 | #include "ge_sub.h" 11 | } 12 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/ge_sub.h: -------------------------------------------------------------------------------- 1 | 2 | /* qhasm: enter ge_sub */ 3 | 4 | /* qhasm: fe X1 */ 5 | 6 | /* qhasm: fe Y1 */ 7 | 8 | /* qhasm: fe Z1 */ 9 | 10 | /* qhasm: fe Z2 */ 11 | 12 | /* qhasm: fe T1 */ 13 | 14 | /* qhasm: fe ZZ */ 15 | 16 | /* qhasm: fe YpX2 */ 17 | 18 | /* qhasm: fe YmX2 */ 19 | 20 | /* qhasm: fe T2d2 */ 21 | 22 | /* qhasm: fe X3 */ 23 | 24 | /* qhasm: fe Y3 */ 25 | 26 | /* qhasm: fe Z3 */ 27 | 28 | /* qhasm: fe T3 */ 29 | 30 | /* qhasm: fe YpX1 */ 31 | 32 | /* qhasm: fe YmX1 */ 33 | 34 | /* qhasm: fe A */ 35 | 36 | /* qhasm: fe B */ 37 | 38 | /* qhasm: fe C */ 39 | 40 | /* qhasm: fe D */ 41 | 42 | /* qhasm: YpX1 = Y1+X1 */ 43 | /* asm 1: fe_add(>YpX1=fe#1,YpX1=r->X,Y,X); */ 45 | fe_add(r->X,p->Y,p->X); 46 | 47 | /* qhasm: YmX1 = Y1-X1 */ 48 | /* asm 1: fe_sub(>YmX1=fe#2,YmX1=r->Y,Y,X); */ 50 | fe_sub(r->Y,p->Y,p->X); 51 | 52 | /* qhasm: A = YpX1*YmX2 */ 53 | /* asm 1: fe_mul(>A=fe#3,A=r->Z,X,YminusX); */ 55 | fe_mul(r->Z,r->X,q->YminusX); 56 | 57 | /* qhasm: B = YmX1*YpX2 */ 58 | /* asm 1: fe_mul(>B=fe#2,B=r->Y,Y,YplusX); */ 60 | fe_mul(r->Y,r->Y,q->YplusX); 61 | 62 | /* qhasm: C = T2d2*T1 */ 63 | /* asm 1: fe_mul(>C=fe#4,C=r->T,T2d,T); */ 65 | fe_mul(r->T,q->T2d,p->T); 66 | 67 | /* qhasm: ZZ = Z1*Z2 */ 68 | /* asm 1: fe_mul(>ZZ=fe#1,ZZ=r->X,Z,Z); */ 70 | fe_mul(r->X,p->Z,q->Z); 71 | 72 | /* qhasm: D = 2*ZZ */ 73 | /* asm 1: fe_add(>D=fe#5,D=t0,X,X); */ 75 | fe_add(t0,r->X,r->X); 76 | 77 | /* qhasm: X3 = A-B */ 78 | /* asm 1: fe_sub(>X3=fe#1,X3=r->X,Z,Y); */ 80 | fe_sub(r->X,r->Z,r->Y); 81 | 82 | /* qhasm: Y3 = A+B */ 83 | /* asm 1: fe_add(>Y3=fe#2,Y3=r->Y,Z,Y); */ 85 | fe_add(r->Y,r->Z,r->Y); 86 | 87 | /* qhasm: Z3 = D-C */ 88 | /* asm 1: fe_sub(>Z3=fe#3,Z3=r->Z,T); */ 90 | fe_sub(r->Z,t0,r->T); 91 | 92 | /* qhasm: T3 = D+C */ 93 | /* asm 1: fe_add(>T3=fe#4,T3=r->T,T); */ 95 | fe_add(r->T,t0,r->T); 96 | 97 | /* qhasm: return */ 98 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/ge_tobytes.c: -------------------------------------------------------------------------------- 1 | #include "ge.h" 2 | 3 | void ge_tobytes(unsigned char *s,const ge_p2 *h) 4 | { 5 | fe recip; 6 | fe x; 7 | fe y; 8 | 9 | fe_invert(recip,h->Z); 10 | fe_mul(x,h->X,recip); 11 | fe_mul(y,h->Y,recip); 12 | fe_tobytes(s,y); 13 | s[31] ^= fe_isnegative(x) << 7; 14 | } 15 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/nacl_includes/crypto_int32.h: -------------------------------------------------------------------------------- 1 | #ifndef crypto_int32_h 2 | #define crypto_int32_h 3 | 4 | typedef int crypto_int32; 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/nacl_includes/crypto_int64.h: -------------------------------------------------------------------------------- 1 | #ifndef crypto_int64_h 2 | #define crypto_int64_h 3 | 4 | typedef long long crypto_int64; 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/nacl_includes/crypto_sign.h: -------------------------------------------------------------------------------- 1 | #ifndef crypto_sign_H 2 | #define crypto_sign_H 3 | 4 | #include "crypto_sign_edwards25519sha512batch.h" 5 | 6 | #define crypto_sign crypto_sign_edwards25519sha512batch 7 | #define crypto_sign_open crypto_sign_edwards25519sha512batch_open 8 | #define crypto_sign_keypair crypto_sign_edwards25519sha512batch_keypair 9 | #define crypto_sign_BYTES crypto_sign_edwards25519sha512batch_BYTES 10 | #define crypto_sign_PUBLICKEYBYTES crypto_sign_edwards25519sha512batch_PUBLICKEYBYTES 11 | #define crypto_sign_SECRETKEYBYTES crypto_sign_edwards25519sha512batch_SECRETKEYBYTES 12 | #define crypto_sign_PRIMITIVE "edwards25519sha512batch" 13 | #define crypto_sign_IMPLEMENTATION crypto_sign_edwards25519sha512batch_IMPLEMENTATION 14 | #define crypto_sign_VERSION crypto_sign_edwards25519sha512batch_VERSION 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/nacl_includes/crypto_sign_edwards25519sha512batch.h: -------------------------------------------------------------------------------- 1 | #ifndef crypto_sign_edwards25519sha512batch_H 2 | #define crypto_sign_edwards25519sha512batch_H 3 | 4 | #define crypto_sign_edwards25519sha512batch_ref10_SECRETKEYBYTES 64 5 | #define crypto_sign_edwards25519sha512batch_ref10_PUBLICKEYBYTES 32 6 | #define crypto_sign_edwards25519sha512batch_ref10_BYTES 64 7 | #ifdef __cplusplus 8 | #include 9 | extern std::string crypto_sign_edwards25519sha512batch_ref10(const std::string &,const std::string &); 10 | extern std::string crypto_sign_edwards25519sha512batch_ref10_open(const std::string &,const std::string &); 11 | extern std::string crypto_sign_edwards25519sha512batch_ref10_keypair(std::string *); 12 | extern "C" { 13 | #endif 14 | extern int crypto_sign_edwards25519sha512batch_ref10(unsigned char *,unsigned long long *,const unsigned char *,unsigned long long,const unsigned char *); 15 | extern int crypto_sign_edwards25519sha512batch_ref10_open(unsigned char *,unsigned long long *,const unsigned char *,unsigned long long,const unsigned char *); 16 | extern int crypto_sign_edwards25519sha512batch_ref10_keypair(unsigned char *,unsigned char *); 17 | #ifdef __cplusplus 18 | } 19 | #endif 20 | 21 | #define crypto_sign_edwards25519sha512batch crypto_sign_edwards25519sha512batch_ref10 22 | #define crypto_sign_edwards25519sha512batch_open crypto_sign_edwards25519sha512batch_ref10_open 23 | #define crypto_sign_edwards25519sha512batch_keypair crypto_sign_edwards25519sha512batch_ref10_keypair 24 | #define crypto_sign_edwards25519sha512batch_BYTES crypto_sign_edwards25519sha512batch_ref10_BYTES 25 | #define crypto_sign_edwards25519sha512batch_PUBLICKEYBYTES crypto_sign_edwards25519sha512batch_ref10_PUBLICKEYBYTES 26 | #define crypto_sign_edwards25519sha512batch_SECRETKEYBYTES crypto_sign_edwards25519sha512batch_ref10_SECRETKEYBYTES 27 | #define crypto_sign_edwards25519sha512batch_IMPLEMENTATION "crypto_sign/edwards25519sha512batch/ref10" 28 | #ifndef crypto_sign_edwards25519sha512batch_ref10_VERSION 29 | #define crypto_sign_edwards25519sha512batch_ref10_VERSION "-" 30 | #endif 31 | #define crypto_sign_edwards25519sha512batch_VERSION crypto_sign_edwards25519sha512batch_ref10_VERSION 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/nacl_includes/crypto_uint32.h: -------------------------------------------------------------------------------- 1 | #ifndef crypto_uint32_h 2 | #define crypto_uint32_h 3 | 4 | typedef unsigned int crypto_uint32; 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/nacl_includes/crypto_uint64.h: -------------------------------------------------------------------------------- 1 | #ifndef crypto_uint64_h 2 | #define crypto_uint64_h 3 | 4 | typedef unsigned long long crypto_uint64; 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/nacl_includes/crypto_verify_32.h: -------------------------------------------------------------------------------- 1 | #ifndef crypto_verify_32_H 2 | #define crypto_verify_32_H 3 | 4 | #define crypto_verify_32_ref_BYTES 32 5 | #ifdef __cplusplus 6 | #include 7 | extern "C" { 8 | #endif 9 | extern int crypto_verify_32_ref(const unsigned char *,const unsigned char *); 10 | #ifdef __cplusplus 11 | } 12 | #endif 13 | 14 | #define crypto_verify_32 crypto_verify_32_ref 15 | #define crypto_verify_32_BYTES crypto_verify_32_ref_BYTES 16 | #define crypto_verify_32_IMPLEMENTATION "crypto_verify/32/ref" 17 | #ifndef crypto_verify_32_ref_VERSION 18 | #define crypto_verify_32_ref_VERSION "-" 19 | #endif 20 | #define crypto_verify_32_VERSION crypto_verify_32_ref_VERSION 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/nacl_sha512/hash.c: -------------------------------------------------------------------------------- 1 | /* 2 | 20080913 3 | D. J. Bernstein 4 | Public domain. 5 | */ 6 | 7 | #include 8 | typedef uint64_t uint64; 9 | 10 | extern int crypto_hashblocks_sha512(unsigned char *statebytes,const unsigned char *in,unsigned long long inlen); 11 | 12 | #define blocks crypto_hashblocks_sha512 13 | 14 | static const unsigned char iv[64] = { 15 | 0x6a,0x09,0xe6,0x67,0xf3,0xbc,0xc9,0x08, 16 | 0xbb,0x67,0xae,0x85,0x84,0xca,0xa7,0x3b, 17 | 0x3c,0x6e,0xf3,0x72,0xfe,0x94,0xf8,0x2b, 18 | 0xa5,0x4f,0xf5,0x3a,0x5f,0x1d,0x36,0xf1, 19 | 0x51,0x0e,0x52,0x7f,0xad,0xe6,0x82,0xd1, 20 | 0x9b,0x05,0x68,0x8c,0x2b,0x3e,0x6c,0x1f, 21 | 0x1f,0x83,0xd9,0xab,0xfb,0x41,0xbd,0x6b, 22 | 0x5b,0xe0,0xcd,0x19,0x13,0x7e,0x21,0x79 23 | } ; 24 | 25 | int crypto_hash_sha512(unsigned char *out,const unsigned char *in,unsigned long long inlen) 26 | { 27 | unsigned char h[64]; 28 | unsigned char padded[256]; 29 | int i; 30 | unsigned long long bytes = inlen; 31 | 32 | for (i = 0;i < 64;++i) h[i] = iv[i]; 33 | 34 | blocks(h,in,inlen); 35 | in += inlen; 36 | inlen &= 127; 37 | in -= inlen; 38 | 39 | for (i = 0;i < inlen;++i) padded[i] = in[i]; 40 | padded[inlen] = 0x80; 41 | 42 | if (inlen < 112) { 43 | for (i = inlen + 1;i < 119;++i) padded[i] = 0; 44 | padded[119] = bytes >> 61; 45 | padded[120] = bytes >> 53; 46 | padded[121] = bytes >> 45; 47 | padded[122] = bytes >> 37; 48 | padded[123] = bytes >> 29; 49 | padded[124] = bytes >> 21; 50 | padded[125] = bytes >> 13; 51 | padded[126] = bytes >> 5; 52 | padded[127] = bytes << 3; 53 | blocks(h,padded,128); 54 | } else { 55 | for (i = inlen + 1;i < 247;++i) padded[i] = 0; 56 | padded[247] = bytes >> 61; 57 | padded[248] = bytes >> 53; 58 | padded[249] = bytes >> 45; 59 | padded[250] = bytes >> 37; 60 | padded[251] = bytes >> 29; 61 | padded[252] = bytes >> 21; 62 | padded[253] = bytes >> 13; 63 | padded[254] = bytes >> 5; 64 | padded[255] = bytes << 3; 65 | blocks(h,padded,256); 66 | } 67 | 68 | for (i = 0;i < 64;++i) out[i] = h[i]; 69 | 70 | return 0; 71 | } 72 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/open.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "crypto_sign.h" 3 | #include "crypto_hash_sha512.h" 4 | #include "crypto_verify_32.h" 5 | #include "ge.h" 6 | #include "sc.h" 7 | 8 | int crypto_sign_open( 9 | unsigned char *m,unsigned long long *mlen, 10 | const unsigned char *sm,unsigned long long smlen, 11 | const unsigned char *pk 12 | ) 13 | { 14 | unsigned char pkcopy[32]; 15 | unsigned char rcopy[32]; 16 | unsigned char scopy[32]; 17 | unsigned char h[64]; 18 | unsigned char rcheck[32]; 19 | ge_p3 A; 20 | ge_p2 R; 21 | 22 | if (smlen < 64) goto badsig; 23 | if (sm[63] & 224) goto badsig; 24 | if (ge_frombytes_negate_vartime(&A,pk) != 0) goto badsig; 25 | 26 | memmove(pkcopy,pk,32); 27 | memmove(rcopy,sm,32); 28 | memmove(scopy,sm + 32,32); 29 | 30 | memmove(m,sm,smlen); 31 | memmove(m + 32,pkcopy,32); 32 | crypto_hash_sha512(h,m,smlen); 33 | sc_reduce(h); 34 | 35 | ge_double_scalarmult_vartime(&R,h,&A,scopy); 36 | ge_tobytes(rcheck,&R); 37 | if (crypto_verify_32(rcheck,rcopy) == 0) { 38 | memmove(m,m + 64,smlen - 64); 39 | memset(m + smlen - 64,0,64); 40 | *mlen = smlen - 64; 41 | return 0; 42 | } 43 | 44 | badsig: 45 | *mlen = -1; 46 | memset(m,0,smlen); 47 | return -1; 48 | } 49 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/pow22523.h: -------------------------------------------------------------------------------- 1 | 2 | /* qhasm: fe z1 */ 3 | 4 | /* qhasm: fe z2 */ 5 | 6 | /* qhasm: fe z8 */ 7 | 8 | /* qhasm: fe z9 */ 9 | 10 | /* qhasm: fe z11 */ 11 | 12 | /* qhasm: fe z22 */ 13 | 14 | /* qhasm: fe z_5_0 */ 15 | 16 | /* qhasm: fe z_10_5 */ 17 | 18 | /* qhasm: fe z_10_0 */ 19 | 20 | /* qhasm: fe z_20_10 */ 21 | 22 | /* qhasm: fe z_20_0 */ 23 | 24 | /* qhasm: fe z_40_20 */ 25 | 26 | /* qhasm: fe z_40_0 */ 27 | 28 | /* qhasm: fe z_50_10 */ 29 | 30 | /* qhasm: fe z_50_0 */ 31 | 32 | /* qhasm: fe z_100_50 */ 33 | 34 | /* qhasm: fe z_100_0 */ 35 | 36 | /* qhasm: fe z_200_100 */ 37 | 38 | /* qhasm: fe z_200_0 */ 39 | 40 | /* qhasm: fe z_250_50 */ 41 | 42 | /* qhasm: fe z_250_0 */ 43 | 44 | /* qhasm: fe z_252_2 */ 45 | 46 | /* qhasm: fe z_252_3 */ 47 | 48 | /* qhasm: enter pow22523 */ 49 | 50 | /* qhasm: z2 = z1^2^1 */ 51 | /* asm 1: fe_sq(>z2=fe#1,z2=fe#1,>z2=fe#1); */ 52 | /* asm 2: fe_sq(>z2=t0,z2=t0,>z2=t0); */ 53 | fe_sq(t0,z); for (i = 1;i < 1;++i) fe_sq(t0,t0); 54 | 55 | /* qhasm: z8 = z2^2^2 */ 56 | /* asm 1: fe_sq(>z8=fe#2,z8=fe#2,>z8=fe#2); */ 57 | /* asm 2: fe_sq(>z8=t1,z8=t1,>z8=t1); */ 58 | fe_sq(t1,t0); for (i = 1;i < 2;++i) fe_sq(t1,t1); 59 | 60 | /* qhasm: z9 = z1*z8 */ 61 | /* asm 1: fe_mul(>z9=fe#2,z9=t1,z11=fe#1,z11=t0,z22=fe#1,z22=fe#1,>z22=fe#1); */ 72 | /* asm 2: fe_sq(>z22=t0,z22=t0,>z22=t0); */ 73 | fe_sq(t0,t0); for (i = 1;i < 1;++i) fe_sq(t0,t0); 74 | 75 | /* qhasm: z_5_0 = z9*z22 */ 76 | /* asm 1: fe_mul(>z_5_0=fe#1,z_5_0=t0,z_10_5=fe#2,z_10_5=fe#2,>z_10_5=fe#2); */ 82 | /* asm 2: fe_sq(>z_10_5=t1,z_10_5=t1,>z_10_5=t1); */ 83 | fe_sq(t1,t0); for (i = 1;i < 5;++i) fe_sq(t1,t1); 84 | 85 | /* qhasm: z_10_0 = z_10_5*z_5_0 */ 86 | /* asm 1: fe_mul(>z_10_0=fe#1,z_10_0=t0,z_20_10=fe#2,z_20_10=fe#2,>z_20_10=fe#2); */ 92 | /* asm 2: fe_sq(>z_20_10=t1,z_20_10=t1,>z_20_10=t1); */ 93 | fe_sq(t1,t0); for (i = 1;i < 10;++i) fe_sq(t1,t1); 94 | 95 | /* qhasm: z_20_0 = z_20_10*z_10_0 */ 96 | /* asm 1: fe_mul(>z_20_0=fe#2,z_20_0=t1,z_40_20=fe#3,z_40_20=fe#3,>z_40_20=fe#3); */ 102 | /* asm 2: fe_sq(>z_40_20=t2,z_40_20=t2,>z_40_20=t2); */ 103 | fe_sq(t2,t1); for (i = 1;i < 20;++i) fe_sq(t2,t2); 104 | 105 | /* qhasm: z_40_0 = z_40_20*z_20_0 */ 106 | /* asm 1: fe_mul(>z_40_0=fe#2,z_40_0=t1,z_50_10=fe#2,z_50_10=fe#2,>z_50_10=fe#2); */ 112 | /* asm 2: fe_sq(>z_50_10=t1,z_50_10=t1,>z_50_10=t1); */ 113 | fe_sq(t1,t1); for (i = 1;i < 10;++i) fe_sq(t1,t1); 114 | 115 | /* qhasm: z_50_0 = z_50_10*z_10_0 */ 116 | /* asm 1: fe_mul(>z_50_0=fe#1,z_50_0=t0,z_100_50=fe#2,z_100_50=fe#2,>z_100_50=fe#2); */ 122 | /* asm 2: fe_sq(>z_100_50=t1,z_100_50=t1,>z_100_50=t1); */ 123 | fe_sq(t1,t0); for (i = 1;i < 50;++i) fe_sq(t1,t1); 124 | 125 | /* qhasm: z_100_0 = z_100_50*z_50_0 */ 126 | /* asm 1: fe_mul(>z_100_0=fe#2,z_100_0=t1,z_200_100=fe#3,z_200_100=fe#3,>z_200_100=fe#3); */ 132 | /* asm 2: fe_sq(>z_200_100=t2,z_200_100=t2,>z_200_100=t2); */ 133 | fe_sq(t2,t1); for (i = 1;i < 100;++i) fe_sq(t2,t2); 134 | 135 | /* qhasm: z_200_0 = z_200_100*z_100_0 */ 136 | /* asm 1: fe_mul(>z_200_0=fe#2,z_200_0=t1,z_250_50=fe#2,z_250_50=fe#2,>z_250_50=fe#2); */ 142 | /* asm 2: fe_sq(>z_250_50=t1,z_250_50=t1,>z_250_50=t1); */ 143 | fe_sq(t1,t1); for (i = 1;i < 50;++i) fe_sq(t1,t1); 144 | 145 | /* qhasm: z_250_0 = z_250_50*z_50_0 */ 146 | /* asm 1: fe_mul(>z_250_0=fe#1,z_250_0=t0,z_252_2=fe#1,z_252_2=fe#1,>z_252_2=fe#1); */ 152 | /* asm 2: fe_sq(>z_252_2=t0,z_252_2=t0,>z_252_2=t0); */ 153 | fe_sq(t0,t0); for (i = 1;i < 2;++i) fe_sq(t0,t0); 154 | 155 | /* qhasm: z_252_3 = z_252_2*z1 */ 156 | /* asm 1: fe_mul(>z_252_3=fe#12,z_252_3=out, 2 | #include "crypto_sign.h" 3 | #include "crypto_hash_sha512.h" 4 | #include "ge.h" 5 | #include "sc.h" 6 | 7 | int crypto_sign( 8 | unsigned char *sm,unsigned long long *smlen, 9 | const unsigned char *m,unsigned long long mlen, 10 | const unsigned char *sk 11 | ) 12 | { 13 | unsigned char pk[32]; 14 | unsigned char az[64]; 15 | unsigned char nonce[64]; 16 | unsigned char hram[64]; 17 | ge_p3 R; 18 | 19 | memmove(pk,sk + 32,32); 20 | 21 | crypto_hash_sha512(az,sk,32); 22 | az[0] &= 248; 23 | az[31] &= 63; 24 | az[31] |= 64; 25 | 26 | *smlen = mlen + 64; 27 | memmove(sm + 64,m,mlen); 28 | memmove(sm + 32,az + 32,32); 29 | crypto_hash_sha512(nonce,sm + 32,mlen + 32); 30 | memmove(sm + 32,pk,32); 31 | 32 | sc_reduce(nonce); 33 | ge_scalarmult_base(&R,nonce); 34 | ge_p3_tobytes(sm,&R); 35 | 36 | crypto_hash_sha512(hram,sm,mlen + 64); 37 | sc_reduce(hram); 38 | sc_muladd(sm + 32,hram,az,nonce); 39 | 40 | return 0; 41 | } 42 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/sqrtm1.h: -------------------------------------------------------------------------------- 1 | -32595792,-7943725,9377950,3500415,12389472,-272473,-25146209,-2005654,326686,11406482 2 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/tests/internal_fast_tests.h: -------------------------------------------------------------------------------- 1 | #ifndef __INTERNAL_FAST_TESTS_H__ 2 | #define __INTERNAL_FAST_TESTS_H__ 3 | 4 | /* silent = 0 : prints info+error messages to stdout, abort() on test failure 5 | * silent = 1 : returns 0 for success, anything else for failure 6 | */ 7 | 8 | int sha512_fast_test(int silent); 9 | int strict_fast_test(int silent); 10 | int elligator_fast_test(int silent); 11 | int curvesigs_fast_test(int silent); 12 | int xeddsa_fast_test(int silent); 13 | int vxeddsa_fast_test(int silent); 14 | int generalized_xeddsa_fast_test(int silent); 15 | int generalized_xveddsa_fast_test(int silent); 16 | 17 | int all_fast_tests(int silent); 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /src/curve25519/ed25519/tests/internal_slow_tests.h: -------------------------------------------------------------------------------- 1 | #ifndef __INTERNAL_SLOW_TESTS_H__ 2 | #define __INTERNAL_SLOW_TESTS_H__ 3 | 4 | /* silent = 0 : prints info+error messages to stdout, abort() on test failure 5 | * silent = 1 : returns 0 for success, anything else for failure 6 | * iterations : hardcoded known-good values are at 10000, so run at least this many 7 | */ 8 | 9 | int curvesigs_slow_test(int silent, int iterations); 10 | int xeddsa_slow_test(int silent, int iterations); 11 | int xeddsa_to_curvesigs_slow_test(int silent, int iterations); 12 | int generalized_xveddsa_slow_test(int silent, int iterations); 13 | 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /src/device_consistency.h: -------------------------------------------------------------------------------- 1 | #ifndef DEVICE_CONSISTENCY_H 2 | #define DEVICE_CONSISTENCY_H 3 | 4 | #include "signal_protocol_types.h" 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | int device_consistency_signature_create(device_consistency_signature **signature, 11 | const uint8_t *signature_data, size_t signature_len, 12 | const uint8_t *vrf_output_data, size_t vrf_output_len); 13 | 14 | signal_buffer *device_consistency_signature_get_signature(const device_consistency_signature *signature); 15 | signal_buffer *device_consistency_signature_get_vrf_output(const device_consistency_signature *signature); 16 | 17 | void device_consistency_signature_destroy(signal_type_base *type); 18 | 19 | int device_consistency_commitment_create(device_consistency_commitment **commitment, 20 | uint32_t generation, ec_public_key_list *identity_key_list, 21 | signal_context *global_context); 22 | 23 | uint32_t device_consistency_commitment_get_generation(const device_consistency_commitment *commitment); 24 | signal_buffer *device_consistency_commitment_get_serialized(const device_consistency_commitment *commitment); 25 | 26 | void device_consistency_commitment_destroy(signal_type_base *type); 27 | 28 | int device_consistency_message_create_from_pair(device_consistency_message **message, 29 | device_consistency_commitment *commitment, 30 | ec_key_pair *identity_key_pair, 31 | signal_context *global_context); 32 | int device_consistency_message_create_from_serialized(device_consistency_message **message, 33 | device_consistency_commitment *commitment, 34 | const uint8_t *serialized_data, size_t serialized_len, 35 | ec_public_key *identity_key, 36 | signal_context *global_context); 37 | 38 | signal_buffer *device_consistency_message_get_serialized(const device_consistency_message *message); 39 | device_consistency_signature *device_consistency_message_get_signature(const device_consistency_message *message); 40 | uint32_t device_consistency_signature_get_generation(const device_consistency_message *message); 41 | 42 | void device_consistency_message_destroy(signal_type_base *type); 43 | 44 | int device_consistency_code_generate_for(device_consistency_commitment *commitment, 45 | device_consistency_signature_list *signatures, 46 | char **code_string, 47 | signal_context *global_context); 48 | 49 | device_consistency_signature_list *device_consistency_signature_list_alloc(void); 50 | device_consistency_signature_list *device_consistency_signature_list_copy(const device_consistency_signature_list *list); 51 | int device_consistency_signature_list_push_back(device_consistency_signature_list *list, device_consistency_signature *value); 52 | unsigned int device_consistency_signature_list_size(const device_consistency_signature_list *list); 53 | device_consistency_signature *device_consistency_signature_list_at(const device_consistency_signature_list *list, unsigned int index); 54 | void device_consistency_signature_list_free(device_consistency_signature_list *list); 55 | 56 | #ifdef __cplusplus 57 | } 58 | #endif 59 | 60 | #endif /* DEVICE_CONSISTENCY_H */ 61 | -------------------------------------------------------------------------------- /src/fingerprint.h: -------------------------------------------------------------------------------- 1 | #ifndef FINGERPRINT_H 2 | #define FINGERPRINT_H 3 | 4 | #include "signal_protocol_types.h" 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | /** 11 | * Construct a fingerprint generator for 60 digit numerics. 12 | * 13 | * @param generator set to a freshly allocated generator instance 14 | * @param iterations The number of internal iterations to perform in the process of 15 | * generating a fingerprint. This needs to be constant, and synchronized 16 | * across all clients. 17 | * 18 | * The higher the iteration count, the higher the security level: 19 | * - 1024 ~ 109.7 bits 20 | * - 1400 > 110 bits 21 | * - 5200 > 112 bits 22 | * @param scannable_version The format version for the scannable fingerprint (0 or 1) 23 | * @param global_context the global library context 24 | * @return 0 on success, or negative on failure 25 | */ 26 | int fingerprint_generator_create(fingerprint_generator **generator, 27 | int iterations, int scannable_version, 28 | signal_context *global_context); 29 | 30 | /** 31 | * Generate a scannable and displayble fingerprint. 32 | * 33 | * @param local_stable_identifier The client's "stable" identifier. 34 | * @param local_identity_key The client's identity key. 35 | * @param remote_stable_identifier The remote party's "stable" identifier. 36 | * @param remote_identity_key The remote party's identity key. 37 | * @param fingerprint_val Set to a freshly allocated unique fingerprint for this conversation 38 | * @return 0 on success, or negative on failure 39 | */ 40 | int fingerprint_generator_create_for(fingerprint_generator *generator, 41 | const char *local_stable_identifier, const ec_public_key *local_identity_key, 42 | const char *remote_stable_identifier, const ec_public_key *remote_identity_key, 43 | fingerprint **fingerprint_val); 44 | 45 | /** 46 | * Generate a scannable and displayble fingerprint for a list of keys 47 | * 48 | * @param local_stable_identifier The client's "stable" identifier. 49 | * @param local_identity_key_list The client's identity key list. 50 | * @param remote_stable_identifier The remote party's "stable" identifier. 51 | * @param remote_identity_key_list The remote party's identity key list. 52 | * @param fingerprint_val Set to a freshly allocated unique fingerprint for this conversation 53 | * @return 0 on success, or negative on failure 54 | */ 55 | int fingerprint_generator_create_for_list(fingerprint_generator *generator, 56 | const char *local_stable_identifier, const ec_public_key_list *local_identity_key_list, 57 | const char *remote_stable_identifier, const ec_public_key_list *remote_identity_key_list, 58 | fingerprint **fingerprint_val); 59 | 60 | void fingerprint_generator_free(fingerprint_generator *generator); 61 | 62 | int fingerprint_create(fingerprint **fingerprint_val, displayable_fingerprint *displayable, scannable_fingerprint *scannable); 63 | displayable_fingerprint *fingerprint_get_displayable(const fingerprint *fingerprint_val); 64 | scannable_fingerprint *fingerprint_get_scannable(const fingerprint *fingerprint_val); 65 | void fingerprint_destroy(signal_type_base *type); 66 | 67 | int displayable_fingerprint_create(displayable_fingerprint **displayable, const char *local_fingerprint, const char *remote_fingerprint); 68 | const char *displayable_fingerprint_local(const displayable_fingerprint *displayable); 69 | const char *displayable_fingerprint_remote(const displayable_fingerprint *displayable); 70 | const char *displayable_fingerprint_text(const displayable_fingerprint *displayable); 71 | void displayable_fingerprint_destroy(signal_type_base *type); 72 | 73 | int scannable_fingerprint_create(scannable_fingerprint **scannable, 74 | uint32_t version, 75 | const char *local_stable_identifier, const signal_buffer *local_fingerprint, 76 | const char *remote_stable_identifier, const signal_buffer *remote_fingerprint); 77 | 78 | int scannable_fingerprint_serialize(signal_buffer **buffer, const scannable_fingerprint *scannable); 79 | int scannable_fingerprint_deserialize(scannable_fingerprint **scannable, const uint8_t *data, size_t len, signal_context *global_context); 80 | uint32_t scannable_fingerprint_get_version(const scannable_fingerprint *scannable); 81 | const char *scannable_fingerprint_get_local_stable_identifier(const scannable_fingerprint *scannable); 82 | signal_buffer *scannable_fingerprint_get_local_fingerprint(const scannable_fingerprint *scannable); 83 | const char *scannable_fingerprint_get_remote_stable_identifier(const scannable_fingerprint *scannable); 84 | signal_buffer *scannable_fingerprint_get_remote_fingerprint(const scannable_fingerprint *scannable); 85 | 86 | /** 87 | * Compare a scanned QR code with what we expect. 88 | * @param scannable The local scannable data 89 | * @param other_scannable The data from the scanned code 90 | * @retval 1 if the scannable codes match 91 | * @retval 0 if the scannable codes do not match 92 | * @retval SG_ERR_FP_VERSION_MISMATCH if the scanned fingerprint is the wrong version 93 | * @retval SG_ERR_FP_IDENT_MISMATCH if the scanned fingerprint is for the wrong stable identifier 94 | */ 95 | int scannable_fingerprint_compare(const scannable_fingerprint *scannable, const scannable_fingerprint *other_scannable); 96 | 97 | void scannable_fingerprint_destroy(signal_type_base *type); 98 | 99 | #ifdef __cplusplus 100 | } 101 | #endif 102 | 103 | #endif /* FINGERPRINT_H */ 104 | -------------------------------------------------------------------------------- /src/group_cipher.h: -------------------------------------------------------------------------------- 1 | #ifndef GROUP_CIPHER_H 2 | #define GROUP_CIPHER_H 3 | 4 | #include 5 | #include 6 | #include "signal_protocol_types.h" 7 | 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | 12 | /* 13 | * The main entry point for Signal Protocol group encrypt/decrypt operations. 14 | * 15 | * Once a session has been established with group_session_builder and a 16 | * sender_key_distribution_message has been distributed to each member of 17 | * the group, this class can be used for all subsequent encrypt/decrypt 18 | * operations within that session (i.e. until group membership changes). 19 | */ 20 | 21 | /** 22 | * Construct a group cipher for encrypt/decrypt operations. 23 | * 24 | * The store and global contexts must remain valid for the lifetime of the 25 | * group cipher. 26 | * 27 | * When finished, free the returned instance by calling group_cipher_free(). 28 | * 29 | * @param cipher set to a freshly allocated group cipher instance 30 | * @param store the signal_protocol_store_context to store all state information in 31 | * @param sender_key_id the sender that messages will be encrypted to or decrypted from 32 | * @param global_context the global library context 33 | * @return 0 on success, or negative on failure 34 | */ 35 | int group_cipher_create(group_cipher **cipher, 36 | signal_protocol_store_context *store, const signal_protocol_sender_key_name *sender_key_id, 37 | signal_context *global_context); 38 | 39 | /** 40 | * Set the optional user data pointer for the group cipher. 41 | * 42 | * This is to give callback functions a way of accessing app specific 43 | * context information for this cipher. 44 | */ 45 | void group_cipher_set_user_data(group_cipher *cipher, void *user_data); 46 | 47 | /** 48 | * Get the optional user data pointer for the group cipher. 49 | * 50 | * This is to give callback functions a way of accessing app specific 51 | * context information for this cipher. 52 | */ 53 | void *group_cipher_get_user_data(group_cipher *cipher); 54 | 55 | /** 56 | * Set the callback function that is called during the decrypt process. 57 | * 58 | * The callback function is called from within group_cipher_decrypt() after 59 | * decryption is complete but before the updated session state has been 60 | * committed to the session store. If the callback function returns a 61 | * negative value, then the decrypt function will immediately fail with 62 | * an error. 63 | * 64 | * This a callback allows some implementations to store the committed plaintext 65 | * to their local message store first, in case they are concerned with a crash 66 | * or write error happening between the time the session state is updated but 67 | * before they're able to successfully store the plaintext to disk. 68 | * 69 | * @param callback the callback function to set 70 | */ 71 | void group_cipher_set_decryption_callback(group_cipher *cipher, 72 | int (*callback)(group_cipher *cipher, signal_buffer *plaintext, void *decrypt_context)); 73 | 74 | /** 75 | * Encrypt a message. 76 | * 77 | * @param padded_plaintext The plaintext message bytes, optionally padded to a constant multiple. 78 | * @param padded_plaintext_len The length of the data pointed to by padded_message 79 | * @param encrypted_message Set to a ciphertext message encrypted to the group+sender+device tuple. 80 | * 81 | * @retval SG_SUCCESS Success 82 | * @retval SG_ERR_NO_SESSION if there is no established session for this contact. 83 | * @retval SG_ERR_INVALID_KEY if there is no valid private key for this session. 84 | */ 85 | int group_cipher_encrypt(group_cipher *cipher, 86 | const uint8_t *padded_plaintext, size_t padded_plaintext_len, 87 | ciphertext_message **encrypted_message); 88 | 89 | /** 90 | * Decrypt a message. 91 | * 92 | * @param ciphertext The sender_key_message to decrypt. 93 | * @param decrypt_context Optional context pointer associated with the 94 | * ciphertext, which is passed to the decryption callback function 95 | * @param plaintext Set to a newly allocated buffer containing the plaintext. 96 | * 97 | * @retval SG_SUCCESS Success 98 | * @retval SG_ERR_INVALID_MESSAGE if the input is not valid ciphertext. 99 | * @retval SG_ERR_DUPLICATE_MESSAGE if the input is a message that has already been received. 100 | * @retval SG_ERR_LEGACY_MESSAGE if the input is a message formatted by a protocol version that 101 | * is no longer supported. 102 | * @retval SG_ERR_NO_SESSION if there is no established session for this contact. 103 | */ 104 | int group_cipher_decrypt(group_cipher *cipher, 105 | sender_key_message *ciphertext, void *decrypt_context, 106 | signal_buffer **plaintext); 107 | 108 | void group_cipher_free(group_cipher *cipher); 109 | 110 | #ifdef __cplusplus 111 | } 112 | #endif 113 | 114 | #endif /* GROUP_CIPHER_H */ 115 | -------------------------------------------------------------------------------- /src/group_session_builder.c: -------------------------------------------------------------------------------- 1 | #include "group_session_builder.h" 2 | 3 | #include 4 | #include 5 | #include "sender_key_record.h" 6 | #include "sender_key_state.h" 7 | #include "sender_key.h" 8 | #include "protocol.h" 9 | #include "key_helper.h" 10 | #include "signal_protocol_internal.h" 11 | 12 | struct group_session_builder 13 | { 14 | signal_protocol_store_context *store; 15 | signal_context *global_context; 16 | }; 17 | 18 | int group_session_builder_create(group_session_builder **builder, 19 | signal_protocol_store_context *store, signal_context *global_context) 20 | { 21 | group_session_builder *result = 0; 22 | 23 | assert(store); 24 | assert(global_context); 25 | 26 | result = malloc(sizeof(group_session_builder)); 27 | if(!result) { 28 | return SG_ERR_NOMEM; 29 | } 30 | memset(result, 0, sizeof(group_session_builder)); 31 | 32 | result->store = store; 33 | result->global_context = global_context; 34 | 35 | *builder = result; 36 | return 0; 37 | } 38 | 39 | int group_session_builder_process_session(group_session_builder *builder, 40 | const signal_protocol_sender_key_name *sender_key_name, 41 | sender_key_distribution_message *distribution_message) 42 | { 43 | int result = 0; 44 | sender_key_record *record = 0; 45 | 46 | assert(builder); 47 | assert(builder->store); 48 | signal_lock(builder->global_context); 49 | 50 | result = signal_protocol_sender_key_load_key(builder->store, &record, sender_key_name); 51 | if(result < 0) { 52 | goto complete; 53 | } 54 | 55 | result = sender_key_record_add_sender_key_state(record, 56 | sender_key_distribution_message_get_id(distribution_message), 57 | sender_key_distribution_message_get_iteration(distribution_message), 58 | sender_key_distribution_message_get_chain_key(distribution_message), 59 | sender_key_distribution_message_get_signature_key(distribution_message)); 60 | if(result < 0) { 61 | goto complete; 62 | } 63 | 64 | result = signal_protocol_sender_key_store_key(builder->store, sender_key_name, record); 65 | 66 | complete: 67 | SIGNAL_UNREF(record); 68 | signal_unlock(builder->global_context); 69 | return result; 70 | } 71 | 72 | int group_session_builder_create_session(group_session_builder *builder, 73 | sender_key_distribution_message **distribution_message, 74 | const signal_protocol_sender_key_name *sender_key_name) 75 | { 76 | int result = 0; 77 | sender_key_record *record = 0; 78 | sender_key_state *state = 0; 79 | uint32_t sender_key_id = 0; 80 | signal_buffer *sender_key = 0; 81 | ec_key_pair *sender_signing_key = 0; 82 | sender_chain_key *chain_key = 0; 83 | signal_buffer *seed = 0; 84 | 85 | assert(builder); 86 | assert(builder->store); 87 | signal_lock(builder->global_context); 88 | 89 | result = signal_protocol_sender_key_load_key(builder->store, &record, sender_key_name); 90 | if(result < 0) { 91 | goto complete; 92 | } 93 | 94 | if(sender_key_record_is_empty(record)) { 95 | result = signal_protocol_key_helper_generate_sender_key_id(&sender_key_id, builder->global_context); 96 | if(result < 0) { 97 | goto complete; 98 | } 99 | 100 | result = signal_protocol_key_helper_generate_sender_key(&sender_key, builder->global_context); 101 | if(result < 0) { 102 | goto complete; 103 | } 104 | 105 | result = signal_protocol_key_helper_generate_sender_signing_key(&sender_signing_key, builder->global_context); 106 | if(result < 0) { 107 | goto complete; 108 | } 109 | 110 | result = sender_key_record_set_sender_key_state(record, sender_key_id, 0, sender_key, sender_signing_key); 111 | if(result < 0) { 112 | goto complete; 113 | } 114 | 115 | result = signal_protocol_sender_key_store_key(builder->store, sender_key_name, record); 116 | if(result < 0) { 117 | goto complete; 118 | } 119 | } 120 | 121 | result = sender_key_record_get_sender_key_state(record, &state); 122 | if(result < 0) { 123 | goto complete; 124 | } 125 | 126 | chain_key = sender_key_state_get_chain_key(state); 127 | seed = sender_chain_key_get_seed(chain_key); 128 | 129 | result = sender_key_distribution_message_create(distribution_message, 130 | sender_key_state_get_key_id(state), 131 | sender_chain_key_get_iteration(chain_key), 132 | signal_buffer_data(seed), signal_buffer_len(seed), 133 | sender_key_state_get_signing_key_public(state), 134 | builder->global_context); 135 | 136 | complete: 137 | signal_buffer_free(sender_key); 138 | SIGNAL_UNREF(sender_signing_key); 139 | SIGNAL_UNREF(record); 140 | signal_unlock(builder->global_context); 141 | return result; 142 | } 143 | 144 | void group_session_builder_free(group_session_builder *builder) 145 | { 146 | if(builder) { 147 | free(builder); 148 | } 149 | } 150 | -------------------------------------------------------------------------------- /src/group_session_builder.h: -------------------------------------------------------------------------------- 1 | #ifndef GROUP_SESSION_BUILDER_H 2 | #define GROUP_SESSION_BUILDER_H 3 | 4 | #include "signal_protocol_types.h" 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | /* 11 | * Group session builder is responsible for setting up group sender key encrypted sessions. 12 | * 13 | * Once a session has been established, group_cipher can be used to 14 | * encrypt/decrypt messages in that session. 15 | *

16 | * The built sessions are unidirectional: they can be used either for sending 17 | * or for receiving, but not both. 18 | * 19 | * Sessions are constructed per (groupId + senderId + deviceId) tuple. Remote logical users 20 | * are identified by their senderId, and each logical recipientId can have multiple physical 21 | * devices. 22 | */ 23 | 24 | /** 25 | * Constructs a group session builder. 26 | * 27 | * The store and global contexts must remain valid for the lifetime of the 28 | * session builder. 29 | * 30 | * When finished, free the returned instance by calling group_session_builder_free(). 31 | * 32 | * @param builder set to a freshly allocated group session builder instance 33 | * @param store the signal_protocol_store_context to store all state information in 34 | * @param global_context the global library context 35 | * @return 0 on success, or negative on failure 36 | */ 37 | int group_session_builder_create(group_session_builder **builder, 38 | signal_protocol_store_context *store, signal_context *global_context); 39 | 40 | /** 41 | * Construct a group session for receiving messages from senderKeyName. 42 | * 43 | * @param sender_key_name the (groupId, senderId, deviceId) tuple associated 44 | * with the sender_key_distribution_message 45 | * @param distribution_message a received sender_key_distribution_message 46 | * @return 0 on success, or negative on failure 47 | */ 48 | int group_session_builder_process_session(group_session_builder *builder, 49 | const signal_protocol_sender_key_name *sender_key_name, 50 | sender_key_distribution_message *distribution_message); 51 | 52 | /** 53 | * Construct a group session for sending messages. 54 | * 55 | * @param distribution_message a distribution message to be allocated and populated 56 | * @param sender_key_name the (groupId, senderId, deviceId) tuple. In this 57 | * case, the sender should be the caller 58 | * @return 0 on success, or negative on failure 59 | */ 60 | int group_session_builder_create_session(group_session_builder *builder, 61 | sender_key_distribution_message **distribution_message, 62 | const signal_protocol_sender_key_name *sender_key_name); 63 | 64 | void group_session_builder_free(group_session_builder *builder); 65 | 66 | #ifdef __cplusplus 67 | } 68 | #endif 69 | 70 | #endif /* GROUP_SESSION_BUILDER_H */ 71 | -------------------------------------------------------------------------------- /src/hkdf.h: -------------------------------------------------------------------------------- 1 | #ifndef HKDF_H 2 | #define HKDF_H 3 | 4 | #include 5 | #include 6 | #include "signal_protocol_types.h" 7 | 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | 12 | int hkdf_create(hkdf_context **context, int message_version, signal_context *global_context); 13 | 14 | ssize_t hkdf_derive_secrets(hkdf_context *context, 15 | uint8_t **output, 16 | const uint8_t *input_key_material, size_t input_key_material_len, 17 | const uint8_t *salt, size_t salt_len, 18 | const uint8_t *info, size_t info_len, 19 | size_t output_len); 20 | 21 | int hkdf_compare(const hkdf_context *context1, const hkdf_context *context2); 22 | 23 | void hkdf_destroy(signal_type_base *type); 24 | 25 | #ifdef __cplusplus 26 | } 27 | #endif 28 | 29 | #endif /* HKDF_H */ 30 | -------------------------------------------------------------------------------- /src/key_helper.h: -------------------------------------------------------------------------------- 1 | #ifndef KEY_HELPER_H 2 | #define KEY_HELPER_H 3 | 4 | #include 5 | #include "signal_protocol_types.h" 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | /** 12 | * Generate an identity key pair. Clients should only do this once, 13 | * at install time. 14 | * 15 | * @param key_pair the generated identity key pair 16 | * @return 0 on success, or negative on failure 17 | */ 18 | int signal_protocol_key_helper_generate_identity_key_pair(ratchet_identity_key_pair **key_pair, signal_context *global_context); 19 | 20 | /** 21 | * Generate a registration ID. Clients should only do this once, 22 | * at install time. 23 | * 24 | * @param registration_id set to the generated registration ID 25 | * @param extended_range By default (0), the generated registration 26 | * ID is sized to require the minimal possible protobuf 27 | * encoding overhead. Specify true (1) if the caller needs 28 | * the full range of MAX_INT at the cost of slightly 29 | * higher encoding overhead. 30 | * @return 0 on success, or negative on failure 31 | */ 32 | int signal_protocol_key_helper_generate_registration_id(uint32_t *registration_id, int extended_range, signal_context *global_context); 33 | 34 | /** 35 | * Generate a random number between 0 (inclusive) and the provided maximum (exclusive). 36 | * 37 | * @param value set to the next random number 38 | * @param max the maximum bound on the value of the random number 39 | * @return 0 on success, or negative on failure 40 | */ 41 | int signal_protocol_key_helper_get_random_sequence(int *value, int max, signal_context *global_context); 42 | 43 | /** 44 | * Generate a list of PreKeys. Clients should do this at install time, and 45 | * subsequently any time the list of PreKeys stored on the server runs low. 46 | * 47 | * Pre key IDs are shorts, so they will eventually be repeated. Clients should 48 | * store pre keys in a circular buffer, so that they are repeated as infrequently 49 | * as possible. 50 | * 51 | * When finished with this list, the caller should free it by calling 52 | * signal_protocol_key_helper_key_list_free(). 53 | * 54 | * @param head pointer to the head of the key list 55 | * @param start the starting pre key ID, inclusive. 56 | * @param count the number of pre keys to generate. 57 | * @return 0 on success, or negative on failure 58 | */ 59 | int signal_protocol_key_helper_generate_pre_keys(signal_protocol_key_helper_pre_key_list_node **head, 60 | unsigned int start, unsigned int count, 61 | signal_context *global_context); 62 | 63 | /** 64 | * Get the pre key element for the current node in the key list. 65 | * 66 | * @param node current list node 67 | * @return pre key element 68 | */ 69 | session_pre_key *signal_protocol_key_helper_key_list_element(const signal_protocol_key_helper_pre_key_list_node *node); 70 | 71 | /** 72 | * Get the next element in the key list. 73 | * 74 | * @param node current list node 75 | * @return next list node, or 0 if at the end of the list 76 | */ 77 | signal_protocol_key_helper_pre_key_list_node *signal_protocol_key_helper_key_list_next(const signal_protocol_key_helper_pre_key_list_node *node); 78 | 79 | /** 80 | * Free the key list. 81 | * 82 | * @param head pointer to the head of the list to free 83 | */ 84 | void signal_protocol_key_helper_key_list_free(signal_protocol_key_helper_pre_key_list_node *head); 85 | 86 | /** 87 | * Generate a signed pre key 88 | * 89 | * @param signed_pre_key set to the generated pre key 90 | * @param identity_key_pair the local client's identity key pair. 91 | * @param signed_pre_key_id the pre key ID to assign the generated signed pre key 92 | * @param timestamp the current time in milliseconds since the UNIX epoch 93 | * 94 | * @return 0 on success, or negative on failure 95 | */ 96 | int signal_protocol_key_helper_generate_signed_pre_key(session_signed_pre_key **signed_pre_key, 97 | const ratchet_identity_key_pair *identity_key_pair, 98 | uint32_t signed_pre_key_id, 99 | uint64_t timestamp, 100 | signal_context *global_context); 101 | 102 | /* 103 | * Generate a sender signing key pair 104 | * 105 | * @param key_pair the generated key pair 106 | * @return 0 on success, or negative on failure 107 | */ 108 | int signal_protocol_key_helper_generate_sender_signing_key(ec_key_pair **key_pair, signal_context *global_context); 109 | 110 | /* 111 | * Generate a sender key 112 | * 113 | * @param key_buffer buffer to be allocated and populated with the result 114 | * @return 0 on success, or negative on failure 115 | */ 116 | int signal_protocol_key_helper_generate_sender_key(signal_buffer **key_buffer, signal_context *global_context); 117 | 118 | /* 119 | * Generate a sender key ID 120 | * 121 | * @param key_id assigned to the generated ID 122 | * @return 0 on success, or negative on failure 123 | */ 124 | int signal_protocol_key_helper_generate_sender_key_id(uint32_t *key_id, signal_context *global_context); 125 | 126 | #ifdef __cplusplus 127 | } 128 | #endif 129 | 130 | #endif /* KEY_HELPER_H */ 131 | -------------------------------------------------------------------------------- /src/libsignal-protocol-c.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@CMAKE_INSTALL_PREFIX@ 2 | exec_prefix=@CMAKE_INSTALL_PREFIX@ 3 | libdir=@LIB_INSTALL_DIR@ 4 | sharedlibdir=@LIB_INSTALL_DIR@ 5 | includedir=@INCLUDE_INSTALL_DIR@ 6 | 7 | Name: @PROJECT_NAME@ 8 | Description: Signal Protocol C Library 9 | Version: @SIGNAL_PROTOCOL_C_VERSION@ 10 | 11 | Requires: 12 | Libs: -L${libdir} -L${sharedlibdir} -l@PROJECT_NAME@ 13 | Cflags: -I${includedir}/signal -------------------------------------------------------------------------------- /src/protobuf-c/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | IF(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang") 2 | SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-shadow") 3 | ENDIF(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang") 4 | 5 | IF(CMAKE_COMPILER_IS_GNUCC) 6 | SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-sign-compare") 7 | IF(GCC_WARN_SIGN_CONVERSION) 8 | SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-sign-conversion") 9 | ENDIF(GCC_WARN_SIGN_CONVERSION) 10 | ENDIF(CMAKE_COMPILER_IS_GNUCC) 11 | 12 | IF(CMAKE_C_COMPILER_ID MATCHES "Clang") 13 | SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-shorten-64-to-32") 14 | ENDIF(CMAKE_C_COMPILER_ID MATCHES "Clang") 15 | 16 | set(protobuf_SRCS 17 | protobuf-c.c 18 | ) 19 | 20 | add_library(protobuf-c OBJECT ${protobuf_SRCS}) 21 | 22 | # Add -fPIC flag 23 | if(BUILD_SHARED_LIBS) 24 | set_property(TARGET protobuf-c PROPERTY POSITION_INDEPENDENT_CODE ON) 25 | endif() 26 | -------------------------------------------------------------------------------- /src/ratchet.h: -------------------------------------------------------------------------------- 1 | #ifndef RATCHET_H 2 | #define RATCHET_H 3 | 4 | #include 5 | #include 6 | #include "signal_protocol_types.h" 7 | 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | 12 | int ratchet_chain_key_create(ratchet_chain_key **chain_key, hkdf_context *kdf, 13 | const uint8_t *key, size_t key_len, uint32_t index, 14 | signal_context *global_context); 15 | int ratchet_chain_key_get_key(const ratchet_chain_key *chain_key, signal_buffer **buffer); 16 | uint32_t ratchet_chain_key_get_index(const ratchet_chain_key *chain_key); 17 | int ratchet_chain_key_get_message_keys(ratchet_chain_key *chain_key, ratchet_message_keys *message_keys); 18 | int ratchet_chain_key_create_next(const ratchet_chain_key *chain_key, ratchet_chain_key **next_chain_key); 19 | void ratchet_chain_key_destroy(signal_type_base *type); 20 | 21 | int ratchet_root_key_create(ratchet_root_key **root_key, hkdf_context *kdf, 22 | const uint8_t *key, size_t key_len, 23 | signal_context *global_context); 24 | int ratchet_root_key_create_chain(ratchet_root_key *root_key, 25 | ratchet_root_key **new_root_key, ratchet_chain_key **new_chain_key, 26 | ec_public_key *their_ratchet_key, 27 | ec_private_key *our_ratchet_key_private); 28 | int ratchet_root_key_get_key(ratchet_root_key *root_key, signal_buffer **buffer); 29 | int ratchet_root_key_compare(const ratchet_root_key *key1, const ratchet_root_key *key2); 30 | void ratchet_root_key_destroy(signal_type_base *type); 31 | 32 | int ratchet_identity_key_pair_create( 33 | ratchet_identity_key_pair **key_pair, 34 | ec_public_key *public_key, 35 | ec_private_key *private_key); 36 | int ratchet_identity_key_pair_serialize(signal_buffer **buffer, const ratchet_identity_key_pair *key_pair); 37 | int ratchet_identity_key_pair_deserialize(ratchet_identity_key_pair **key_pair, const uint8_t *data, size_t len, signal_context *global_context); 38 | ec_public_key *ratchet_identity_key_pair_get_public(const ratchet_identity_key_pair *key_pair); 39 | ec_private_key *ratchet_identity_key_pair_get_private(const ratchet_identity_key_pair *key_pair); 40 | void ratchet_identity_key_pair_destroy(signal_type_base *type); 41 | 42 | typedef struct symmetric_signal_protocol_parameters symmetric_signal_protocol_parameters; 43 | typedef struct alice_signal_protocol_parameters alice_signal_protocol_parameters; 44 | typedef struct bob_signal_protocol_parameters bob_signal_protocol_parameters; 45 | 46 | int symmetric_signal_protocol_parameters_create( 47 | symmetric_signal_protocol_parameters **parameters, 48 | ratchet_identity_key_pair *our_identity_key, 49 | ec_key_pair *our_base_key, 50 | ec_key_pair *our_ratchet_key, 51 | ec_public_key *their_base_key, 52 | ec_public_key *their_ratchet_key, 53 | ec_public_key *their_identity_key); 54 | ratchet_identity_key_pair *symmetric_signal_protocol_parameters_get_our_identity_key(const symmetric_signal_protocol_parameters *parameters); 55 | ec_key_pair *symmetric_signal_protocol_parameters_get_our_base_key(const symmetric_signal_protocol_parameters *parameters); 56 | ec_key_pair *symmetric_signal_protocol_parameters_get_our_ratchet_key(const symmetric_signal_protocol_parameters *parameters); 57 | ec_public_key *symmetric_signal_protocol_parameters_get_their_base_key(const symmetric_signal_protocol_parameters *parameters); 58 | ec_public_key *symmetric_signal_protocol_parameters_get_their_ratchet_key(const symmetric_signal_protocol_parameters *parameters); 59 | ec_public_key *symmetric_signal_protocol_parameters_get_their_identity_key(const symmetric_signal_protocol_parameters *parameters); 60 | void symmetric_signal_protocol_parameters_destroy(signal_type_base *type); 61 | 62 | int alice_signal_protocol_parameters_create( 63 | alice_signal_protocol_parameters **parameters, 64 | ratchet_identity_key_pair *our_identity_key, 65 | ec_key_pair *our_base_key, 66 | ec_public_key *their_identity_key, 67 | ec_public_key *their_signed_pre_key, 68 | ec_public_key *their_one_time_pre_key, 69 | ec_public_key *their_ratchet_key); 70 | void alice_signal_protocol_parameters_destroy(signal_type_base *type); 71 | 72 | int bob_signal_protocol_parameters_create( 73 | bob_signal_protocol_parameters **parameters, 74 | ratchet_identity_key_pair *our_identity_key, 75 | ec_key_pair *our_signed_pre_key, 76 | ec_key_pair *our_one_time_pre_key, 77 | ec_key_pair *our_ratchet_key, 78 | ec_public_key *their_identity_key, 79 | ec_public_key *their_base_key); 80 | void bob_signal_protocol_parameters_destroy(signal_type_base *type); 81 | 82 | int ratcheting_session_symmetric_initialize(session_state *state, symmetric_signal_protocol_parameters *parameters, signal_context *global_context); 83 | int ratcheting_session_alice_initialize(session_state *state, alice_signal_protocol_parameters *parameters, signal_context *global_context); 84 | int ratcheting_session_bob_initialize(session_state *state, bob_signal_protocol_parameters *parameters, signal_context *global_context); 85 | 86 | #ifdef __cplusplus 87 | } 88 | #endif 89 | 90 | #endif /* RATCHET_H */ 91 | -------------------------------------------------------------------------------- /src/sender_key.h: -------------------------------------------------------------------------------- 1 | #ifndef SENDER_KEY 2 | #define SENDER_KEY 3 | 4 | #include 5 | #include 6 | #include "signal_protocol_types.h" 7 | 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | 12 | int sender_message_key_create(sender_message_key **key, 13 | uint32_t iteration, signal_buffer *seed, 14 | signal_context *global_context); 15 | uint32_t sender_message_key_get_iteration(sender_message_key *key); 16 | signal_buffer *sender_message_key_get_iv(sender_message_key *key); 17 | signal_buffer *sender_message_key_get_cipher_key(sender_message_key *key); 18 | signal_buffer *sender_message_key_get_seed(sender_message_key *key); 19 | void sender_message_key_destroy(signal_type_base *type); 20 | 21 | int sender_chain_key_create(sender_chain_key **key, 22 | uint32_t iteration, signal_buffer *chain_key, 23 | signal_context *global_context); 24 | uint32_t sender_chain_key_get_iteration(sender_chain_key *key); 25 | int sender_chain_key_create_message_key(sender_chain_key *key, sender_message_key **message_key); 26 | int sender_chain_key_create_next(sender_chain_key *key, sender_chain_key **next_key); 27 | signal_buffer *sender_chain_key_get_seed(sender_chain_key *key); 28 | void sender_chain_key_destroy(signal_type_base *type); 29 | 30 | #ifdef __cplusplus 31 | } 32 | #endif 33 | 34 | #endif /* SENDER_KEY */ 35 | -------------------------------------------------------------------------------- /src/sender_key_record.h: -------------------------------------------------------------------------------- 1 | #ifndef SENDER_KEY_RECORD_H 2 | #define SENDER_KEY_RECORD_H 3 | 4 | #include "signal_protocol_types.h" 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | int sender_key_record_create(sender_key_record **record, 11 | signal_context *global_context); 12 | int sender_key_record_serialize(signal_buffer **buffer, sender_key_record *record); 13 | int sender_key_record_deserialize(sender_key_record **record, const uint8_t *data, size_t len, signal_context *global_context); 14 | int sender_key_record_copy(sender_key_record **record, sender_key_record *other_state, signal_context *global_context); 15 | 16 | int sender_key_record_is_empty(sender_key_record *record); 17 | int sender_key_record_get_sender_key_state(sender_key_record *record, sender_key_state **state); 18 | int sender_key_record_get_sender_key_state_by_id(sender_key_record *record, sender_key_state **state, uint32_t key_id); 19 | int sender_key_record_add_sender_key_state(sender_key_record *record, 20 | uint32_t id, uint32_t iteration, signal_buffer *chain_key, ec_public_key *signature_key); 21 | int sender_key_record_set_sender_key_state(sender_key_record *record, 22 | uint32_t id, uint32_t iteration, signal_buffer *chain_key, ec_key_pair *signature_key_pair); 23 | 24 | signal_buffer *sender_key_record_get_user_record(const sender_key_record *record); 25 | void sender_key_record_set_user_record(sender_key_record *record, signal_buffer *user_record); 26 | 27 | void sender_key_record_destroy(signal_type_base *type); 28 | 29 | #ifdef __cplusplus 30 | } 31 | #endif 32 | 33 | #endif /* SENDER_KEY_RECORD_H */ 34 | -------------------------------------------------------------------------------- /src/sender_key_state.h: -------------------------------------------------------------------------------- 1 | #ifndef SENDER_KEY_STATE_H 2 | #define SENDER_KEY_STATE_H 3 | 4 | #include 5 | #include "signal_protocol_types.h" 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | int sender_key_state_create(sender_key_state **state, 12 | uint32_t id, sender_chain_key *chain_key, 13 | ec_public_key *signature_public_key, ec_private_key *signature_private_key, 14 | signal_context *global_context); 15 | int sender_key_state_serialize(signal_buffer **buffer, sender_key_state *state); 16 | int sender_key_state_deserialize(sender_key_state **state, const uint8_t *data, size_t len, signal_context *global_context); 17 | int sender_key_state_copy(sender_key_state **state, sender_key_state *other_state, signal_context *global_context); 18 | 19 | uint32_t sender_key_state_get_key_id(sender_key_state *state); 20 | sender_chain_key *sender_key_state_get_chain_key(sender_key_state *state); 21 | void sender_key_state_set_chain_key(sender_key_state *state, sender_chain_key *chain_key); 22 | ec_public_key *sender_key_state_get_signing_key_public(sender_key_state *state); 23 | ec_private_key *sender_key_state_get_signing_key_private(sender_key_state *state); 24 | int sender_key_state_has_sender_message_key(sender_key_state *state, uint32_t iteration); 25 | int sender_key_state_add_sender_message_key(sender_key_state *state, sender_message_key *message_key); 26 | sender_message_key *sender_key_state_remove_sender_message_key(sender_key_state *state, uint32_t iteration); 27 | 28 | void sender_key_state_destroy(signal_type_base *type); 29 | 30 | #ifdef __cplusplus 31 | } 32 | #endif 33 | 34 | #endif /* SENDER_KEY_STATE_H */ 35 | -------------------------------------------------------------------------------- /src/session_builder.h: -------------------------------------------------------------------------------- 1 | #ifndef SESSION_BUILDER_H 2 | #define SESSION_BUILDER_H 3 | 4 | #include 5 | #include "signal_protocol_types.h" 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | /* 12 | * Session builder is responsible for setting up encrypted sessions. 13 | * Once a session has been established, session_cipher 14 | * can be used to encrypt/decrypt messages in that session. 15 | * 16 | * Sessions are built from one these different possible vectors: 17 | * - A session_pre_key_bundle retrieved from a server 18 | * - A pre_key_signal_message received from a client 19 | * 20 | * Sessions are constructed per Signal Protocol address 21 | * (recipient name + device ID tuple). Remote logical users are identified by 22 | * their recipient name, and each logical recipient can have multiple 23 | * physical devices. 24 | */ 25 | 26 | /** 27 | * Constructs a session builder. 28 | * 29 | * The store and global contexts must remain valid for the lifetime of the 30 | * session builder. 31 | * 32 | * When finished, free the returned instance by calling session_builder_free(). 33 | * 34 | * @param builder set to a freshly allocated session builder instance 35 | * @param store the signal_protocol_store_context to store all state information in 36 | * @param remote_address the address of the remote user to build a session with 37 | * @param global_context the global library context 38 | * @return 0 on success, or negative on failure 39 | */ 40 | int session_builder_create(session_builder **builder, 41 | signal_protocol_store_context *store, const signal_protocol_address *remote_address, 42 | signal_context *global_context); 43 | 44 | /** 45 | * Build a new session from a session_pre_key_bundle retrieved from a server. 46 | * 47 | * @param bundle A pre key bundle for the destination recipient, retrieved from a server. 48 | * @retval SG_SUCCESS Success 49 | * @retval SG_ERR_INVALID_KEY when the session_pre_key_bundle is badly formatted. 50 | * @retval SG_ERR_UNTRUSTED_IDENTITY when the sender's identity key is not trusted. 51 | */ 52 | int session_builder_process_pre_key_bundle(session_builder *builder, session_pre_key_bundle *bundle); 53 | 54 | void session_builder_free(session_builder *builder); 55 | 56 | #ifdef __cplusplus 57 | } 58 | #endif 59 | 60 | #endif /* SESSION_BUILDER_H */ 61 | -------------------------------------------------------------------------------- /src/session_builder_internal.h: -------------------------------------------------------------------------------- 1 | #ifndef SESSION_BUILDER_INTERNAL_H 2 | #define SESSION_BUILDER_INTERNAL_H 3 | 4 | #include 5 | #include "signal_protocol_types.h" 6 | 7 | /** 8 | * Build a new session from a received pre_key_signal_message. 9 | * 10 | * After a session is constructed in this way, the embedded signal_message 11 | * can be decrypted. 12 | * 13 | * @param message The received pre_key_signal_message. 14 | * @param unsigned_pre_key_id set to the unsigned pre key ID, if available. 15 | * Return value indicates whether or not this value is available. 16 | * @retval 0 Success, no unsigned pre key value available 17 | * @retval 1 Success, an unsigned pre key is available 18 | * @retval SG_ERR_INVALID_KEY_ID when there is no local pre_key_record that 19 | * corresponds to the PreKey ID in the message. 20 | * @retval SG_ERR_INVALID_KEY when the message is formatted incorrectly. 21 | * @retval SG_ERR_UNTRUSTED_IDENTITY when the identity key of the sender is untrusted. 22 | */ 23 | int session_builder_process_pre_key_signal_message(session_builder *builder, 24 | session_record *record, pre_key_signal_message *message, uint32_t *unsigned_pre_key_id); 25 | 26 | #endif /* SESSION_BUILDER_INTERNAL_H */ 27 | -------------------------------------------------------------------------------- /src/session_pre_key.h: -------------------------------------------------------------------------------- 1 | #ifndef SESSION_PRE_KEY_H 2 | #define SESSION_PRE_KEY_H 3 | 4 | #include 5 | #include 6 | #include "signal_protocol_types.h" 7 | 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | 12 | #define PRE_KEY_MEDIUM_MAX_VALUE 0xFFFFFF 13 | 14 | /*------------------------------------------------------------------------*/ 15 | 16 | int session_pre_key_create(session_pre_key **pre_key, uint32_t id, ec_key_pair *key_pair); 17 | int session_pre_key_serialize(signal_buffer **buffer, const session_pre_key *pre_key); 18 | int session_pre_key_deserialize(session_pre_key **pre_key, const uint8_t *data, size_t len, signal_context *global_context); 19 | 20 | uint32_t session_pre_key_get_id(const session_pre_key *pre_key); 21 | ec_key_pair *session_pre_key_get_key_pair(const session_pre_key *pre_key); 22 | 23 | void session_pre_key_destroy(signal_type_base *type); 24 | 25 | /*------------------------------------------------------------------------*/ 26 | 27 | int session_signed_pre_key_create(session_signed_pre_key **pre_key, 28 | uint32_t id, uint64_t timestamp, ec_key_pair *key_pair, 29 | const uint8_t *signature, size_t signature_len); 30 | int session_signed_pre_key_serialize(signal_buffer **buffer, const session_signed_pre_key *pre_key); 31 | int session_signed_pre_key_deserialize(session_signed_pre_key **pre_key, const uint8_t *data, size_t len, signal_context *global_context); 32 | 33 | uint32_t session_signed_pre_key_get_id(const session_signed_pre_key *pre_key); 34 | uint64_t session_signed_pre_key_get_timestamp(const session_signed_pre_key *pre_key); 35 | ec_key_pair *session_signed_pre_key_get_key_pair(const session_signed_pre_key *pre_key); 36 | const uint8_t *session_signed_pre_key_get_signature(const session_signed_pre_key *pre_key); 37 | size_t session_signed_pre_key_get_signature_len(const session_signed_pre_key *pre_key); 38 | 39 | void session_signed_pre_key_destroy(signal_type_base *type); 40 | 41 | /*------------------------------------------------------------------------*/ 42 | 43 | int session_pre_key_bundle_create(session_pre_key_bundle **bundle, 44 | uint32_t registration_id, int device_id, uint32_t pre_key_id, 45 | ec_public_key *pre_key_public, 46 | uint32_t signed_pre_key_id, ec_public_key *signed_pre_key_public, 47 | const uint8_t *signed_pre_key_signature_data, size_t signed_pre_key_signature_len, 48 | ec_public_key *identity_key); 49 | 50 | uint32_t session_pre_key_bundle_get_registration_id(const session_pre_key_bundle *bundle); 51 | int session_pre_key_bundle_get_device_id(const session_pre_key_bundle *bundle); 52 | uint32_t session_pre_key_bundle_get_pre_key_id(const session_pre_key_bundle *bundle); 53 | ec_public_key *session_pre_key_bundle_get_pre_key(const session_pre_key_bundle *bundle); 54 | uint32_t session_pre_key_bundle_get_signed_pre_key_id(const session_pre_key_bundle *bundle); 55 | ec_public_key *session_pre_key_bundle_get_signed_pre_key(const session_pre_key_bundle *bundle); 56 | signal_buffer *session_pre_key_bundle_get_signed_pre_key_signature(const session_pre_key_bundle *bundle); 57 | ec_public_key *session_pre_key_bundle_get_identity_key(const session_pre_key_bundle *bundle); 58 | 59 | void session_pre_key_bundle_destroy(signal_type_base *type); 60 | 61 | #ifdef __cplusplus 62 | } 63 | #endif 64 | 65 | #endif /* SESSION_PRE_KEY_H */ 66 | -------------------------------------------------------------------------------- /src/session_record.h: -------------------------------------------------------------------------------- 1 | #ifndef SESSION_RECORD_H 2 | #define SESSION_RECORD_H 3 | 4 | #include 5 | #include 6 | #include "signal_protocol_types.h" 7 | 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | 12 | int session_record_create(session_record **record, session_state *state, signal_context *global_context); 13 | int session_record_serialize(signal_buffer **buffer, const session_record *record); 14 | int session_record_deserialize(session_record **record, const uint8_t *data, size_t len, signal_context *global_context); 15 | int session_record_copy(session_record **record, session_record *other_record, signal_context *global_context); 16 | 17 | int session_record_has_session_state(session_record *record, uint32_t version, const ec_public_key *alice_base_key); 18 | session_state *session_record_get_state(session_record *record); 19 | void session_record_set_state(session_record *record, session_state *state); 20 | 21 | session_record_state_node *session_record_get_previous_states_head(const session_record *record); 22 | session_state *session_record_get_previous_states_element(const session_record_state_node *node); 23 | session_record_state_node *session_record_get_previous_states_next(const session_record_state_node *node); 24 | 25 | /** 26 | * Removes the specified node in the previous states list. 27 | * @param node the node to remove 28 | * @return the node immediately following the removed node, or null if at the end of the list 29 | */ 30 | session_record_state_node *session_record_get_previous_states_remove(session_record *record, session_record_state_node *node); 31 | 32 | int session_record_is_fresh(session_record *record); 33 | 34 | /** 35 | * Move the current session_state into the list of "previous" session states, 36 | * and replace the current session_state with a fresh reset instance. 37 | * 38 | * @return 0 on success, negative on failure 39 | */ 40 | int session_record_archive_current_state(session_record *record); 41 | 42 | int session_record_promote_state(session_record *record, session_state *promoted_state); 43 | 44 | signal_buffer *session_record_get_user_record(const session_record *record); 45 | void session_record_set_user_record(session_record *record, signal_buffer *user_record); 46 | 47 | void session_record_destroy(signal_type_base *type); 48 | 49 | #ifdef __cplusplus 50 | } 51 | #endif 52 | 53 | #endif /* SESSION_RECORD_H */ 54 | -------------------------------------------------------------------------------- /src/session_state.h: -------------------------------------------------------------------------------- 1 | #ifndef SESSION_STATE_H 2 | #define SESSION_STATE_H 3 | 4 | #include 5 | #include 6 | #include "signal_protocol_types.h" 7 | 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | 12 | /*------------------------------------------------------------------------*/ 13 | 14 | int session_state_create(session_state **state, signal_context *global_context); 15 | int session_state_serialize(signal_buffer **buffer, session_state *state); 16 | int session_state_deserialize(session_state **state, const uint8_t *data, size_t len, signal_context *global_context); 17 | int session_state_copy(session_state **state, session_state *other_state, signal_context *global_context); 18 | 19 | void session_state_set_session_version(session_state *state, uint32_t version); 20 | uint32_t session_state_get_session_version(const session_state *state); 21 | 22 | void session_state_set_local_identity_key(session_state *state, ec_public_key *identity_key); 23 | ec_public_key *session_state_get_local_identity_key(const session_state *state); 24 | 25 | void session_state_set_remote_identity_key(session_state *state, ec_public_key *identity_key); 26 | ec_public_key *session_state_get_remote_identity_key(const session_state *state); 27 | 28 | void session_state_set_root_key(session_state *state, ratchet_root_key *root_key); 29 | ratchet_root_key *session_state_get_root_key(const session_state *state); 30 | 31 | void session_state_set_previous_counter(session_state *state, uint32_t counter); 32 | uint32_t session_state_get_previous_counter(const session_state *state); 33 | 34 | void session_state_set_sender_chain(session_state *state, ec_key_pair *sender_ratchet_key_pair, ratchet_chain_key *chain_key); 35 | ec_public_key *session_state_get_sender_ratchet_key(const session_state *state); 36 | ec_key_pair *session_state_get_sender_ratchet_key_pair(const session_state *state); 37 | ratchet_chain_key *session_state_get_sender_chain_key(const session_state *state); 38 | int session_state_set_sender_chain_key(session_state *state, ratchet_chain_key *chain_key); 39 | int session_state_has_sender_chain(const session_state *state); 40 | 41 | int session_state_has_message_keys(session_state *state, ec_public_key *sender_ephemeral, uint32_t counter); 42 | int session_state_remove_message_keys(session_state *state, 43 | ratchet_message_keys *message_keys_result, 44 | ec_public_key *sender_ephemeral, uint32_t counter); 45 | int session_state_set_message_keys(session_state *state, 46 | ec_public_key *sender_ephemeral, ratchet_message_keys *message_keys); 47 | 48 | int session_state_add_receiver_chain(session_state *state, ec_public_key *sender_ratchet_key, ratchet_chain_key *chain_key); 49 | int session_state_set_receiver_chain_key(session_state *state, ec_public_key *sender_ephemeral, ratchet_chain_key *chain_key); 50 | ratchet_chain_key *session_state_get_receiver_chain_key(session_state *state, ec_public_key *sender_ephemeral); 51 | 52 | void session_state_set_pending_key_exchange(session_state *state, 53 | uint32_t sequence, 54 | ec_key_pair *our_base_key, ec_key_pair *our_ratchet_key, 55 | ratchet_identity_key_pair *our_identity_key); 56 | uint32_t session_state_get_pending_key_exchange_sequence(session_state *state); 57 | ec_key_pair *session_state_get_pending_key_exchange_base_key(const session_state *state); 58 | ec_key_pair *session_state_get_pending_key_exchange_ratchet_key(const session_state *state); 59 | ratchet_identity_key_pair *session_state_get_pending_key_exchange_identity_key(const session_state *state); 60 | int session_state_has_pending_key_exchange(const session_state *state); 61 | 62 | void session_state_set_unacknowledged_pre_key_message(session_state *state, 63 | const uint32_t *pre_key_id, uint32_t signed_pre_key_id, ec_public_key *base_key); 64 | int session_state_unacknowledged_pre_key_message_has_pre_key_id(const session_state *state); 65 | uint32_t session_state_unacknowledged_pre_key_message_get_pre_key_id(const session_state *state); 66 | uint32_t session_state_unacknowledged_pre_key_message_get_signed_pre_key_id(const session_state *state); 67 | ec_public_key *session_state_unacknowledged_pre_key_message_get_base_key(const session_state *state); 68 | int session_state_has_unacknowledged_pre_key_message(const session_state *state); 69 | void session_state_clear_unacknowledged_pre_key_message(session_state *state); 70 | 71 | void session_state_set_remote_registration_id(session_state *state, uint32_t id); 72 | uint32_t session_state_get_remote_registration_id(const session_state *state); 73 | 74 | void session_state_set_local_registration_id(session_state *state, uint32_t id); 75 | uint32_t session_state_get_local_registration_id(const session_state *state); 76 | 77 | void session_state_set_needs_refresh(session_state *state, int value); 78 | int session_state_get_needs_refresh(const session_state *state); 79 | 80 | void session_state_set_alice_base_key(session_state *state, ec_public_key *key); 81 | ec_public_key *session_state_get_alice_base_key(const session_state *state); 82 | 83 | void session_state_destroy(signal_type_base *type); 84 | 85 | #ifdef __cplusplus 86 | } 87 | #endif 88 | 89 | #endif /* SESSION_STATE_H */ 90 | -------------------------------------------------------------------------------- /src/signal_protocol_internal.h: -------------------------------------------------------------------------------- 1 | #ifndef SIGNAL_PROTOCOL_INTERNAL_H 2 | #define SIGNAL_PROTOCOL_INTERNAL_H 3 | 4 | #include 5 | #include "LocalStorageProtocol.pb-c.h" 6 | #include "signal_protocol.h" 7 | 8 | struct signal_type_base { 9 | unsigned int ref_count; 10 | void (*destroy)(signal_type_base *instance); 11 | }; 12 | 13 | void signal_type_init(signal_type_base *instance, 14 | void (*destroy_func)(signal_type_base *instance)); 15 | 16 | #define SIGNAL_INIT(instance, destroy_func) signal_type_init((signal_type_base *)instance, destroy_func) 17 | 18 | struct signal_buffer { 19 | size_t len; 20 | uint8_t data[]; 21 | }; 22 | 23 | struct signal_context { 24 | signal_crypto_provider crypto_provider; 25 | void (*lock)(void *user_data); 26 | void (*unlock)(void *user_data); 27 | void (*log)(int level, const char *message, size_t len, void *user_data); 28 | void *user_data; 29 | }; 30 | 31 | int signal_crypto_random(signal_context *context, uint8_t *data, size_t len); 32 | 33 | int signal_hmac_sha256_init(signal_context *context, void **hmac_context, const uint8_t *key, size_t key_len); 34 | int signal_hmac_sha256_update(signal_context *context, void *hmac_context, const uint8_t *data, size_t data_len); 35 | int signal_hmac_sha256_final(signal_context *context, void *hmac_context, signal_buffer **output); 36 | void signal_hmac_sha256_cleanup(signal_context *context, void *hmac_context); 37 | 38 | int signal_sha512_digest_init(signal_context *context, void **digest_context); 39 | int signal_sha512_digest_update(signal_context *context, void *digest_context, const uint8_t *data, size_t data_len); 40 | int signal_sha512_digest_final(signal_context *context, void *digest_context, signal_buffer **output); 41 | void signal_sha512_digest_cleanup(signal_context *context, void *digest_context); 42 | 43 | 44 | int signal_encrypt(signal_context *context, 45 | signal_buffer **output, 46 | int cipher, 47 | const uint8_t *key, size_t key_len, 48 | const uint8_t *iv, size_t iv_len, 49 | const uint8_t *plaintext, size_t plaintext_len); 50 | 51 | int signal_decrypt(signal_context *context, 52 | signal_buffer **output, 53 | int cipher, 54 | const uint8_t *key, size_t key_len, 55 | const uint8_t *iv, size_t iv_len, 56 | const uint8_t *ciphertext, size_t ciphertext_len); 57 | 58 | void signal_lock(signal_context *context); 59 | void signal_unlock(signal_context *context); 60 | void signal_log(signal_context *context, int level, const char *format, ...); 61 | void signal_explicit_bzero(void *v, size_t n); 62 | int signal_constant_memcmp(const void *s1, const void *s2, size_t n); 63 | 64 | /*------------------------------------------------------------------------*/ 65 | 66 | /* 67 | * Functions used for internal protocol buffers serialization support. 68 | */ 69 | 70 | int ec_public_key_serialize_protobuf(ProtobufCBinaryData *buffer, const ec_public_key *key); 71 | int ec_private_key_serialize_protobuf(ProtobufCBinaryData *buffer, const ec_private_key *key); 72 | 73 | int ratchet_chain_key_get_key_protobuf(const ratchet_chain_key *chain_key, ProtobufCBinaryData *buffer); 74 | int ratchet_root_key_get_key_protobuf(const ratchet_root_key *root_key, ProtobufCBinaryData *buffer); 75 | 76 | int session_state_serialize_prepare(session_state *state, Textsecure__SessionStructure *session_structure); 77 | void session_state_serialize_prepare_free(Textsecure__SessionStructure *session_structure); 78 | int session_state_deserialize_protobuf(session_state **state, Textsecure__SessionStructure *session_structure, signal_context *global_context); 79 | 80 | int sender_key_state_serialize_prepare(sender_key_state *state, Textsecure__SenderKeyStateStructure *state_structure); 81 | void sender_key_state_serialize_prepare_free(Textsecure__SenderKeyStateStructure *state_structure); 82 | int sender_key_state_deserialize_protobuf(sender_key_state **state, Textsecure__SenderKeyStateStructure *state_structure, signal_context *global_context); 83 | 84 | void signal_protocol_str_serialize_protobuf(ProtobufCBinaryData *buffer, const char *str); 85 | char *signal_protocol_str_deserialize_protobuf(ProtobufCBinaryData *buffer); 86 | 87 | #endif /* SIGNAL_PROTOCOL_INTERNAL_H */ 88 | -------------------------------------------------------------------------------- /src/signal_protocol_types.h: -------------------------------------------------------------------------------- 1 | #ifndef SIGNAL_PROTOCOL_TYPES_H 2 | #define SIGNAL_PROTOCOL_TYPES_H 3 | 4 | #include 5 | #include 6 | 7 | #ifndef _WINDOWS 8 | #include 9 | #else 10 | #include 11 | typedef SSIZE_T ssize_t; 12 | #endif 13 | 14 | #ifdef __cplusplus 15 | extern "C" { 16 | #endif 17 | 18 | /* 19 | * Base library types 20 | */ 21 | typedef struct signal_type_base signal_type_base; 22 | typedef struct signal_buffer signal_buffer; 23 | typedef struct signal_buffer_list signal_buffer_list; 24 | typedef struct signal_int_list signal_int_list; 25 | 26 | /* 27 | * Global context for the Signal Protocol library 28 | */ 29 | typedef struct signal_context signal_context; 30 | 31 | /* 32 | * Context for the Signal Protocol data store implementation 33 | */ 34 | typedef struct signal_protocol_store_context signal_protocol_store_context; 35 | 36 | /* 37 | * Address of an Signal Protocol message recipient 38 | */ 39 | typedef struct signal_protocol_address { 40 | const char *name; 41 | size_t name_len; 42 | int32_t device_id; 43 | } signal_protocol_address; 44 | 45 | /* 46 | * A representation of a (group + sender + device) tuple 47 | */ 48 | typedef struct signal_protocol_sender_key_name { 49 | const char *group_id; 50 | size_t group_id_len; 51 | signal_protocol_address sender; 52 | } signal_protocol_sender_key_name; 53 | 54 | /* 55 | * Curve key types 56 | */ 57 | typedef struct ec_public_key ec_public_key; 58 | typedef struct ec_private_key ec_private_key; 59 | typedef struct ec_key_pair ec_key_pair; 60 | typedef struct ec_public_key_list ec_public_key_list; 61 | 62 | /* 63 | * HKDF types 64 | */ 65 | typedef struct hkdf_context hkdf_context; 66 | 67 | /* 68 | * Key helper types 69 | */ 70 | typedef struct signal_protocol_key_helper_pre_key_list_node signal_protocol_key_helper_pre_key_list_node; 71 | 72 | /* 73 | * Protocol types 74 | */ 75 | typedef struct ciphertext_message ciphertext_message; 76 | typedef struct signal_message signal_message; 77 | typedef struct pre_key_signal_message pre_key_signal_message; 78 | typedef struct sender_key_message sender_key_message; 79 | typedef struct sender_key_distribution_message sender_key_distribution_message; 80 | 81 | /* 82 | * Ratchet types 83 | */ 84 | #define RATCHET_CIPHER_KEY_LENGTH 32 85 | #define RATCHET_MAC_KEY_LENGTH 32 86 | #define RATCHET_IV_LENGTH 16 87 | 88 | typedef struct ratchet_chain_key ratchet_chain_key; 89 | typedef struct ratchet_root_key ratchet_root_key; 90 | typedef struct ratchet_identity_key_pair ratchet_identity_key_pair; 91 | 92 | typedef struct ratchet_message_keys { 93 | uint8_t cipher_key[RATCHET_CIPHER_KEY_LENGTH]; 94 | uint8_t mac_key[RATCHET_MAC_KEY_LENGTH]; 95 | uint8_t iv[RATCHET_IV_LENGTH]; 96 | uint32_t counter; 97 | } ratchet_message_keys; 98 | 99 | /* 100 | * Session types 101 | */ 102 | typedef struct session_pre_key session_pre_key; 103 | typedef struct session_signed_pre_key session_signed_pre_key; 104 | typedef struct session_pre_key_bundle session_pre_key_bundle; 105 | typedef struct session_builder session_builder; 106 | typedef struct session_record session_record; 107 | typedef struct session_record_state_node session_record_state_node; 108 | typedef struct session_state session_state; 109 | typedef struct session_cipher session_cipher; 110 | 111 | /* 112 | * Group types 113 | */ 114 | typedef struct sender_message_key sender_message_key; 115 | typedef struct sender_chain_key sender_chain_key; 116 | typedef struct sender_key_state sender_key_state; 117 | typedef struct sender_key_record sender_key_record; 118 | typedef struct group_session_builder group_session_builder; 119 | typedef struct group_cipher group_cipher; 120 | 121 | /* 122 | * Fingerprint types 123 | */ 124 | typedef struct fingerprint fingerprint; 125 | typedef struct displayable_fingerprint displayable_fingerprint; 126 | typedef struct scannable_fingerprint scannable_fingerprint; 127 | typedef struct fingerprint_generator fingerprint_generator; 128 | 129 | /* 130 | * Device consistency types 131 | */ 132 | typedef struct device_consistency_signature device_consistency_signature; 133 | typedef struct device_consistency_commitment device_consistency_commitment; 134 | typedef struct device_consistency_message device_consistency_message; 135 | typedef struct device_consistency_signature_list device_consistency_signature_list; 136 | 137 | #ifdef __cplusplus 138 | } 139 | #endif 140 | 141 | #endif /* SIGNAL_PROTOCOL_TYPES_H */ 142 | -------------------------------------------------------------------------------- /src/signal_utarray.h: -------------------------------------------------------------------------------- 1 | #ifndef SIGNAL_UTARRAY_H 2 | #define SIGNAL_UTARRAY_H 3 | 4 | #include "signal_protocol.h" 5 | 6 | #define oom() do { \ 7 | result = SG_ERR_NOMEM; \ 8 | goto complete; \ 9 | } while(0) 10 | 11 | #include "utarray.h" 12 | 13 | #endif /* SIGNAL_UTARRAY_H */ 14 | -------------------------------------------------------------------------------- /src/vpool.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2006, 2008 Alexey Vatchenko 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | /* 18 | * VPool: implementation of pool of data with a variable size. 19 | */ 20 | #ifndef _VPOOL_H_ 21 | #define _VPOOL_H_ 22 | 23 | #include 24 | #include 25 | 26 | struct vpool { 27 | void *v_basebuf; /* pointer returned by (re|m)alloc() */ 28 | void *v_buf; /* actual data starts here */ 29 | size_t v_off; 30 | size_t v_size; 31 | 32 | size_t v_blksize; 33 | size_t v_limit; 34 | int v_lasterr; 35 | }; 36 | 37 | enum vpool_trunc {VPOOL_EXCLUDE, VPOOL_INCLUDE}; 38 | #define VPOOL_TAIL UINT_MAX 39 | 40 | void vpool_init(struct vpool *pool, size_t blksize, size_t limit); 41 | void vpool_final(struct vpool *pool); 42 | 43 | void vpool_reset(struct vpool *pool); 44 | void vpool_wipe(struct vpool *pool); 45 | 46 | void * vpool_insert(struct vpool *pool, 47 | size_t where, void *data, size_t datsize); 48 | void * vpool_expand(struct vpool *pool, size_t where, size_t size); 49 | 50 | int vpool_truncate(struct vpool *pool, 51 | size_t where, size_t size, enum vpool_trunc how); 52 | 53 | #define vpool_is_empty(pool) ((pool)->v_off == 0) 54 | #define vpool_get_buf(pool) ((pool)->v_buf) 55 | #define vpool_get_length(pool) ((pool)->v_off) 56 | #define vpool_get_error(pool) ((pool)->v_lasterr) 57 | 58 | void vpool_export(struct vpool *pool, void **buf, size_t *size); 59 | 60 | #endif /* !_VPOOL_H_ */ 61 | -------------------------------------------------------------------------------- /tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | enable_testing() 2 | find_library(M_LIB m) 3 | find_package(Check 0.9.10 REQUIRED) 4 | IF(NOT(APPLE AND ${CMAKE_SYSTEM_NAME} MATCHES "Darwin")) 5 | find_package(OpenSSL 1.0 REQUIRED) 6 | ENDIF() 7 | find_package(Threads) 8 | include_directories(${CHECK_INCLUDE_DIRS}) 9 | 10 | IF(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang") 11 | SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-function") 12 | ENDIF(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang") 13 | 14 | IF(CMAKE_COMPILER_IS_GNUCC) 15 | SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-sign-compare") 16 | IF(GCC_WARN_SIGN_CONVERSION) 17 | SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-sign-conversion") 18 | ENDIF(GCC_WARN_SIGN_CONVERSION) 19 | ENDIF(CMAKE_COMPILER_IS_GNUCC) 20 | 21 | IF(CMAKE_C_COMPILER_ID MATCHES "Clang") 22 | SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-invalid-source-encoding -Wno-shorten-64-to-32") 23 | ENDIF(CMAKE_C_COMPILER_ID MATCHES "Clang") 24 | 25 | # On Windows .exe and .dll files must be placed at the same directory 26 | if(WIN32 AND BUILD_SHARED_LIBS) 27 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/src) 28 | set(TEST_PATH ${CMAKE_BINARY_DIR}/src) 29 | else() 30 | set(TEST_PATH ${CMAKE_CURRENT_BINARY_DIR}) 31 | endif() 32 | 33 | set(LIBS ${LIBS} 34 | ${M_LIB} 35 | ${CHECK_LDFLAGS} 36 | ${OPENSSL_LIBRARIES} 37 | ${CMAKE_THREAD_LIBS_INIT} 38 | ${CMAKE_DL_LIBS} 39 | signal-protocol-c 40 | ) 41 | 42 | set(common_SRCS 43 | test_common.c 44 | test_common.h 45 | ) 46 | 47 | include_directories(. ../src) 48 | 49 | IF(APPLE AND ${CMAKE_SYSTEM_NAME} MATCHES "Darwin") 50 | set(common_SRCS ${common_SRCS} 51 | test_common_ccrypto.c 52 | ) 53 | ELSE() 54 | set(common_SRCS ${common_SRCS} 55 | test_common_openssl.c 56 | ) 57 | include_directories(${OPENSSL_INCLUDE_DIR}) 58 | ENDIF() 59 | 60 | add_executable(test_curve25519 test_curve25519.c ${common_SRCS}) 61 | target_link_libraries(test_curve25519 ${LIBS}) 62 | add_test(test_curve25519 ${TEST_PATH}/test_curve25519) 63 | 64 | add_executable(test_hkdf test_hkdf.c ${common_SRCS}) 65 | target_link_libraries(test_hkdf ${LIBS}) 66 | add_test(test_hkdf ${TEST_PATH}/test_hkdf) 67 | 68 | add_executable(test_ratchet test_ratchet.c ${common_SRCS}) 69 | target_link_libraries(test_ratchet ${LIBS}) 70 | add_test(test_ratchet ${TEST_PATH}/test_ratchet) 71 | 72 | add_executable(test_protocol test_protocol.c ${common_SRCS}) 73 | target_link_libraries(test_protocol ${LIBS}) 74 | add_test(test_protocol ${TEST_PATH}/test_protocol) 75 | 76 | add_executable(test_session_record test_session_record.c ${common_SRCS}) 77 | target_link_libraries(test_session_record ${LIBS}) 78 | add_test(test_session_record ${TEST_PATH}/test_session_record) 79 | 80 | add_executable(test_session_cipher test_session_cipher.c ${common_SRCS}) 81 | target_link_libraries(test_session_cipher ${LIBS}) 82 | add_test(test_session_cipher ${TEST_PATH}/test_session_cipher) 83 | 84 | add_executable(test_session_builder test_session_builder.c ${common_SRCS}) 85 | target_link_libraries(test_session_builder ${LIBS}) 86 | add_test(test_session_builder ${TEST_PATH}/test_session_builder) 87 | 88 | add_executable(test_key_helper test_key_helper.c ${common_SRCS}) 89 | target_link_libraries(test_key_helper ${LIBS}) 90 | add_test(test_key_helper ${TEST_PATH}/test_key_helper) 91 | 92 | add_executable(test_simultaneous_initiate test_simultaneous_initiate.c ${common_SRCS}) 93 | target_link_libraries(test_simultaneous_initiate ${LIBS}) 94 | add_test(test_simultaneous_initiate ${TEST_PATH}/test_simultaneous_initiate) 95 | 96 | add_executable(test_sender_key_record test_sender_key_record.c ${common_SRCS}) 97 | target_link_libraries(test_sender_key_record ${LIBS}) 98 | add_test(test_sender_key_record ${TEST_PATH}/test_sender_key_record) 99 | 100 | add_executable(test_group_cipher test_group_cipher.c ${common_SRCS}) 101 | target_link_libraries(test_group_cipher ${LIBS}) 102 | add_test(test_group_cipher ${TEST_PATH}/test_group_cipher) 103 | 104 | add_executable(test_fingerprint test_fingerprint.c ${common_SRCS}) 105 | target_link_libraries(test_fingerprint ${LIBS}) 106 | add_test(test_fingerprint ${TEST_PATH}/test_fingerprint) 107 | 108 | add_executable(test_device_consistency test_device_consistency.c ${common_SRCS}) 109 | target_link_libraries(test_device_consistency ${LIBS}) 110 | add_test(test_device_consistency ${TEST_PATH}/test_device_consistency) 111 | -------------------------------------------------------------------------------- /tests/test_common.h: -------------------------------------------------------------------------------- 1 | #ifndef TEST_COMMON_H 2 | #define TEST_COMMON_H 3 | 4 | #include 5 | #include 6 | #include "../src/signal_protocol.h" 7 | 8 | /* Test utility functions */ 9 | void print_public_key(const char *prefix, ec_public_key *key); 10 | void print_buffer(const char *prefix, signal_buffer *buffer); 11 | void shuffle_buffers(signal_buffer **array, size_t n); 12 | void shuffle_ec_public_keys(ec_public_key **array, size_t n); 13 | ec_public_key *create_test_ec_public_key(signal_context *context); 14 | ec_private_key *create_test_ec_private_key(signal_context *context); 15 | 16 | /* Test logging */ 17 | void test_log(int level, const char *message, size_t len, void *user_data); 18 | 19 | /* Test crypto provider */ 20 | int test_random_generator(uint8_t *data, size_t len, void *user_data); 21 | int test_hmac_sha256_init(void **hmac_context, const uint8_t *key, size_t key_len, void *user_data); 22 | int test_hmac_sha256_update(void *hmac_context, const uint8_t *data, size_t data_len, void *user_data); 23 | int test_hmac_sha256_final(void *hmac_context, signal_buffer **output, void *user_data); 24 | void test_hmac_sha256_cleanup(void *hmac_context, void *user_data); 25 | int test_sha512_digest_init(void **digest_context, void *user_data); 26 | int test_sha512_digest_update(void *digest_context, const uint8_t *data, size_t data_len, void *user_data); 27 | int test_sha512_digest_final(void *digest_context, signal_buffer **output, void *user_data); 28 | void test_sha512_digest_cleanup(void *digest_context, void *user_data); 29 | 30 | int test_encrypt(signal_buffer **output, 31 | int cipher, 32 | const uint8_t *key, size_t key_len, 33 | const uint8_t *iv, size_t iv_len, 34 | const uint8_t *plaintext, size_t plaintext_len, 35 | void *user_data); 36 | int test_decrypt(signal_buffer **output, 37 | int cipher, 38 | const uint8_t *key, size_t key_len, 39 | const uint8_t *iv, size_t iv_len, 40 | const uint8_t *ciphertext, size_t ciphertext_len, 41 | void *user_data); 42 | void setup_test_crypto_provider(signal_context *context); 43 | 44 | /* Test data store context */ 45 | void setup_test_store_context(signal_protocol_store_context **context, signal_context *global_context); 46 | 47 | /* Test session store */ 48 | int test_session_store_load_session(signal_buffer **record, signal_buffer **user_record, const signal_protocol_address *address, void *user_data); 49 | int test_session_store_get_sub_device_sessions(signal_int_list **sessions, const char *name, size_t name_len, void *user_data); 50 | int test_session_store_store_session(const signal_protocol_address *address, uint8_t *record, size_t record_len, uint8_t *user_record_data, size_t user_record_len, void *user_data); 51 | int test_session_store_contains_session(const signal_protocol_address *address, void *user_data); 52 | int test_session_store_delete_session(const signal_protocol_address *address, void *user_data); 53 | int test_session_store_delete_all_sessions(const char *name, size_t name_len, void *user_data); 54 | void test_session_store_destroy(void *user_data); 55 | void setup_test_session_store(signal_protocol_store_context *context); 56 | 57 | /* Test pre-key store */ 58 | int test_pre_key_store_load_pre_key(signal_buffer **record, uint32_t pre_key_id, void *user_data); 59 | int test_pre_key_store_store_pre_key(uint32_t pre_key_id, uint8_t *record, size_t record_len, void *user_data); 60 | int test_pre_key_store_contains_pre_key(uint32_t pre_key_id, void *user_data); 61 | int test_pre_key_store_remove_pre_key(uint32_t pre_key_id, void *user_data); 62 | void test_pre_key_store_destroy(void *user_data); 63 | void setup_test_pre_key_store(signal_protocol_store_context *context); 64 | 65 | /* Test signed pre-key store */ 66 | int test_signed_pre_key_store_load_signed_pre_key(signal_buffer **record, uint32_t signed_pre_key_id, void *user_data); 67 | int test_signed_pre_key_store_store_signed_pre_key(uint32_t signed_pre_key_id, uint8_t *record, size_t record_len, void *user_data); 68 | int test_signed_pre_key_store_contains_signed_pre_key(uint32_t signed_pre_key_id, void *user_data); 69 | int test_signed_pre_key_store_remove_signed_pre_key(uint32_t signed_pre_key_id, void *user_data); 70 | void test_signed_pre_key_store_destroy(void *user_data); 71 | void setup_test_signed_pre_key_store(signal_protocol_store_context *context); 72 | 73 | /* Test identity key store */ 74 | int test_identity_key_store_get_identity_key_pair(signal_buffer **public_data, signal_buffer **private_data, void *user_data); 75 | int test_identity_key_store_get_local_registration_id(void *user_data, uint32_t *registration_id); 76 | int test_identity_key_store_save_identity(const signal_protocol_address *address, uint8_t *key_data, size_t key_len, void *user_data); 77 | int test_identity_key_store_is_trusted_identity(const signal_protocol_address *address, uint8_t *key_data, size_t key_len, void *user_data); 78 | void test_identity_key_store_destroy(void *user_data); 79 | void setup_test_identity_key_store(signal_protocol_store_context *context, signal_context *global_context); 80 | 81 | /* Test sender key store */ 82 | int test_sender_key_store_store_sender_key(const signal_protocol_sender_key_name *sender_key_name, uint8_t *record, size_t record_len, uint8_t *user_record_data, size_t user_record_len, void *user_data); 83 | int test_sender_key_store_load_sender_key(signal_buffer **record, signal_buffer **user_record, const signal_protocol_sender_key_name *sender_key_name, void *user_data); 84 | void test_sender_key_store_destroy(void *user_data); 85 | void setup_test_sender_key_store(signal_protocol_store_context *context, signal_context *global_context); 86 | 87 | /* Portability */ 88 | #ifndef __OpenBSD__ 89 | /* OpenBSD extension */ 90 | void srand_deterministic(unsigned int seed); 91 | #endif 92 | 93 | #endif /* TEST_COMMON_H */ 94 | -------------------------------------------------------------------------------- /tests/test_session_builder.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/signalapp/libsignal-protocol-c/3a83a4f4ed2302ff6e68ab569c88793b50c22d28/tests/test_session_builder.c -------------------------------------------------------------------------------- /tests/test_utarray.h: -------------------------------------------------------------------------------- 1 | #ifndef TEST_UTARRAY_H 2 | #define TEST_UTARRAY_H 3 | 4 | #include 5 | 6 | #define oom() ck_abort() 7 | 8 | #include "utarray.h" 9 | 10 | #endif /* TEST_UTARRAY_H */ 11 | --------------------------------------------------------------------------------