Compare commits
1 Commits
ae3d2b20d0
...
b77f273e4e
| Author | SHA1 | Date | |
|---|---|---|---|
| b77f273e4e |
@ -28,9 +28,6 @@ target_include_directories(imgui PUBLIC
|
|||||||
libs/imgui/backends
|
libs/imgui/backends
|
||||||
)
|
)
|
||||||
|
|
||||||
# LibHydrogen
|
|
||||||
add_subdirectory(libs/libhydrogen EXCLUDE_FROM_ALL)
|
|
||||||
|
|
||||||
add_executable(work-calendar
|
add_executable(work-calendar
|
||||||
$<$<PLATFORM_ID:Windows>:src/main_win32.cpp>
|
$<$<PLATFORM_ID:Windows>:src/main_win32.cpp>
|
||||||
$<$<PLATFORM_ID:Linux>:src/main_linux.cpp>
|
$<$<PLATFORM_ID:Linux>:src/main_linux.cpp>
|
||||||
@ -39,10 +36,9 @@ add_executable(work-calendar
|
|||||||
target_link_libraries(work-calendar
|
target_link_libraries(work-calendar
|
||||||
PRIVATE
|
PRIVATE
|
||||||
imgui
|
imgui
|
||||||
hydrogen::hydrogen
|
|
||||||
$<$<PLATFORM_ID:Windows>:D3D11>
|
$<$<PLATFORM_ID:Windows>:D3D11>
|
||||||
$<$<PLATFORM_ID:Linux>:
|
$<$<PLATFORM_ID:Linux>:
|
||||||
vulkan
|
vulkan
|
||||||
glfw
|
glfw
|
||||||
>
|
>
|
||||||
)
|
)
|
||||||
BIN
calendar.wcl
BIN
calendar.wcl
Binary file not shown.
2
keks.wcl
2
keks.wcl
@ -1,2 +0,0 @@
|
|||||||
ŠCl.H¾ÇUn".ŒT¡Ô„Ÿ9¨M]$w‚‰Á#æÆ€ûê-‰<>Ðx¶5©2¥Êm®B*–dqúË7UF‘·7Ò»í‡äeÝ{…6¡Q2ý= ˆò<kè^÷âP0¯eþv¡8ø6ÉÊ3Öy.ê/Å0!˜E~éÿ6ƒxI¶g6qŸèEª ÄgID‚D¹ú5ìÃáILœ-Ê)HjMµí}ëÌê.²,)Úäã¾A
|
|
||||||
á†TR<52>¼Ž?úµlÂE8+¥É¢+ßêøqRaUƒ:‚Ó‡<C393>0Õ:c+×Á¤Ñ˜ë§î¾:'´þš3
|
|
||||||
@ -1,165 +0,0 @@
|
|||||||
---
|
|
||||||
Language: Cpp
|
|
||||||
AccessModifierOffset: -4
|
|
||||||
AlignAfterOpenBracket: Align
|
|
||||||
AlignConsecutiveMacros: true
|
|
||||||
AlignConsecutiveAssignments: true
|
|
||||||
AlignConsecutiveBitFields: true
|
|
||||||
AlignConsecutiveDeclarations: true
|
|
||||||
AlignEscapedNewlines: true
|
|
||||||
AlignOperands: true
|
|
||||||
AlignTrailingComments: false
|
|
||||||
AllowAllArgumentsOnNextLine: true
|
|
||||||
AllowAllConstructorInitializersOnNextLine: true
|
|
||||||
AllowAllParametersOfDeclarationOnNextLine: true
|
|
||||||
AllowShortEnumsOnASingleLine: true
|
|
||||||
AllowShortBlocksOnASingleLine: false
|
|
||||||
AllowShortCaseLabelsOnASingleLine: false
|
|
||||||
AllowShortFunctionsOnASingleLine: false
|
|
||||||
AllowShortLambdasOnASingleLine: All
|
|
||||||
AllowShortIfStatementsOnASingleLine: Never
|
|
||||||
AllowShortLoopsOnASingleLine: false
|
|
||||||
AlwaysBreakAfterDefinitionReturnType: None
|
|
||||||
AlwaysBreakAfterReturnType: TopLevelDefinitions
|
|
||||||
AlwaysBreakBeforeMultilineStrings: true
|
|
||||||
AlwaysBreakTemplateDeclarations: MultiLine
|
|
||||||
AttributeMacros:
|
|
||||||
- __capability
|
|
||||||
BinPackArguments: true
|
|
||||||
BinPackParameters: true
|
|
||||||
BraceWrapping:
|
|
||||||
AfterCaseLabel: false
|
|
||||||
AfterClass: false
|
|
||||||
AfterControlStatement: Never
|
|
||||||
AfterEnum: false
|
|
||||||
AfterFunction: true
|
|
||||||
AfterNamespace: false
|
|
||||||
AfterObjCDeclaration: false
|
|
||||||
AfterStruct: false
|
|
||||||
AfterUnion: false
|
|
||||||
AfterExternBlock: false
|
|
||||||
BeforeCatch: false
|
|
||||||
BeforeElse: false
|
|
||||||
BeforeLambdaBody: false
|
|
||||||
BeforeWhile: false
|
|
||||||
IndentBraces: false
|
|
||||||
SplitEmptyFunction: true
|
|
||||||
SplitEmptyRecord: true
|
|
||||||
SplitEmptyNamespace: true
|
|
||||||
BreakBeforeBinaryOperators: None
|
|
||||||
BreakBeforeConceptDeclarations: true
|
|
||||||
BreakBeforeBraces: WebKit
|
|
||||||
BreakBeforeInheritanceComma: true
|
|
||||||
BreakInheritanceList: BeforeColon
|
|
||||||
BreakBeforeTernaryOperators: true
|
|
||||||
BreakConstructorInitializersBeforeComma: false
|
|
||||||
BreakConstructorInitializers: BeforeComma
|
|
||||||
BreakAfterJavaFieldAnnotations: false
|
|
||||||
BreakStringLiterals: true
|
|
||||||
ColumnLimit: 100
|
|
||||||
CommentPragmas: "^ IWYU pragma:"
|
|
||||||
CompactNamespaces: false
|
|
||||||
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
|
||||||
ConstructorInitializerIndentWidth: 4
|
|
||||||
ContinuationIndentWidth: 4
|
|
||||||
Cpp11BracedListStyle: false
|
|
||||||
DeriveLineEnding: true
|
|
||||||
DerivePointerAlignment: true
|
|
||||||
DisableFormat: false
|
|
||||||
EmptyLineBeforeAccessModifier: LogicalBlock
|
|
||||||
ExperimentalAutoDetectBinPacking: true
|
|
||||||
FixNamespaceComments: false
|
|
||||||
ForEachMacros:
|
|
||||||
- foreach
|
|
||||||
- Q_FOREACH
|
|
||||||
- BOOST_FOREACH
|
|
||||||
StatementAttributeLikeMacros:
|
|
||||||
- Q_EMIT
|
|
||||||
IncludeBlocks: Preserve
|
|
||||||
IncludeCategories:
|
|
||||||
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
|
|
||||||
Priority: 2
|
|
||||||
SortPriority: 0
|
|
||||||
CaseSensitive: false
|
|
||||||
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
|
|
||||||
Priority: 3
|
|
||||||
SortPriority: 0
|
|
||||||
CaseSensitive: false
|
|
||||||
- Regex: ".*"
|
|
||||||
Priority: 1
|
|
||||||
SortPriority: 0
|
|
||||||
CaseSensitive: false
|
|
||||||
IncludeIsMainRegex: "(Test)?$"
|
|
||||||
IncludeIsMainSourceRegex: ""
|
|
||||||
IndentCaseLabels: false
|
|
||||||
IndentCaseBlocks: false
|
|
||||||
IndentGotoLabels: true
|
|
||||||
IndentPPDirectives: AfterHash
|
|
||||||
IndentExternBlock: AfterExternBlock
|
|
||||||
IndentRequires: false
|
|
||||||
IndentWidth: 4
|
|
||||||
IndentWrappedFunctionNames: false
|
|
||||||
InsertTrailingCommas: None
|
|
||||||
JavaScriptQuotes: Leave
|
|
||||||
JavaScriptWrapImports: true
|
|
||||||
KeepEmptyLinesAtTheStartOfBlocks: true
|
|
||||||
MacroBlockBegin: ""
|
|
||||||
MacroBlockEnd: ""
|
|
||||||
MaxEmptyLinesToKeep: 1
|
|
||||||
NamespaceIndentation: Inner
|
|
||||||
ObjCBinPackProtocolList: Auto
|
|
||||||
ObjCBlockIndentWidth: 4
|
|
||||||
ObjCBreakBeforeNestedBlockParam: true
|
|
||||||
ObjCSpaceAfterProperty: true
|
|
||||||
ObjCSpaceBeforeProtocolList: true
|
|
||||||
PenaltyBreakAssignment: 2
|
|
||||||
PenaltyBreakBeforeFirstCallParameter: 19
|
|
||||||
PenaltyBreakComment: 300
|
|
||||||
PenaltyBreakFirstLessLess: 120
|
|
||||||
PenaltyBreakString: 1000
|
|
||||||
PenaltyBreakTemplateDeclaration: 10
|
|
||||||
PenaltyExcessCharacter: 1000000
|
|
||||||
PenaltyReturnTypeOnItsOwnLine: 60
|
|
||||||
PenaltyIndentedWhitespace: 0
|
|
||||||
PointerAlignment: Left
|
|
||||||
ReflowComments: true
|
|
||||||
SortIncludes: true
|
|
||||||
SortJavaStaticImport: Before
|
|
||||||
SortUsingDeclarations: true
|
|
||||||
SpaceAfterCStyleCast: true
|
|
||||||
SpaceAfterLogicalNot: false
|
|
||||||
SpaceAfterTemplateKeyword: true
|
|
||||||
SpaceBeforeAssignmentOperators: true
|
|
||||||
SpaceBeforeCaseColon: false
|
|
||||||
SpaceBeforeCpp11BracedList: true
|
|
||||||
SpaceBeforeCtorInitializerColon: true
|
|
||||||
SpaceBeforeInheritanceColon: true
|
|
||||||
SpaceBeforeParens: ControlStatements
|
|
||||||
SpaceAroundPointerQualifiers: Default
|
|
||||||
SpaceBeforeRangeBasedForLoopColon: true
|
|
||||||
SpaceInEmptyBlock: true
|
|
||||||
SpaceInEmptyParentheses: false
|
|
||||||
SpacesBeforeTrailingComments: 1
|
|
||||||
SpacesInAngles: false
|
|
||||||
SpacesInConditionalStatement: false
|
|
||||||
SpacesInContainerLiterals: true
|
|
||||||
SpacesInCStyleCastParentheses: false
|
|
||||||
SpacesInParentheses: false
|
|
||||||
SpacesInSquareBrackets: false
|
|
||||||
SpaceBeforeSquareBrackets: false
|
|
||||||
BitFieldColonSpacing: Both
|
|
||||||
Standard: Latest
|
|
||||||
StatementMacros:
|
|
||||||
- Q_UNUSED
|
|
||||||
- QT_REQUIRE_VERSION
|
|
||||||
TabWidth: 4
|
|
||||||
UseCRLF: false
|
|
||||||
UseTab: Never
|
|
||||||
WhitespaceSensitiveMacros:
|
|
||||||
- STRINGIZE
|
|
||||||
- PP_STRINGIZE
|
|
||||||
- BOOST_PP_STRINGIZE
|
|
||||||
- NS_SWIFT_NAME
|
|
||||||
- CF_SWIFT_NAME
|
|
||||||
---
|
|
||||||
|
|
||||||
@ -1,47 +0,0 @@
|
|||||||
{
|
|
||||||
"additional_commands": {
|
|
||||||
"add_custom_command": {
|
|
||||||
"kwargs": {
|
|
||||||
"ARGS": "*",
|
|
||||||
"COMMAND": 1,
|
|
||||||
"OUTPUT": 1,
|
|
||||||
"WORKING_DIRECTORY": 1
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"configure_package_config_file": {
|
|
||||||
"kwargs": {
|
|
||||||
"INSTALL_DESTINATION": 1
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"include_directories": {
|
|
||||||
"kwargs": {
|
|
||||||
"SYSTEM": 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"list": {
|
|
||||||
"kwargs": {
|
|
||||||
"APPEND": 1,
|
|
||||||
"OUTPUT_VARIABLE": 1,
|
|
||||||
"PREPEND": 1,
|
|
||||||
"TRANSFORM": 1
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"set_target_properties": {
|
|
||||||
"kwargs": {
|
|
||||||
"EXCLUDE_FROM_ALL": 1,
|
|
||||||
"EXCLUDE_FROM_DEFAULT_BUILD": 1,
|
|
||||||
"PROPERTIES": 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"string": {
|
|
||||||
"kwargs": {
|
|
||||||
"APPEND": 1,
|
|
||||||
"CONCAT": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"keyword_case": "upper",
|
|
||||||
"line_width": 99,
|
|
||||||
"max_subargs_per_line": 6
|
|
||||||
}
|
|
||||||
|
|
||||||
56
libs/libhydrogen/.github/workflows/ci.yml
vendored
56
libs/libhydrogen/.github/workflows/ci.yml
vendored
@ -1,56 +0,0 @@
|
|||||||
name: CI
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [master]
|
|
||||||
pull_request:
|
|
||||||
branches: [master]
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
zig:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v6
|
|
||||||
|
|
||||||
- name: Update packages list
|
|
||||||
run: sudo apt-get update
|
|
||||||
|
|
||||||
- name: Install Zig
|
|
||||||
uses: mlugg/setup-zig@v2
|
|
||||||
with:
|
|
||||||
version: master
|
|
||||||
|
|
||||||
- name: Build
|
|
||||||
run: |
|
|
||||||
zig build
|
|
||||||
zig build -Dtarget=x86_64-linux
|
|
||||||
zig build -Dtarget=aarch64-linux
|
|
||||||
zig build -Dtarget=x86_64-windows
|
|
||||||
zig build -Dtarget=aarch64-windows
|
|
||||||
zig build -Dtarget=x86_64-macos
|
|
||||||
zig build -Dtarget=aarch64-macos
|
|
||||||
zig build -Dtarget=wasm32-wasi
|
|
||||||
zig build -Drelease
|
|
||||||
rm -fr zig-cache zig-out
|
|
||||||
|
|
||||||
make:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v6
|
|
||||||
|
|
||||||
- name: Update packages list
|
|
||||||
run: sudo apt-get update
|
|
||||||
|
|
||||||
- name: Install Make
|
|
||||||
run: sudo apt-get install make
|
|
||||||
|
|
||||||
- name: Build
|
|
||||||
run: make
|
|
||||||
|
|
||||||
- name: Test
|
|
||||||
run: make test
|
|
||||||
|
|
||||||
@ -1,58 +0,0 @@
|
|||||||
name: "CodeQL"
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [ "master" ]
|
|
||||||
pull_request:
|
|
||||||
# The branches below must be a subset of the branches above
|
|
||||||
branches: [ "master" ]
|
|
||||||
schedule:
|
|
||||||
- cron: '18 19 * * 2'
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
analyze:
|
|
||||||
name: Analyze
|
|
||||||
runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }}
|
|
||||||
timeout-minutes: ${{ (matrix.language == 'swift' && 120) || 360 }}
|
|
||||||
permissions:
|
|
||||||
actions: read
|
|
||||||
contents: read
|
|
||||||
security-events: write
|
|
||||||
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
language: [ 'c-cpp' ]
|
|
||||||
autobuild_force_build_system: ['cmake', 'make', 'meson']
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout repository
|
|
||||||
uses: actions/checkout@v6
|
|
||||||
|
|
||||||
- name: Maybe remove non-CMake build systems
|
|
||||||
if: matrix.autobuild_force_build_system == 'cmake'
|
|
||||||
run: |
|
|
||||||
rm -vrf Makefile* meson.build
|
|
||||||
|
|
||||||
- name: Maybe remove non-Make build systems
|
|
||||||
if: matrix.autobuild_force_build_system == 'make'
|
|
||||||
run: |
|
|
||||||
rm -vrf CMakeLists.txt cmake/ meson.build
|
|
||||||
|
|
||||||
- name: Maybe remove non-Meson build systems
|
|
||||||
if: matrix.autobuild_force_build_system == 'meson'
|
|
||||||
run: |
|
|
||||||
rm -vrf Makefile* CMakeLists.txt cmake/
|
|
||||||
|
|
||||||
- name: Initialize CodeQL
|
|
||||||
uses: github/codeql-action/init@v4
|
|
||||||
with:
|
|
||||||
languages: ${{ matrix.language }}
|
|
||||||
|
|
||||||
- name: Autobuild
|
|
||||||
uses: github/codeql-action/autobuild@v4
|
|
||||||
|
|
||||||
- name: Perform CodeQL Analysis
|
|
||||||
uses: github/codeql-action/analyze@v4
|
|
||||||
with:
|
|
||||||
category: "/language:${{matrix.language}}"
|
|
||||||
17
libs/libhydrogen/.github/workflows/issues.yml
vendored
17
libs/libhydrogen/.github/workflows/issues.yml
vendored
@ -1,17 +0,0 @@
|
|||||||
name: Close inactive issues
|
|
||||||
on:
|
|
||||||
schedule:
|
|
||||||
- cron: "30 1 * * *"
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
close-issues:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
permissions:
|
|
||||||
issues: write
|
|
||||||
pull-requests: write
|
|
||||||
steps:
|
|
||||||
- uses: actions/stale@v10
|
|
||||||
with:
|
|
||||||
stale-issue-message: "This issue is stale because it has been open for 30 days with no activity."
|
|
||||||
close-issue-message: "This issue was closed because it has been inactive for 14 days since being marked as stale."
|
|
||||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
33
libs/libhydrogen/.gitignore
vendored
33
libs/libhydrogen/.gitignore
vendored
@ -1,33 +0,0 @@
|
|||||||
*.bc
|
|
||||||
*.dSYM
|
|
||||||
*.done
|
|
||||||
*.final
|
|
||||||
*.gcda
|
|
||||||
*.gcno
|
|
||||||
*.i
|
|
||||||
*.la
|
|
||||||
*.lo
|
|
||||||
*.log
|
|
||||||
*.mem
|
|
||||||
*.nexe
|
|
||||||
*.o
|
|
||||||
*.plist
|
|
||||||
*.scan
|
|
||||||
*.sdf
|
|
||||||
*.status
|
|
||||||
*.su
|
|
||||||
*.tar.*
|
|
||||||
*~
|
|
||||||
.DS_Store
|
|
||||||
.deps
|
|
||||||
.dirstamp
|
|
||||||
.done
|
|
||||||
.idea
|
|
||||||
.libs
|
|
||||||
build.options.json
|
|
||||||
cmake-build-*
|
|
||||||
coverage.info
|
|
||||||
depcomp
|
|
||||||
hydrogen-crypto.zip
|
|
||||||
libhydrogen.a
|
|
||||||
tests/tests
|
|
||||||
@ -1,31 +0,0 @@
|
|||||||
language: c
|
|
||||||
sudo: false
|
|
||||||
dist: bionic
|
|
||||||
|
|
||||||
env:
|
|
||||||
- CFLAGS="-Wall -W -O"
|
|
||||||
|
|
||||||
os:
|
|
||||||
- linux
|
|
||||||
|
|
||||||
compiler:
|
|
||||||
- clang
|
|
||||||
- gcc
|
|
||||||
- g++
|
|
||||||
|
|
||||||
arch:
|
|
||||||
- arm64
|
|
||||||
- amd64
|
|
||||||
- s390x
|
|
||||||
- ppc64le
|
|
||||||
|
|
||||||
addons:
|
|
||||||
apt:
|
|
||||||
packages:
|
|
||||||
- p7zip-full
|
|
||||||
|
|
||||||
script:
|
|
||||||
- make
|
|
||||||
- make test
|
|
||||||
- make clean
|
|
||||||
- make -f Makefile.arduino package
|
|
||||||
@ -1,18 +0,0 @@
|
|||||||
cff-version: 1.2.0
|
|
||||||
title: libhydrogen
|
|
||||||
message: >-
|
|
||||||
If you use this software, please cite it using the
|
|
||||||
metadata from this file.
|
|
||||||
type: software
|
|
||||||
authors:
|
|
||||||
- given-names: Frank
|
|
||||||
family-names: Denis
|
|
||||||
orcid: 'https://orcid.org/0009-0008-4417-1713'
|
|
||||||
repository-code: 'https://github.com/jedisct1/libhydrogen'
|
|
||||||
url: 'https://libhydrogen.org'
|
|
||||||
abstract: 'A lightweight, secure, easy-to-use crypto library suitable for constrained environments.'
|
|
||||||
keywords:
|
|
||||||
- cryptography
|
|
||||||
- library
|
|
||||||
- embedded
|
|
||||||
license: ISC
|
|
||||||
@ -1,193 +0,0 @@
|
|||||||
cmake_minimum_required(VERSION 3.1)
|
|
||||||
|
|
||||||
project(hydrogen LANGUAGES C)
|
|
||||||
|
|
||||||
include(CMakePackageConfigHelpers)
|
|
||||||
include(GNUInstallDirs)
|
|
||||||
|
|
||||||
string(TOUPPER "${PROJECT_NAME}" setting_prefix)
|
|
||||||
function(get_setting setting_name setting_type setting_description)
|
|
||||||
string(TOUPPER "${setting_prefix}_${setting_name}" setting_external_name)
|
|
||||||
set("${setting_external_name}" "" CACHE "${setting_type}" "${setting_description}")
|
|
||||||
set("${setting_name}" "${${setting_external_name}}" PARENT_SCOPE)
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
# Project files
|
|
||||||
|
|
||||||
set(source_files
|
|
||||||
"${PROJECT_NAME}.c"
|
|
||||||
"impl/common.h"
|
|
||||||
"impl/core.h"
|
|
||||||
"impl/gimli-core.h"
|
|
||||||
"impl/gimli-core/portable.h"
|
|
||||||
"impl/gimli-core/sse2.h"
|
|
||||||
"impl/hash.h"
|
|
||||||
"impl/${PROJECT_NAME}_p.h"
|
|
||||||
"impl/kdf.h"
|
|
||||||
"impl/kx.h"
|
|
||||||
"impl/pwhash.h"
|
|
||||||
"impl/random.h"
|
|
||||||
"impl/secretbox.h"
|
|
||||||
"impl/sign.h"
|
|
||||||
"impl/x25519.h")
|
|
||||||
|
|
||||||
set(header_files "${PROJECT_NAME}.h")
|
|
||||||
|
|
||||||
set(test_files "tests/tests.c")
|
|
||||||
|
|
||||||
set(arduino_files "library.properties")
|
|
||||||
|
|
||||||
# Compile options
|
|
||||||
|
|
||||||
get_setting(target_arch STRING "Target system architecture (fed to the compiler's -march=XXX).")
|
|
||||||
if(NOT target_arch AND NOT CMAKE_CROSSCOMPILING)
|
|
||||||
set(target_arch native)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
get_setting(target_device STRING "Target device identifier (defines HYDRO_TARGET_DEVICE_XXX).")
|
|
||||||
|
|
||||||
set(compile_options
|
|
||||||
# --- GNU, Clang ---
|
|
||||||
$<$<OR:$<C_COMPILER_ID:AppleClang>,$<C_COMPILER_ID:Clang>,$<C_COMPILER_ID:GNU>>:
|
|
||||||
# ---- Definitions ----
|
|
||||||
$<$<BOOL:${target_device}>:-DHYDRO_TARGET_DEVICE_${target_device}>
|
|
||||||
# ---- Optimizations ----
|
|
||||||
-Os $<$<BOOL:${target_arch}>:-march=${target_arch}> -fno-exceptions
|
|
||||||
# ---- Warnings ----
|
|
||||||
-Wall
|
|
||||||
-Wextra
|
|
||||||
-Wmissing-prototypes
|
|
||||||
-Wdiv-by-zero
|
|
||||||
-Wbad-function-cast
|
|
||||||
-Wcast-align
|
|
||||||
-Wcast-qual
|
|
||||||
-Wfloat-equal
|
|
||||||
-Wmissing-declarations
|
|
||||||
-Wnested-externs
|
|
||||||
-Wno-unknown-pragmas
|
|
||||||
-Wpointer-arith
|
|
||||||
-Wredundant-decls
|
|
||||||
-Wstrict-prototypes
|
|
||||||
-Wswitch-enum
|
|
||||||
-Wno-type-limits
|
|
||||||
>
|
|
||||||
# --- MSVC ---
|
|
||||||
$<$<C_COMPILER_ID:MSVC>:
|
|
||||||
# ---- Definitions ----
|
|
||||||
$<$<BOOL:${target_device}>:/DHYDRO_TARGET_DEVICE_${target_device}>
|
|
||||||
# ---- Optimizations ----
|
|
||||||
/Os /EHsc
|
|
||||||
# ---- Warnings ----
|
|
||||||
/W4
|
|
||||||
/wd4197 # * suppress warning "top-level volatile in cast is ignored"
|
|
||||||
/wd4146 # * suppress warning "unary minus operator applied to unsigned type, result still
|
|
||||||
# unsigned"
|
|
||||||
/wd4310 # * suppress warning "cast truncates constant value"
|
|
||||||
>)
|
|
||||||
|
|
||||||
# Prefix project files with the project root
|
|
||||||
|
|
||||||
# Main library
|
|
||||||
|
|
||||||
add_library("${PROJECT_NAME}")
|
|
||||||
add_library("${PROJECT_NAME}::${PROJECT_NAME}" ALIAS "${PROJECT_NAME}")
|
|
||||||
|
|
||||||
target_sources("${PROJECT_NAME}" PRIVATE ${source_files})
|
|
||||||
|
|
||||||
target_include_directories("${PROJECT_NAME}"
|
|
||||||
PUBLIC $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}>
|
|
||||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
|
|
||||||
|
|
||||||
target_compile_options("${PROJECT_NAME}" PRIVATE ${compile_options})
|
|
||||||
|
|
||||||
# Installation
|
|
||||||
|
|
||||||
set(targets_export_name "${PROJECT_NAME}-targets")
|
|
||||||
|
|
||||||
install(TARGETS "${PROJECT_NAME}"
|
|
||||||
EXPORT "${targets_export_name}"
|
|
||||||
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
|
|
||||||
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}")
|
|
||||||
|
|
||||||
install(FILES ${header_files} DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
|
|
||||||
|
|
||||||
# CMake find_package() support
|
|
||||||
|
|
||||||
set(install_config_dir "${CMAKE_INSTALL_DATADIR}/cmake/${PROJECT_NAME}")
|
|
||||||
|
|
||||||
set(targets_export_file_name "${targets_export_name}.cmake")
|
|
||||||
set(targets_export_file "${PROJECT_BINARY_DIR}/${targets_export_file_name}")
|
|
||||||
|
|
||||||
install(EXPORT "${targets_export_name}"
|
|
||||||
FILE "${targets_export_file_name}"
|
|
||||||
NAMESPACE "${PROJECT_NAME}::"
|
|
||||||
DESTINATION "${install_config_dir}")
|
|
||||||
|
|
||||||
set(config_file_name "${PROJECT_NAME}-config.cmake")
|
|
||||||
set(config_template_file "${PROJECT_SOURCE_DIR}/cmake/${config_file_name}.in")
|
|
||||||
set(config_file "${PROJECT_BINARY_DIR}/${config_file_name}")
|
|
||||||
|
|
||||||
configure_package_config_file("${config_template_file}" "${config_file}"
|
|
||||||
INSTALL_DESTINATION "${install_config_dir}")
|
|
||||||
|
|
||||||
install(FILES "${config_file}" DESTINATION "${install_config_dir}")
|
|
||||||
|
|
||||||
export(EXPORT "${targets_export_name}" FILE "${targets_export_file}" NAMESPACE "${PROJECT_NAME}::")
|
|
||||||
|
|
||||||
export(PACKAGE "${PROJECT_NAME}")
|
|
||||||
|
|
||||||
# Tests
|
|
||||||
|
|
||||||
set(tests_executable "${PROJECT_NAME}-tests")
|
|
||||||
set(tests_run_target "${PROJECT_NAME}-run-tests")
|
|
||||||
set(tests_run_file "${PROJECT_BINARY_DIR}/${tests_run_target}.done")
|
|
||||||
|
|
||||||
enable_testing()
|
|
||||||
add_executable("${tests_executable}" ${test_files})
|
|
||||||
target_compile_options("${tests_executable}" PRIVATE ${compile_options})
|
|
||||||
target_link_libraries("${tests_executable}" "${PROJECT_NAME}")
|
|
||||||
add_test(NAME "${tests_executable}" COMMAND "${tests_executable}")
|
|
||||||
|
|
||||||
if(CMAKE_CROSSCOMPILING)
|
|
||||||
# Disable tests executable by default when cross-compiling (as it will fail to build when, e.g.,
|
|
||||||
# cross-compiling for Arduino/AVR).
|
|
||||||
set_target_properties("${tests_executable}"
|
|
||||||
PROPERTIES
|
|
||||||
EXCLUDE_FROM_ALL 1
|
|
||||||
EXCLUDE_FROM_DEFAULT_BUILD 1)
|
|
||||||
else()
|
|
||||||
# Otherwise, auto-run the tests on build.
|
|
||||||
add_custom_command(OUTPUT "${tests_run_file}"
|
|
||||||
DEPENDS "${tests_executable}"
|
|
||||||
COMMAND "${CMAKE_COMMAND}"
|
|
||||||
ARGS -E remove "${tests_run_file}"
|
|
||||||
COMMAND "${CMAKE_CTEST_COMMAND}"
|
|
||||||
ARGS -C $<CONFIGURATION> --output-on-failure
|
|
||||||
COMMAND "${CMAKE_COMMAND}"
|
|
||||||
ARGS -E touch "${tests_run_file}"
|
|
||||||
WORKING_DIRECTORY "${PROJECT_BINARY_DIR}"
|
|
||||||
VERBATIM)
|
|
||||||
add_custom_target("${tests_run_target}" ALL DEPENDS "${tests_run_file}" VERBATIM)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Generate Arduino package
|
|
||||||
|
|
||||||
set(arduino_package_file "${PROJECT_BINARY_DIR}/hydrogen-crypto.zip")
|
|
||||||
|
|
||||||
# Use the relative versions of the file path lists or else the full paths will end up in the
|
|
||||||
# generated archive.
|
|
||||||
add_custom_command(OUTPUT "${arduino_package_file}"
|
|
||||||
COMMAND "${CMAKE_COMMAND}"
|
|
||||||
ARGS -E
|
|
||||||
tar
|
|
||||||
cf
|
|
||||||
"${arduino_package_file}"
|
|
||||||
--format=zip
|
|
||||||
--
|
|
||||||
${source_files}
|
|
||||||
${header_files}
|
|
||||||
${arduino_files}
|
|
||||||
WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}"
|
|
||||||
VERBATIM)
|
|
||||||
|
|
||||||
add_custom_target("${PROJECT_NAME}-arduino-package" DEPENDS "${arduino_package_file}" VERBATIM)
|
|
||||||
@ -1,18 +0,0 @@
|
|||||||
/*
|
|
||||||
* ISC License
|
|
||||||
*
|
|
||||||
* Copyright (c) 2017-2026
|
|
||||||
* Frank Denis <j at pureftpd dot org>
|
|
||||||
*
|
|
||||||
* Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
|
||||||
* copyright notice and this permission notice appear in all copies.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
@ -1,61 +0,0 @@
|
|||||||
PREFIX ?= /usr/local
|
|
||||||
WFLAGS ?= -Wall -Wextra -Wmissing-prototypes -Wdiv-by-zero -Wbad-function-cast -Wcast-align -Wcast-qual -Wfloat-equal -Wmissing-declarations -Wnested-externs -Wno-unknown-pragmas -Wpointer-arith -Wredundant-decls -Wstrict-prototypes -Wswitch-enum -Wno-type-limits
|
|
||||||
CFLAGS ?= -Os -mtune=native -fno-exceptions $(WFLAGS)
|
|
||||||
CFLAGS += -I.
|
|
||||||
OBJ = hydrogen.o
|
|
||||||
AR ?= ar
|
|
||||||
RANLIB ?= ranlib
|
|
||||||
|
|
||||||
SRC = \
|
|
||||||
hydrogen.c \
|
|
||||||
hydrogen.h \
|
|
||||||
impl/common.h \
|
|
||||||
impl/core.h \
|
|
||||||
impl/gimli-core.h \
|
|
||||||
impl/hash.h \
|
|
||||||
impl/hydrogen_p.h \
|
|
||||||
impl/kdf.h \
|
|
||||||
impl/kx.h \
|
|
||||||
impl/pwhash.h \
|
|
||||||
impl/random.h \
|
|
||||||
impl/secretbox.h \
|
|
||||||
impl/sign.h \
|
|
||||||
impl/x25519.h
|
|
||||||
|
|
||||||
all: lib test
|
|
||||||
|
|
||||||
lib: libhydrogen.a
|
|
||||||
|
|
||||||
install: lib
|
|
||||||
mkdir -p $(PREFIX)/lib
|
|
||||||
install -o 0 -g 0 -m 0755 libhydrogen.a $(PREFIX)/lib 2> /dev/null || install -m 0755 libhydrogen.a $(PREFIX)/lib
|
|
||||||
mkdir -p $(PREFIX)/include
|
|
||||||
install -o 0 -g 0 -m 0644 hydrogen.h $(PREFIX)/include 2> /dev/null || install -m 0644 hydrogen.h $(PREFIX)/include
|
|
||||||
ldconfig 2> /dev/null || true
|
|
||||||
|
|
||||||
uninstall:
|
|
||||||
rm -f $(PREFIX)/lib/libhydrogen.a
|
|
||||||
rm -f $(PREFIX)/include/hydrogen.h
|
|
||||||
|
|
||||||
test: tests/tests
|
|
||||||
rm -f tests/tests.done
|
|
||||||
tests/tests && touch tests/tests.done
|
|
||||||
|
|
||||||
tests/tests: $(SRC) tests/tests.c
|
|
||||||
$(CC) $(CFLAGS) -O3 -o tests/tests hydrogen.c tests/tests.c
|
|
||||||
|
|
||||||
$(OBJ): $(SRC)
|
|
||||||
|
|
||||||
libhydrogen.a: $(OBJ)
|
|
||||||
$(AR) -r $@ $^
|
|
||||||
$(RANLIB) $@
|
|
||||||
|
|
||||||
.PHONY: clean
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -f libhydrogen.a $(OBJ)
|
|
||||||
rm -f tests/tests tests/*.done
|
|
||||||
|
|
||||||
check: test
|
|
||||||
|
|
||||||
distclean: clean
|
|
||||||
@ -1,52 +0,0 @@
|
|||||||
TARGET_DEVICE ?= atmega328p
|
|
||||||
HWTYPE ?= HYDRO_TARGET_DEVICE_ATMEGA328
|
|
||||||
ARDUINO_HOME ?= /Applications/Arduino.app/Contents/Java
|
|
||||||
ARDUINO_TOOLS ?= $(ARDUINO_HOME)/hardware/tools/avr/bin
|
|
||||||
AR = $(ARDUINO_TOOLS)/avr-gcc-ar
|
|
||||||
CC = $(ARDUINO_TOOLS)/avr-gcc
|
|
||||||
RANLIB = $(ARDUINO_TOOLS)/avr-gcc-ranlib
|
|
||||||
WFLAGS ?= -Wall -Wextra -Wmissing-prototypes -Wdiv-by-zero -Wbad-function-cast -Wcast-align -Wcast-qual -Wfloat-equal -Wmissing-declarations -Wnested-externs -Wno-unknown-pragmas -Wpointer-arith -Wredundant-decls -Wstrict-prototypes -Wswitch-enum -Wno-type-limits
|
|
||||||
CFLAGS ?= -mmcu=$(TARGET_DEVICE) -Os -mcall-prologues -fno-exceptions -ffunction-sections -fdata-sections -flto $(WFLAGS)
|
|
||||||
CFLAGS += -I. -I$(ARDUINO_HOME)/hardware/arduino/avr/cores/arduino -I$(ARDUINO_HOME)/hardware/arduino/avr/variants/standard
|
|
||||||
CFLAGS += -DHYDRO_HWTYPE=$(HYDRO_HWTYPE)
|
|
||||||
OBJ = hydrogen.o
|
|
||||||
ARDUINO_PACKAGE ?= hydrogen-crypto.zip
|
|
||||||
SRC = \
|
|
||||||
hydrogen.c \
|
|
||||||
hydrogen.h \
|
|
||||||
impl/common.h \
|
|
||||||
impl/core.h \
|
|
||||||
impl/gimli-core.h \
|
|
||||||
impl/hash.h \
|
|
||||||
impl/hydrogen_p.h \
|
|
||||||
impl/kdf.h \
|
|
||||||
impl/kx.h \
|
|
||||||
impl/pwhash.h \
|
|
||||||
impl/random.h \
|
|
||||||
impl/secretbox.h \
|
|
||||||
impl/sign.h \
|
|
||||||
impl/x25519.h \
|
|
||||||
impl/gimli-core/portable.h \
|
|
||||||
impl/random/*.h
|
|
||||||
|
|
||||||
all: lib package
|
|
||||||
|
|
||||||
package: $(ARDUINO_PACKAGE)
|
|
||||||
|
|
||||||
$(ARDUINO_PACKAGE):
|
|
||||||
7z a -tzip -mx=9 -r $(ARDUINO_PACKAGE) $(SRC) library.properties
|
|
||||||
|
|
||||||
lib: libhydrogen.a
|
|
||||||
|
|
||||||
$(OBJ): $(SRC)
|
|
||||||
|
|
||||||
libhydrogen.a: $(OBJ)
|
|
||||||
$(AR) -ar cr $@ $^
|
|
||||||
$(RANLIB) $@
|
|
||||||
|
|
||||||
.PHONY: clean
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -f libhydrogen.a $(OBJ)
|
|
||||||
rm -f tests/tests
|
|
||||||
rm -f $(ARDUINO_PACKAGE)
|
|
||||||
@ -1,43 +0,0 @@
|
|||||||
MCU ?= cortex-m7
|
|
||||||
WFLAGS ?= -Wall -Wextra -Wmissing-prototypes -Wdiv-by-zero -Wbad-function-cast -Wcast-align -Wcast-qual -Wfloat-equal -Wmissing-declarations -Wnested-externs -Wno-unknown-pragmas -Wpointer-arith -Wredundant-decls -Wstrict-prototypes -Wswitch-enum -Wno-type-limits
|
|
||||||
CFLAGS ?= -Os -mcpu=$(MCU) -mthumb -mpure-code -fno-exceptions -ffunction-sections -fdata-sections -flto $(WFLAGS)
|
|
||||||
CFLAGS += -DCHIBIOS
|
|
||||||
CFLAGS += -I.
|
|
||||||
OBJ = hydrogen.o
|
|
||||||
AR ?= arm-none-eabi-ar
|
|
||||||
CC = arm-none-eabi-gcc
|
|
||||||
RANLIB ?= arm-none-eabi-ranlib
|
|
||||||
|
|
||||||
SRC = \
|
|
||||||
hydrogen.c \
|
|
||||||
hydrogen.h \
|
|
||||||
impl/common.h \
|
|
||||||
impl/core.h \
|
|
||||||
impl/gimli-core.h \
|
|
||||||
impl/hash.h \
|
|
||||||
impl/hydrogen_p.h \
|
|
||||||
impl/kdf.h \
|
|
||||||
impl/kx.h \
|
|
||||||
impl/pwhash.h \
|
|
||||||
impl/random.h \
|
|
||||||
impl/secretbox.h \
|
|
||||||
impl/sign.h \
|
|
||||||
impl/x25519.h
|
|
||||||
|
|
||||||
all: lib
|
|
||||||
|
|
||||||
lib: libhydrogen.a
|
|
||||||
|
|
||||||
$(OBJ): $(SRC)
|
|
||||||
|
|
||||||
libhydrogen.a: $(OBJ)
|
|
||||||
$(AR) -r $@ $^
|
|
||||||
$(RANLIB) $@
|
|
||||||
|
|
||||||
.PHONY: clean
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -f libhydrogen.a $(OBJ)
|
|
||||||
rm -f tests/tests tests/*.done
|
|
||||||
|
|
||||||
distclean: clean
|
|
||||||
@ -1,40 +0,0 @@
|
|||||||
PARTICLE_PACKAGE ?= hydrogen-crypto.zip
|
|
||||||
SRC = \
|
|
||||||
hydrogen.c \
|
|
||||||
hydrogen.h \
|
|
||||||
impl/common.h \
|
|
||||||
impl/core.h \
|
|
||||||
impl/gimli-core.h \
|
|
||||||
impl/hash.h \
|
|
||||||
impl/hydrogen_p.h \
|
|
||||||
impl/kdf.h \
|
|
||||||
impl/kx.h \
|
|
||||||
impl/pwhash.h \
|
|
||||||
impl/random.h \
|
|
||||||
impl/secretbox.h \
|
|
||||||
impl/sign.h \
|
|
||||||
impl/x25519.h \
|
|
||||||
impl/gimli-core/portable.h
|
|
||||||
|
|
||||||
all: package
|
|
||||||
|
|
||||||
package: $(PARTICLE_PACKAGE)
|
|
||||||
|
|
||||||
$(PARTICLE_PACKAGE):
|
|
||||||
mkdir particle
|
|
||||||
mkdir particle/src
|
|
||||||
cp library.properties particle/.
|
|
||||||
cp README.md particle/.
|
|
||||||
cp LICENSE particle/.
|
|
||||||
cp -r impl particle/src/.
|
|
||||||
cp hydrogen.h particle/src/.
|
|
||||||
cp hydrogen.c particle/src/hydrogen.cpp
|
|
||||||
7z a -tzip -mx=9 -r $(PARTICLE_PACKAGE) particle/.
|
|
||||||
rm -rf particle
|
|
||||||
|
|
||||||
.PHONY: clean
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -f tests/tests
|
|
||||||
rm -rf particle
|
|
||||||
rm -f $(PARTICLE_PACKAGE)
|
|
||||||
@ -1,38 +0,0 @@
|
|||||||
[](https://github.com/jedisct1/libhydrogen/actions/workflows/ci.yml)
|
|
||||||
[](https://github.com/jedisct1/libhydrogen/actions/workflows/codeql-analysis.yml)
|
|
||||||
[](https://opencollective.com/libhydrogen) [](https://scan.coverity.com/projects/13315)
|
|
||||||
[](https://ci.trust-in-soft.com/projects/jedisct1/libhydrogen)
|
|
||||||
|
|
||||||

|
|
||||||
==============
|
|
||||||
|
|
||||||
The Hydrogen library is a small, easy-to-use, hard-to-misuse cryptographic library.
|
|
||||||
|
|
||||||
Features:
|
|
||||||
- Consistent high-level API, inspired by libsodium. Instead of low-level primitives, it exposes simple functions to solve common problems that cryptography can solve.
|
|
||||||
- 100% built using just two cryptographic building blocks: the [Curve25519](https://cr.yp.to/ecdh.html) elliptic curve, and the [Gimli](https://csrc.nist.gov/CSRC/media/Projects/Lightweight-Cryptography/documents/round-1/spec-doc/gimli-spec.pdf) permutation.
|
|
||||||
- Small and easy to audit. Implemented as one tiny file for every set of operation, and adding a single `.c` file to your project is all it takes to use libhydrogen in your project.
|
|
||||||
- The whole code is released under a single, very liberal license (ISC).
|
|
||||||
- Zero dynamic memory allocations and low stack requirements (median: 32 bytes, max: 128 bytes). This makes it usable in constrained environments such as microcontrollers.
|
|
||||||
- Portable: written in standard C99. Supports Linux, *BSD, MacOS, Windows, and the Arduino IDE out of the box.
|
|
||||||
- Can generate cryptographically-secure random numbers, even on Arduino boards.
|
|
||||||
- Attempts to mitigate the implications of accidental misuse, even on systems with an unreliable PRG and/or no clock.
|
|
||||||
|
|
||||||
Non-goals:
|
|
||||||
- Having multiple primitives serving the same purpose, even to provide compatibility with other libraries.
|
|
||||||
- Networking -- but a simple key exchange API based on the Noise protocol is available, and a STROBE-based transport API will be implemented.
|
|
||||||
- Interoperability with other libraries.
|
|
||||||
- Replacing libsodium. Libhydrogen tries to keep the number of APIs and the code size down to a minimum.
|
|
||||||
|
|
||||||
# [Libhydrogen documentation](https://github.com/jedisct1/libhydrogen/wiki)
|
|
||||||
|
|
||||||
The documentation is maintained in the [libhydrogen wiki](https://github.com/jedisct1/libhydrogen/wiki).
|
|
||||||
|
|
||||||
The legacy libhydrogen code (leveraging XChaCha20, SipHashX, BLAKE2SX, Curve25519) remains available in the [v0 branch](https://github.com/jedisct1/libhydrogen/tree/v0).
|
|
||||||
|
|
||||||
## Contributors
|
|
||||||
|
|
||||||
### Code Contributors
|
|
||||||
|
|
||||||
This project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].
|
|
||||||
<a href="https://github.com/jedisct1/libhydrogen/graphs/contributors"><img src="https://opencollective.com/libhydrogen/contributors.svg?width=890&button=false" /></a>
|
|
||||||
@ -1,32 +0,0 @@
|
|||||||
const std = @import("std");
|
|
||||||
|
|
||||||
pub fn build(b: *std.Build) void {
|
|
||||||
const target = b.standardTargetOptions(.{});
|
|
||||||
const optimize = b.standardOptimizeOption(.{ .preferred_optimize_mode = .ReleaseSmall });
|
|
||||||
|
|
||||||
const mod = b.createModule(.{
|
|
||||||
.target = target,
|
|
||||||
.optimize = optimize,
|
|
||||||
.link_libc = true,
|
|
||||||
.strip = true,
|
|
||||||
});
|
|
||||||
|
|
||||||
mod.addCSourceFile(.{
|
|
||||||
.file = b.path("hydrogen.c"),
|
|
||||||
});
|
|
||||||
|
|
||||||
const lib = b.addLibrary(.{
|
|
||||||
.name = "hydrogen",
|
|
||||||
.linkage = .static,
|
|
||||||
.root_module = mod,
|
|
||||||
});
|
|
||||||
|
|
||||||
b.installArtifact(lib);
|
|
||||||
|
|
||||||
_ = b.addModule("libhydrogen", .{
|
|
||||||
.root_source_file = b.path("hydrogen.c"),
|
|
||||||
.target = target,
|
|
||||||
.optimize = optimize,
|
|
||||||
.link_libc = true,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
@ -1,13 +0,0 @@
|
|||||||
.{
|
|
||||||
.name = .libhydrogen,
|
|
||||||
.version = "1.0.0",
|
|
||||||
.fingerprint = 0x98fa0ad39dcdc390,
|
|
||||||
|
|
||||||
.paths = .{
|
|
||||||
"build.zig",
|
|
||||||
"build.zig.zon",
|
|
||||||
"hydrogen.c",
|
|
||||||
"hydrogen.h",
|
|
||||||
"impl",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
@ -1,127 +0,0 @@
|
|||||||
# Cross-compilation file for the Arduino/AVR toolchain.
|
|
||||||
|
|
||||||
# To use, pass -DCMAKE_TOOLCHAIN_FILE=cmake/arduino-avr-toolchain.cmake in your CMake command line.
|
|
||||||
# You can specify the target device MCU identifier with -DHYDROGEN_ARDUINO_AVR_TARGET_DEVICE=XXX.
|
|
||||||
|
|
||||||
cmake_minimum_required(VERSION 3.12)
|
|
||||||
|
|
||||||
set(project_setting_prefix HYDROGEN)
|
|
||||||
function(set_project_setting setting_name setting_value)
|
|
||||||
set("${project_setting_prefix}_${setting_name}" "${setting_value}" CACHE INTERNAL "")
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
set(setting_prefix "${project_setting_prefix}_ARDUINO_AVR")
|
|
||||||
function(get_setting setting_name setting_type setting_description)
|
|
||||||
string(TOUPPER "${setting_prefix}_${setting_name}" setting_external_name)
|
|
||||||
set("${setting_external_name}" "" CACHE "${setting_type}" "${setting_description}")
|
|
||||||
set("${setting_name}" "${${setting_external_name}}" PARENT_SCOPE)
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
# Target device setting
|
|
||||||
|
|
||||||
get_setting(target_device STRING "Target Arduino device MCU identifier.")
|
|
||||||
if(NOT target_device)
|
|
||||||
set(target_device atmega328p)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if("${target_device}" STREQUAL atmega328p)
|
|
||||||
set_project_setting(TARGET_DEVICE ATMEGA328)
|
|
||||||
else()
|
|
||||||
message(FATAL_ERROR "Unrecognized ${setting_prefix}_TARGET_DEVICE value ${target_device}")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Find Arduino SDK home
|
|
||||||
|
|
||||||
get_setting(sdk_dir PATH "Arduino SDK home directory.")
|
|
||||||
|
|
||||||
# Try ARDUINO_SDK_PATH environment variable.
|
|
||||||
if(NOT sdk_dir)
|
|
||||||
if(DEFINED ENV{ARDUINO_SDK_PATH})
|
|
||||||
set(sdk_dir "$ENV{ARDUINO_SDK_PATH}")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Try some platform-specific guesses.
|
|
||||||
if(NOT sdk_dir)
|
|
||||||
# Windows
|
|
||||||
if(WIN32)
|
|
||||||
list(APPEND arduino_home_dir_guesses "C:/Program Files (x86)/Arduino"
|
|
||||||
"C:/Program Files/Arduino")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# macOS
|
|
||||||
if(APPLE)
|
|
||||||
list(APPEND arduino_home_dir_guesses "/Applications/Arduino.app/Contents/Java")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Linux/Unix
|
|
||||||
if(UNIX AND NOT APPLE)
|
|
||||||
list(APPEND arduino_home_dir_guesses "/usr/share/arduino" "/usr/local/share/arduino")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(DEFINED arduino_home_dir_guesses)
|
|
||||||
foreach(arduino_home_dir_guess IN LISTS arduino_home_dir_guesses)
|
|
||||||
if(IS_DIRECTORY "${arduino_home_dir_guess}")
|
|
||||||
set(sdk_dir "${arduino_home_dir_guess}")
|
|
||||||
break()
|
|
||||||
endif()
|
|
||||||
endforeach()
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(NOT sdk_dir)
|
|
||||||
message(FATAL_ERROR "Couldn't determine Arduino SDK home directory. "
|
|
||||||
"Try passing -D${setting_prefix}_SDK_DIR=... to the CMake command line, or "
|
|
||||||
"set the ARDUINO_SDK_PATH environment variable.")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Locate toolchain programs
|
|
||||||
|
|
||||||
set(arduino_tools_dir "${sdk_dir}/hardware/tools/avr/bin")
|
|
||||||
set(program_prefix "${setting_prefix}_PROGRAM")
|
|
||||||
function(find_in_toolchain program_name)
|
|
||||||
string(TOUPPER "${program_prefix}_${program_name}" program_external_name)
|
|
||||||
string(REPLACE "_" "-" program_file_name "${program_name}")
|
|
||||||
|
|
||||||
find_program("${program_external_name}" "${program_file_name}"
|
|
||||||
PATHS "${arduino_tools_dir}"
|
|
||||||
NO_DEFAULT_PATH)
|
|
||||||
|
|
||||||
if("${${program_external_name}}" STREQUAL "${program_external_name}-NOTFOUND")
|
|
||||||
message(FATAL_ERROR "Couldn't find program ${program_file_name} "
|
|
||||||
"in Arduino/AVR toolchain at ${arduino_tools_dir}")
|
|
||||||
else()
|
|
||||||
set("${program_name}" "${${program_external_name}}" PARENT_SCOPE)
|
|
||||||
endif()
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
find_in_toolchain(avr_gcc)
|
|
||||||
find_in_toolchain(avr_gcc_ranlib)
|
|
||||||
find_in_toolchain(avr_gcc_ar)
|
|
||||||
find_in_toolchain(avr_gcc_nm)
|
|
||||||
find_in_toolchain(avr_strip)
|
|
||||||
|
|
||||||
# Configure CMake toolchain settings
|
|
||||||
|
|
||||||
set(CMAKE_SYSTEM_NAME Generic)
|
|
||||||
set(CMAKE_C_COMPILER "${avr_gcc}")
|
|
||||||
set(CMAKE_ASM_COMPILER "${avr_gcc}")
|
|
||||||
set(CMAKE_RANLIB "${avr_gcc_ranlib}")
|
|
||||||
set(CMAKE_AR "${avr_gcc_ar}")
|
|
||||||
set(CMAKE_NM "${avr_gcc_nm}")
|
|
||||||
set(CMAKE_STRIP "${avr_strip}")
|
|
||||||
|
|
||||||
set(CMAKE_C_OUTPUT_EXTENSION .o)
|
|
||||||
set(CMAKE_ASM_OUTPUT_EXTENSION .o)
|
|
||||||
|
|
||||||
# Set compile flags
|
|
||||||
|
|
||||||
string(CONCAT CMAKE_C_FLAGS " -mmcu=${target_device} -mcall-prologues -fno-exceptions"
|
|
||||||
" -ffunction-sections -fdata-sections -flto")
|
|
||||||
|
|
||||||
# Add include directories
|
|
||||||
|
|
||||||
include_directories(SYSTEM "${sdk_dir}/hardware/arduino/avr/cores/arduino"
|
|
||||||
"${sdk_dir}/hardware/arduino/avr/variants/standard"
|
|
||||||
"${sdk_dir}/hardware/arduino/cores/arduino"
|
|
||||||
"${sdk_dir}/hardware/arduino/variants/standard")
|
|
||||||
@ -1,7 +0,0 @@
|
|||||||
get_filename_component(hydrogen_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
|
|
||||||
|
|
||||||
if(NOT TARGET hydrogen::hydrogen)
|
|
||||||
include("${hydrogen_CMAKE_DIR}/hydrogen-targets.cmake")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(hydrogen_LIBRARIES hydrogen::hydrogen)
|
|
||||||
@ -1,58 +0,0 @@
|
|||||||
# Cross-compilation file for WebAssembly with WASI.
|
|
||||||
|
|
||||||
# To use, pass -DCMAKE_TOOLCHAIN_FILE=cmake/wasm32-wasi-toolchain.cmake in your CMake command line.
|
|
||||||
# You'll also need to specify a sysroot directory with -DHYDROGEN_WASM32_WASI_SYSROOT_DIR=XXX.
|
|
||||||
|
|
||||||
cmake_minimum_required(VERSION 3.12)
|
|
||||||
|
|
||||||
set(project_setting_prefix HYDROGEN)
|
|
||||||
set(setting_prefix "${project_setting_prefix}_WASM32_WASI")
|
|
||||||
function(get_setting setting_name setting_type setting_description)
|
|
||||||
string(TOUPPER "${setting_prefix}_${setting_name}" setting_external_name)
|
|
||||||
set("${setting_external_name}" "" CACHE "${setting_type}" "${setting_description}")
|
|
||||||
set("${setting_name}" "${${setting_external_name}}" PARENT_SCOPE)
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
# Sysroot setting
|
|
||||||
|
|
||||||
get_setting(sysroot_dir STRING "Directory containing the wasm32-wasi sysroot.")
|
|
||||||
|
|
||||||
# Locate toolchain programs
|
|
||||||
|
|
||||||
set(program_prefix "${setting_prefix}_PROGRAM")
|
|
||||||
function(find_in_toolchain program_name)
|
|
||||||
string(TOUPPER "${program_prefix}_${program_name}" program_external_name)
|
|
||||||
string(REPLACE "_" "-" program_file_name "${program_name}")
|
|
||||||
|
|
||||||
find_program("${program_external_name}" "${program_file_name}")
|
|
||||||
|
|
||||||
if("${${program_external_name}}" STREQUAL "${program_external_name}-NOTFOUND")
|
|
||||||
message(FATAL_ERROR "Couldn't find toolchain program ${program_file_name}")
|
|
||||||
else()
|
|
||||||
set("${program_name}" "${${program_external_name}}" PARENT_SCOPE)
|
|
||||||
endif()
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
find_in_toolchain(clang)
|
|
||||||
find_in_toolchain(llvm_ranlib)
|
|
||||||
find_in_toolchain(llvm_ar)
|
|
||||||
find_in_toolchain(llvm_nm)
|
|
||||||
find_in_toolchain(llvm_strip)
|
|
||||||
|
|
||||||
# Configure CMake toolchain settings
|
|
||||||
|
|
||||||
set(CMAKE_SYSTEM_NAME Generic)
|
|
||||||
set(CMAKE_C_COMPILER "${clang}")
|
|
||||||
set(CMAKE_ASM_COMPILER "${clang}")
|
|
||||||
set(CMAKE_RANLIB "${llvm_ranlib}")
|
|
||||||
set(CMAKE_AR "${llvm_ar}")
|
|
||||||
set(CMAKE_NM "${llvm_nm}")
|
|
||||||
set(CMAKE_STRIP "${llvm_strip}")
|
|
||||||
|
|
||||||
set(CMAKE_C_OUTPUT_EXTENSION .o)
|
|
||||||
set(CMAKE_ASM_OUTPUT_EXTENSION .o)
|
|
||||||
|
|
||||||
# Set compile flags
|
|
||||||
|
|
||||||
string(CONCAT CMAKE_C_FLAGS " -DED25519_NONDETERMINISTIC=1 --target=wasm32-wasi"
|
|
||||||
" --sysroot=${sysroot_dir} -Wl,--stack-first")
|
|
||||||
@ -1,19 +0,0 @@
|
|||||||
#include "hydrogen.h"
|
|
||||||
|
|
||||||
#include "impl/common.h"
|
|
||||||
#include "impl/hydrogen_p.h"
|
|
||||||
|
|
||||||
#include "impl/random.h"
|
|
||||||
|
|
||||||
#include "impl/core.h"
|
|
||||||
#include "impl/gimli-core.h"
|
|
||||||
|
|
||||||
#include "impl/hash.h"
|
|
||||||
#include "impl/kdf.h"
|
|
||||||
#include "impl/secretbox.h"
|
|
||||||
|
|
||||||
#include "impl/x25519.h"
|
|
||||||
|
|
||||||
#include "impl/kx.h"
|
|
||||||
#include "impl/pwhash.h"
|
|
||||||
#include "impl/sign.h"
|
|
||||||
@ -1,337 +0,0 @@
|
|||||||
#ifndef hydrogen_H
|
|
||||||
#define hydrogen_H
|
|
||||||
|
|
||||||
#if !(defined(__linux__) && defined(__KERNEL__))
|
|
||||||
# include <stdbool.h>
|
|
||||||
# include <stdint.h>
|
|
||||||
# include <stdlib.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(__cplusplus) && defined(__GNUC__)
|
|
||||||
# pragma GCC diagnostic ignored "-Wdeclaration-after-statement"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
# ifdef __GNUC__
|
|
||||||
# pragma GCC diagnostic ignored "-Wlong-long"
|
|
||||||
# endif
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__clang__) || defined(__GNUC__)
|
|
||||||
# define _hydro_attr_(X) __attribute__(X)
|
|
||||||
#else
|
|
||||||
# define _hydro_attr_(X)
|
|
||||||
#endif
|
|
||||||
#define _hydro_attr_deprecated_ _hydro_attr_((deprecated))
|
|
||||||
#define _hydro_attr_malloc_ _hydro_attr_((malloc))
|
|
||||||
#define _hydro_attr_noinline_ _hydro_attr_((noinline))
|
|
||||||
#define _hydro_attr_noreturn_ _hydro_attr_((noreturn))
|
|
||||||
#define _hydro_attr_warn_unused_result_ _hydro_attr_((warn_unused_result))
|
|
||||||
#define _hydro_attr_weak_ _hydro_attr_((weak))
|
|
||||||
|
|
||||||
#if defined(__INTEL_COMPILER) || defined(_MSC_VER)
|
|
||||||
# define _hydro_attr_aligned_(X) __declspec(align(X))
|
|
||||||
#elif defined(__clang__) || defined(__GNUC__)
|
|
||||||
# define _hydro_attr_aligned_(X) _hydro_attr_((aligned(X)))
|
|
||||||
#else
|
|
||||||
# define _hydro_attr_aligned_(X)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define HYDRO_VERSION_MAJOR 1
|
|
||||||
#define HYDRO_VERSION_MINOR 0
|
|
||||||
|
|
||||||
int hydro_init(void);
|
|
||||||
|
|
||||||
/* ---------------- */
|
|
||||||
|
|
||||||
#define hydro_random_SEEDBYTES 32
|
|
||||||
|
|
||||||
uint32_t hydro_random_u32(void);
|
|
||||||
|
|
||||||
uint32_t hydro_random_uniform(const uint32_t upper_bound);
|
|
||||||
|
|
||||||
void hydro_random_buf(void *out, size_t out_len);
|
|
||||||
|
|
||||||
void hydro_random_buf_deterministic(void *out, size_t out_len,
|
|
||||||
const uint8_t seed[hydro_random_SEEDBYTES]);
|
|
||||||
|
|
||||||
void hydro_random_ratchet(void);
|
|
||||||
|
|
||||||
void hydro_random_reseed(void);
|
|
||||||
|
|
||||||
/* ---------------- */
|
|
||||||
|
|
||||||
#define hydro_hash_BYTES 32
|
|
||||||
#define hydro_hash_BYTES_MAX 65535
|
|
||||||
#define hydro_hash_BYTES_MIN 16
|
|
||||||
#define hydro_hash_CONTEXTBYTES 8
|
|
||||||
#define hydro_hash_KEYBYTES 32
|
|
||||||
|
|
||||||
typedef struct hydro_hash_state {
|
|
||||||
uint32_t state[12];
|
|
||||||
uint8_t buf_off;
|
|
||||||
uint8_t align[3];
|
|
||||||
} hydro_hash_state;
|
|
||||||
|
|
||||||
void hydro_hash_keygen(uint8_t key[hydro_hash_KEYBYTES]);
|
|
||||||
|
|
||||||
int hydro_hash_init(hydro_hash_state *state, const char ctx[hydro_hash_CONTEXTBYTES],
|
|
||||||
const uint8_t key[hydro_hash_KEYBYTES]);
|
|
||||||
|
|
||||||
int hydro_hash_update(hydro_hash_state *state, const void *in_, size_t in_len);
|
|
||||||
|
|
||||||
int hydro_hash_final(hydro_hash_state *state, uint8_t *out, size_t out_len);
|
|
||||||
|
|
||||||
int hydro_hash_hash(uint8_t *out, size_t out_len, const void *in_, size_t in_len,
|
|
||||||
const char ctx[hydro_hash_CONTEXTBYTES],
|
|
||||||
const uint8_t key[hydro_hash_KEYBYTES]);
|
|
||||||
|
|
||||||
/* ---------------- */
|
|
||||||
|
|
||||||
#define hydro_secretbox_CONTEXTBYTES 8
|
|
||||||
#define hydro_secretbox_HEADERBYTES (20 + 16)
|
|
||||||
#define hydro_secretbox_KEYBYTES 32
|
|
||||||
#define hydro_secretbox_PROBEBYTES 16
|
|
||||||
|
|
||||||
void hydro_secretbox_keygen(uint8_t key[hydro_secretbox_KEYBYTES]);
|
|
||||||
|
|
||||||
int hydro_secretbox_encrypt(uint8_t *c, const void *m_, size_t mlen, uint64_t msg_id,
|
|
||||||
const char ctx[hydro_secretbox_CONTEXTBYTES],
|
|
||||||
const uint8_t key[hydro_secretbox_KEYBYTES]);
|
|
||||||
|
|
||||||
int hydro_secretbox_decrypt(void *m_, const uint8_t *c, size_t clen, uint64_t msg_id,
|
|
||||||
const char ctx[hydro_secretbox_CONTEXTBYTES],
|
|
||||||
const uint8_t key[hydro_secretbox_KEYBYTES])
|
|
||||||
_hydro_attr_warn_unused_result_;
|
|
||||||
|
|
||||||
void hydro_secretbox_probe_create(uint8_t probe[hydro_secretbox_PROBEBYTES], const uint8_t *c,
|
|
||||||
size_t c_len, const char ctx[hydro_secretbox_CONTEXTBYTES],
|
|
||||||
const uint8_t key[hydro_secretbox_KEYBYTES]);
|
|
||||||
|
|
||||||
int hydro_secretbox_probe_verify(const uint8_t probe[hydro_secretbox_PROBEBYTES], const uint8_t *c,
|
|
||||||
size_t c_len, const char ctx[hydro_secretbox_CONTEXTBYTES],
|
|
||||||
const uint8_t key[hydro_secretbox_KEYBYTES])
|
|
||||||
_hydro_attr_warn_unused_result_;
|
|
||||||
|
|
||||||
/* ---------------- */
|
|
||||||
|
|
||||||
#define hydro_kdf_CONTEXTBYTES 8
|
|
||||||
#define hydro_kdf_KEYBYTES 32
|
|
||||||
#define hydro_kdf_BYTES_MAX 65535
|
|
||||||
#define hydro_kdf_BYTES_MIN 16
|
|
||||||
|
|
||||||
void hydro_kdf_keygen(uint8_t key[hydro_kdf_KEYBYTES]);
|
|
||||||
|
|
||||||
int hydro_kdf_derive_from_key(uint8_t *subkey, size_t subkey_len, uint64_t subkey_id,
|
|
||||||
const char ctx[hydro_kdf_CONTEXTBYTES],
|
|
||||||
const uint8_t key[hydro_kdf_KEYBYTES]);
|
|
||||||
|
|
||||||
/* ---------------- */
|
|
||||||
|
|
||||||
#define hydro_sign_BYTES 64
|
|
||||||
#define hydro_sign_CONTEXTBYTES 8
|
|
||||||
#define hydro_sign_PUBLICKEYBYTES 32
|
|
||||||
#define hydro_sign_SECRETKEYBYTES 64
|
|
||||||
#define hydro_sign_SEEDBYTES 32
|
|
||||||
|
|
||||||
typedef struct hydro_sign_state {
|
|
||||||
hydro_hash_state hash_st;
|
|
||||||
} hydro_sign_state;
|
|
||||||
|
|
||||||
typedef struct hydro_sign_keypair {
|
|
||||||
uint8_t pk[hydro_sign_PUBLICKEYBYTES];
|
|
||||||
uint8_t sk[hydro_sign_SECRETKEYBYTES];
|
|
||||||
} hydro_sign_keypair;
|
|
||||||
|
|
||||||
void hydro_sign_keygen(hydro_sign_keypair *kp);
|
|
||||||
|
|
||||||
void hydro_sign_keygen_deterministic(hydro_sign_keypair *kp,
|
|
||||||
const uint8_t seed[hydro_sign_SEEDBYTES]);
|
|
||||||
|
|
||||||
int hydro_sign_init(hydro_sign_state *state, const char ctx[hydro_sign_CONTEXTBYTES]);
|
|
||||||
|
|
||||||
int hydro_sign_update(hydro_sign_state *state, const void *m_, size_t mlen);
|
|
||||||
|
|
||||||
int hydro_sign_final_create(hydro_sign_state *state, uint8_t csig[hydro_sign_BYTES],
|
|
||||||
const uint8_t sk[hydro_sign_SECRETKEYBYTES]);
|
|
||||||
|
|
||||||
int hydro_sign_final_verify(hydro_sign_state *state, const uint8_t csig[hydro_sign_BYTES],
|
|
||||||
const uint8_t pk[hydro_sign_PUBLICKEYBYTES])
|
|
||||||
_hydro_attr_warn_unused_result_;
|
|
||||||
|
|
||||||
int hydro_sign_create(uint8_t csig[hydro_sign_BYTES], const void *m_, size_t mlen,
|
|
||||||
const char ctx[hydro_sign_CONTEXTBYTES],
|
|
||||||
const uint8_t sk[hydro_sign_SECRETKEYBYTES]);
|
|
||||||
|
|
||||||
int hydro_sign_verify(const uint8_t csig[hydro_sign_BYTES], const void *m_, size_t mlen,
|
|
||||||
const char ctx[hydro_sign_CONTEXTBYTES],
|
|
||||||
const uint8_t pk[hydro_sign_PUBLICKEYBYTES]) _hydro_attr_warn_unused_result_;
|
|
||||||
|
|
||||||
/* ---------------- */
|
|
||||||
|
|
||||||
#define hydro_kx_SESSIONKEYBYTES 32
|
|
||||||
#define hydro_kx_PUBLICKEYBYTES 32
|
|
||||||
#define hydro_kx_SECRETKEYBYTES 32
|
|
||||||
#define hydro_kx_PSKBYTES 32
|
|
||||||
#define hydro_kx_SEEDBYTES 32
|
|
||||||
|
|
||||||
typedef struct hydro_kx_keypair {
|
|
||||||
uint8_t pk[hydro_kx_PUBLICKEYBYTES];
|
|
||||||
uint8_t sk[hydro_kx_SECRETKEYBYTES];
|
|
||||||
} hydro_kx_keypair;
|
|
||||||
|
|
||||||
typedef struct hydro_kx_session_keypair {
|
|
||||||
uint8_t rx[hydro_kx_SESSIONKEYBYTES];
|
|
||||||
uint8_t tx[hydro_kx_SESSIONKEYBYTES];
|
|
||||||
} hydro_kx_session_keypair;
|
|
||||||
|
|
||||||
typedef struct hydro_kx_state {
|
|
||||||
hydro_kx_keypair eph_kp;
|
|
||||||
hydro_hash_state h_st;
|
|
||||||
} hydro_kx_state;
|
|
||||||
|
|
||||||
void hydro_kx_keygen(hydro_kx_keypair *static_kp);
|
|
||||||
|
|
||||||
void hydro_kx_keygen_deterministic(hydro_kx_keypair *static_kp,
|
|
||||||
const uint8_t seed[hydro_kx_SEEDBYTES]);
|
|
||||||
|
|
||||||
/* NOISE_N */
|
|
||||||
|
|
||||||
#define hydro_kx_N_PACKET1BYTES (32 + 16)
|
|
||||||
|
|
||||||
int hydro_kx_n_1(hydro_kx_session_keypair *kp, uint8_t packet1[hydro_kx_N_PACKET1BYTES],
|
|
||||||
const uint8_t psk[hydro_kx_PSKBYTES],
|
|
||||||
const uint8_t peer_static_pk[hydro_kx_PUBLICKEYBYTES]);
|
|
||||||
|
|
||||||
int hydro_kx_n_2(hydro_kx_session_keypair *kp, const uint8_t packet1[hydro_kx_N_PACKET1BYTES],
|
|
||||||
const uint8_t psk[hydro_kx_PSKBYTES], const hydro_kx_keypair *static_kp);
|
|
||||||
|
|
||||||
/* NOISE_KK */
|
|
||||||
|
|
||||||
#define hydro_kx_KK_PACKET1BYTES (32 + 16)
|
|
||||||
#define hydro_kx_KK_PACKET2BYTES (32 + 16)
|
|
||||||
|
|
||||||
int hydro_kx_kk_1(hydro_kx_state *state, uint8_t packet1[hydro_kx_KK_PACKET1BYTES],
|
|
||||||
const uint8_t peer_static_pk[hydro_kx_PUBLICKEYBYTES],
|
|
||||||
const hydro_kx_keypair *static_kp);
|
|
||||||
|
|
||||||
int hydro_kx_kk_2(hydro_kx_session_keypair *kp, uint8_t packet2[hydro_kx_KK_PACKET2BYTES],
|
|
||||||
const uint8_t packet1[hydro_kx_KK_PACKET1BYTES],
|
|
||||||
const uint8_t peer_static_pk[hydro_kx_PUBLICKEYBYTES],
|
|
||||||
const hydro_kx_keypair *static_kp);
|
|
||||||
|
|
||||||
int hydro_kx_kk_3(hydro_kx_state *state, hydro_kx_session_keypair *kp,
|
|
||||||
const uint8_t packet2[hydro_kx_KK_PACKET2BYTES],
|
|
||||||
const hydro_kx_keypair *static_kp);
|
|
||||||
|
|
||||||
/* NOISE_XX */
|
|
||||||
|
|
||||||
#define hydro_kx_XX_PACKET1BYTES (32 + 16)
|
|
||||||
#define hydro_kx_XX_PACKET2BYTES (32 + 32 + 16 + 16)
|
|
||||||
#define hydro_kx_XX_PACKET3BYTES (32 + 16 + 16)
|
|
||||||
|
|
||||||
int hydro_kx_xx_1(hydro_kx_state *state, uint8_t packet1[hydro_kx_XX_PACKET1BYTES],
|
|
||||||
const uint8_t psk[hydro_kx_PSKBYTES]);
|
|
||||||
|
|
||||||
int hydro_kx_xx_2(hydro_kx_state *state, uint8_t packet2[hydro_kx_XX_PACKET2BYTES],
|
|
||||||
const uint8_t packet1[hydro_kx_XX_PACKET1BYTES],
|
|
||||||
const uint8_t psk[hydro_kx_PSKBYTES], const hydro_kx_keypair *static_kp);
|
|
||||||
|
|
||||||
int hydro_kx_xx_3(hydro_kx_state *state, hydro_kx_session_keypair *kp,
|
|
||||||
uint8_t packet3[hydro_kx_XX_PACKET3BYTES],
|
|
||||||
uint8_t peer_static_pk[hydro_kx_PUBLICKEYBYTES],
|
|
||||||
const uint8_t packet2[hydro_kx_XX_PACKET2BYTES],
|
|
||||||
const uint8_t psk[hydro_kx_PSKBYTES], const hydro_kx_keypair *static_kp);
|
|
||||||
|
|
||||||
int hydro_kx_xx_4(hydro_kx_state *state, hydro_kx_session_keypair *kp,
|
|
||||||
uint8_t peer_static_pk[hydro_kx_PUBLICKEYBYTES],
|
|
||||||
const uint8_t packet3[hydro_kx_XX_PACKET3BYTES],
|
|
||||||
const uint8_t psk[hydro_kx_PSKBYTES]);
|
|
||||||
|
|
||||||
/* NOISE_NK */
|
|
||||||
|
|
||||||
#define hydro_kx_NK_PACKET1BYTES (32 + 16)
|
|
||||||
#define hydro_kx_NK_PACKET2BYTES (32 + 16)
|
|
||||||
|
|
||||||
int hydro_kx_nk_1(hydro_kx_state *state, uint8_t packet1[hydro_kx_NK_PACKET1BYTES],
|
|
||||||
const uint8_t psk[hydro_kx_PSKBYTES],
|
|
||||||
const uint8_t peer_static_pk[hydro_kx_PUBLICKEYBYTES]);
|
|
||||||
|
|
||||||
int hydro_kx_nk_2(hydro_kx_session_keypair *kp, uint8_t packet2[hydro_kx_NK_PACKET2BYTES],
|
|
||||||
const uint8_t packet1[hydro_kx_NK_PACKET1BYTES],
|
|
||||||
const uint8_t psk[hydro_kx_PSKBYTES], const hydro_kx_keypair *static_kp);
|
|
||||||
|
|
||||||
int hydro_kx_nk_3(hydro_kx_state *state, hydro_kx_session_keypair *kp,
|
|
||||||
const uint8_t packet2[hydro_kx_NK_PACKET2BYTES]);
|
|
||||||
|
|
||||||
/* ---------------- */
|
|
||||||
|
|
||||||
#define hydro_pwhash_CONTEXTBYTES 8
|
|
||||||
#define hydro_pwhash_MASTERKEYBYTES 32
|
|
||||||
#define hydro_pwhash_STOREDBYTES 128
|
|
||||||
|
|
||||||
void hydro_pwhash_keygen(uint8_t master_key[hydro_pwhash_MASTERKEYBYTES]);
|
|
||||||
|
|
||||||
int hydro_pwhash_deterministic(uint8_t *h, size_t h_len, const char *passwd, size_t passwd_len,
|
|
||||||
const char ctx[hydro_pwhash_CONTEXTBYTES],
|
|
||||||
const uint8_t master_key[hydro_pwhash_MASTERKEYBYTES],
|
|
||||||
uint64_t opslimit, size_t memlimit, uint8_t threads);
|
|
||||||
|
|
||||||
int hydro_pwhash_create(uint8_t stored[hydro_pwhash_STOREDBYTES], const char *passwd,
|
|
||||||
size_t passwd_len, const uint8_t master_key[hydro_pwhash_MASTERKEYBYTES],
|
|
||||||
uint64_t opslimit, size_t memlimit, uint8_t threads);
|
|
||||||
|
|
||||||
int hydro_pwhash_verify(const uint8_t stored[hydro_pwhash_STOREDBYTES], const char *passwd,
|
|
||||||
size_t passwd_len, const uint8_t master_key[hydro_pwhash_MASTERKEYBYTES],
|
|
||||||
uint64_t opslimit_max, size_t memlimit_max, uint8_t threads_max);
|
|
||||||
|
|
||||||
int hydro_pwhash_derive_static_key(uint8_t *static_key, size_t static_key_len,
|
|
||||||
const uint8_t stored[hydro_pwhash_STOREDBYTES],
|
|
||||||
const char *passwd, size_t passwd_len,
|
|
||||||
const char ctx[hydro_pwhash_CONTEXTBYTES],
|
|
||||||
const uint8_t master_key[hydro_pwhash_MASTERKEYBYTES],
|
|
||||||
uint64_t opslimit_max, size_t memlimit_max, uint8_t threads_max);
|
|
||||||
|
|
||||||
int hydro_pwhash_reencrypt(uint8_t stored[hydro_pwhash_STOREDBYTES],
|
|
||||||
const uint8_t master_key[hydro_pwhash_MASTERKEYBYTES],
|
|
||||||
const uint8_t new_master_key[hydro_pwhash_MASTERKEYBYTES]);
|
|
||||||
|
|
||||||
int hydro_pwhash_upgrade(uint8_t stored[hydro_pwhash_STOREDBYTES],
|
|
||||||
const uint8_t master_key[hydro_pwhash_MASTERKEYBYTES], uint64_t opslimit,
|
|
||||||
size_t memlimit, uint8_t threads);
|
|
||||||
|
|
||||||
/* ---------------- */
|
|
||||||
|
|
||||||
void hydro_memzero(void *pnt, size_t len);
|
|
||||||
|
|
||||||
void hydro_increment(uint8_t *n, size_t len);
|
|
||||||
|
|
||||||
bool hydro_equal(const void *b1_, const void *b2_, size_t len);
|
|
||||||
|
|
||||||
int hydro_compare(const uint8_t *b1_, const uint8_t *b2_, size_t len);
|
|
||||||
|
|
||||||
char *hydro_bin2hex(char *hex, size_t hex_maxlen, const uint8_t *bin, size_t bin_len);
|
|
||||||
|
|
||||||
int hydro_hex2bin(uint8_t *bin, size_t bin_maxlen, const char *hex, size_t hex_len,
|
|
||||||
const char *ignore, const char **hex_end_p);
|
|
||||||
|
|
||||||
int hydro_pad(unsigned char *buf, size_t unpadded_buflen, size_t blocksize, size_t max_buflen);
|
|
||||||
|
|
||||||
int hydro_unpad(const unsigned char *buf, size_t padded_buflen, size_t blocksize);
|
|
||||||
|
|
||||||
/* ---------------- */
|
|
||||||
|
|
||||||
#define HYDRO_HWTYPE_ATMEGA328 1
|
|
||||||
|
|
||||||
#ifndef HYDRO_HWTYPE
|
|
||||||
# ifdef __AVR__
|
|
||||||
# define HYDRO_HWTYPE HYDRO_HWTYPE_ATMEGA328
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,334 +0,0 @@
|
|||||||
#if defined(__linux__) && defined(__KERNEL__)
|
|
||||||
# define TLS /* Danger: at most one call into hydro_*() at a time */
|
|
||||||
# define CHAR_BIT 8
|
|
||||||
# define abort BUG
|
|
||||||
# define uint_fast16_t uint16_t
|
|
||||||
# define errno hydro_errno
|
|
||||||
static int errno;
|
|
||||||
#else
|
|
||||||
# include <errno.h>
|
|
||||||
# include <limits.h>
|
|
||||||
# include <stdbool.h>
|
|
||||||
# include <stdint.h>
|
|
||||||
# include <stdlib.h>
|
|
||||||
# include <string.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined (__CHERIOT__)
|
|
||||||
static int errno;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(__unix__) && (defined(__APPLE__) || defined(__linux__))
|
|
||||||
# define __unix__ 1
|
|
||||||
#endif
|
|
||||||
#ifndef __GNUC__
|
|
||||||
# define __restrict__
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && \
|
|
||||||
__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
|
||||||
# define NATIVE_BIG_ENDIAN
|
|
||||||
#endif
|
|
||||||
#ifndef NATIVE_BIG_ENDIAN
|
|
||||||
# ifndef NATIVE_LITTLE_ENDIAN
|
|
||||||
# define NATIVE_LITTLE_ENDIAN
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef TLS
|
|
||||||
# if defined(_WIN32) && !defined(__GNUC__)
|
|
||||||
# define TLS __declspec(thread)
|
|
||||||
# elif (defined(__clang__) || defined(__GNUC__)) && defined(__unix__) && !defined(__TINYC__)
|
|
||||||
# define TLS __thread
|
|
||||||
# else
|
|
||||||
# define TLS
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef SIZE_MAX
|
|
||||||
# define SIZE_MAX ((size_t) -1)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __OpenBSD__
|
|
||||||
# define HAVE_EXPLICIT_BZERO 1
|
|
||||||
#elif defined(__GLIBC__) && defined(__GLIBC_PREREQ) && defined(_GNU_SOURCE)
|
|
||||||
# if __GLIBC_PREREQ(2, 25)
|
|
||||||
# define HAVE_EXPLICIT_BZERO 1
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define COMPILER_ASSERT(X) (void) sizeof(char[(X) ? 1 : -1])
|
|
||||||
|
|
||||||
#define ROTL32(x, b) (uint32_t)(((x) << (b)) | ((x) >> (32 - (b))))
|
|
||||||
#define ROTL64(x, b) (uint64_t)(((x) << (b)) | ((x) >> (64 - (b))))
|
|
||||||
#define ROTR32(x, b) (uint32_t)(((x) >> (b)) | ((x) << (32 - (b))))
|
|
||||||
#define ROTR64(x, b) (uint64_t)(((x) >> (b)) | ((x) << (64 - (b))))
|
|
||||||
|
|
||||||
#define LOAD64_LE(SRC) load64_le(SRC)
|
|
||||||
static inline uint64_t
|
|
||||||
load64_le(const uint8_t src[8])
|
|
||||||
{
|
|
||||||
#ifdef NATIVE_LITTLE_ENDIAN
|
|
||||||
uint64_t w;
|
|
||||||
memcpy(&w, src, sizeof w);
|
|
||||||
return w;
|
|
||||||
#else
|
|
||||||
uint64_t w = (uint64_t) src[0];
|
|
||||||
w |= (uint64_t) src[1] << 8;
|
|
||||||
w |= (uint64_t) src[2] << 16;
|
|
||||||
w |= (uint64_t) src[3] << 24;
|
|
||||||
w |= (uint64_t) src[4] << 32;
|
|
||||||
w |= (uint64_t) src[5] << 40;
|
|
||||||
w |= (uint64_t) src[6] << 48;
|
|
||||||
w |= (uint64_t) src[7] << 56;
|
|
||||||
return w;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#define STORE64_LE(DST, W) store64_le((DST), (W))
|
|
||||||
static inline void
|
|
||||||
store64_le(uint8_t dst[8], uint64_t w)
|
|
||||||
{
|
|
||||||
#ifdef NATIVE_LITTLE_ENDIAN
|
|
||||||
memcpy(dst, &w, sizeof w);
|
|
||||||
#else
|
|
||||||
dst[0] = (uint8_t) w;
|
|
||||||
w >>= 8;
|
|
||||||
dst[1] = (uint8_t) w;
|
|
||||||
w >>= 8;
|
|
||||||
dst[2] = (uint8_t) w;
|
|
||||||
w >>= 8;
|
|
||||||
dst[3] = (uint8_t) w;
|
|
||||||
w >>= 8;
|
|
||||||
dst[4] = (uint8_t) w;
|
|
||||||
w >>= 8;
|
|
||||||
dst[5] = (uint8_t) w;
|
|
||||||
w >>= 8;
|
|
||||||
dst[6] = (uint8_t) w;
|
|
||||||
w >>= 8;
|
|
||||||
dst[7] = (uint8_t) w;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#define LOAD32_LE(SRC) load32_le(SRC)
|
|
||||||
static inline uint32_t
|
|
||||||
load32_le(const uint8_t src[4])
|
|
||||||
{
|
|
||||||
#ifdef NATIVE_LITTLE_ENDIAN
|
|
||||||
uint32_t w;
|
|
||||||
memcpy(&w, src, sizeof w);
|
|
||||||
return w;
|
|
||||||
#else
|
|
||||||
uint32_t w = (uint32_t) src[0];
|
|
||||||
w |= (uint32_t) src[1] << 8;
|
|
||||||
w |= (uint32_t) src[2] << 16;
|
|
||||||
w |= (uint32_t) src[3] << 24;
|
|
||||||
return w;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#define STORE32_LE(DST, W) store32_le((DST), (W))
|
|
||||||
static inline void
|
|
||||||
store32_le(uint8_t dst[4], uint32_t w)
|
|
||||||
{
|
|
||||||
#ifdef NATIVE_LITTLE_ENDIAN
|
|
||||||
memcpy(dst, &w, sizeof w);
|
|
||||||
#else
|
|
||||||
dst[0] = (uint8_t) w;
|
|
||||||
w >>= 8;
|
|
||||||
dst[1] = (uint8_t) w;
|
|
||||||
w >>= 8;
|
|
||||||
dst[2] = (uint8_t) w;
|
|
||||||
w >>= 8;
|
|
||||||
dst[3] = (uint8_t) w;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#define LOAD16_LE(SRC) load16_le(SRC)
|
|
||||||
static inline uint16_t
|
|
||||||
load16_le(const uint8_t src[2])
|
|
||||||
{
|
|
||||||
#ifdef NATIVE_LITTLE_ENDIAN
|
|
||||||
uint16_t w;
|
|
||||||
memcpy(&w, src, sizeof w);
|
|
||||||
return w;
|
|
||||||
#else
|
|
||||||
uint16_t w = (uint16_t) src[0];
|
|
||||||
w |= (uint16_t) src[1] << 8;
|
|
||||||
return w;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#define STORE16_LE(DST, W) store16_le((DST), (W))
|
|
||||||
static inline void
|
|
||||||
store16_le(uint8_t dst[2], uint16_t w)
|
|
||||||
{
|
|
||||||
#ifdef NATIVE_LITTLE_ENDIAN
|
|
||||||
memcpy(dst, &w, sizeof w);
|
|
||||||
#else
|
|
||||||
dst[0] = (uint8_t) w;
|
|
||||||
w >>= 8;
|
|
||||||
dst[1] = (uint8_t) w;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ----- */
|
|
||||||
|
|
||||||
#define LOAD64_BE(SRC) load64_be(SRC)
|
|
||||||
static inline uint64_t
|
|
||||||
load64_be(const uint8_t src[8])
|
|
||||||
{
|
|
||||||
#ifdef NATIVE_BIG_ENDIAN
|
|
||||||
uint64_t w;
|
|
||||||
memcpy(&w, src, sizeof w);
|
|
||||||
return w;
|
|
||||||
#else
|
|
||||||
uint64_t w = (uint64_t) src[7];
|
|
||||||
w |= (uint64_t) src[6] << 8;
|
|
||||||
w |= (uint64_t) src[5] << 16;
|
|
||||||
w |= (uint64_t) src[4] << 24;
|
|
||||||
w |= (uint64_t) src[3] << 32;
|
|
||||||
w |= (uint64_t) src[2] << 40;
|
|
||||||
w |= (uint64_t) src[1] << 48;
|
|
||||||
w |= (uint64_t) src[0] << 56;
|
|
||||||
return w;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#define STORE64_BE(DST, W) store64_be((DST), (W))
|
|
||||||
static inline void
|
|
||||||
store64_be(uint8_t dst[8], uint64_t w)
|
|
||||||
{
|
|
||||||
#ifdef NATIVE_BIG_ENDIAN
|
|
||||||
memcpy(dst, &w, sizeof w);
|
|
||||||
#else
|
|
||||||
dst[7] = (uint8_t) w;
|
|
||||||
w >>= 8;
|
|
||||||
dst[6] = (uint8_t) w;
|
|
||||||
w >>= 8;
|
|
||||||
dst[5] = (uint8_t) w;
|
|
||||||
w >>= 8;
|
|
||||||
dst[4] = (uint8_t) w;
|
|
||||||
w >>= 8;
|
|
||||||
dst[3] = (uint8_t) w;
|
|
||||||
w >>= 8;
|
|
||||||
dst[2] = (uint8_t) w;
|
|
||||||
w >>= 8;
|
|
||||||
dst[1] = (uint8_t) w;
|
|
||||||
w >>= 8;
|
|
||||||
dst[0] = (uint8_t) w;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#define LOAD32_BE(SRC) load32_be(SRC)
|
|
||||||
static inline uint32_t
|
|
||||||
load32_be(const uint8_t src[4])
|
|
||||||
{
|
|
||||||
#ifdef NATIVE_BIG_ENDIAN
|
|
||||||
uint32_t w;
|
|
||||||
memcpy(&w, src, sizeof w);
|
|
||||||
return w;
|
|
||||||
#else
|
|
||||||
uint32_t w = (uint32_t) src[3];
|
|
||||||
w |= (uint32_t) src[2] << 8;
|
|
||||||
w |= (uint32_t) src[1] << 16;
|
|
||||||
w |= (uint32_t) src[0] << 24;
|
|
||||||
return w;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#define STORE32_BE(DST, W) store32_be((DST), (W))
|
|
||||||
static inline void
|
|
||||||
store32_be(uint8_t dst[4], uint32_t w)
|
|
||||||
{
|
|
||||||
#ifdef NATIVE_BIG_ENDIAN
|
|
||||||
memcpy(dst, &w, sizeof w);
|
|
||||||
#else
|
|
||||||
dst[3] = (uint8_t) w;
|
|
||||||
w >>= 8;
|
|
||||||
dst[2] = (uint8_t) w;
|
|
||||||
w >>= 8;
|
|
||||||
dst[1] = (uint8_t) w;
|
|
||||||
w >>= 8;
|
|
||||||
dst[0] = (uint8_t) w;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#define LOAD16_BE(SRC) load16_be(SRC)
|
|
||||||
static inline uint16_t
|
|
||||||
load16_be(const uint8_t src[2])
|
|
||||||
{
|
|
||||||
#ifdef NATIVE_BIG_ENDIAN
|
|
||||||
uint16_t w;
|
|
||||||
memcpy(&w, src, sizeof w);
|
|
||||||
return w;
|
|
||||||
#else
|
|
||||||
uint16_t w = (uint16_t) src[1];
|
|
||||||
w |= (uint16_t) src[0] << 8;
|
|
||||||
return w;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#define STORE16_BE(DST, W) store16_be((DST), (W))
|
|
||||||
static inline void
|
|
||||||
store16_be(uint8_t dst[2], uint16_t w)
|
|
||||||
{
|
|
||||||
#ifdef NATIVE_BIG_ENDIAN
|
|
||||||
memcpy(dst, &w, sizeof w);
|
|
||||||
#else
|
|
||||||
dst[1] = (uint8_t) w;
|
|
||||||
w >>= 8;
|
|
||||||
dst[0] = (uint8_t) w;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
mem_cpy(void *__restrict__ dst_, const void *__restrict__ src_, size_t n)
|
|
||||||
{
|
|
||||||
unsigned char *dst = (unsigned char *) dst_;
|
|
||||||
const unsigned char *src = (const unsigned char *) src_;
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
for (i = 0; i < n; i++) {
|
|
||||||
dst[i] = src[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
mem_zero(void *dst_, size_t n)
|
|
||||||
{
|
|
||||||
unsigned char *dst = (unsigned char *) dst_;
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
for (i = 0; i < n; i++) {
|
|
||||||
dst[i] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
mem_xor(void *__restrict__ dst_, const void *__restrict__ src_, size_t n)
|
|
||||||
{
|
|
||||||
unsigned char *dst = (unsigned char *) dst_;
|
|
||||||
const unsigned char *src = (const unsigned char *) src_;
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
for (i = 0; i < n; i++) {
|
|
||||||
dst[i] ^= src[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
mem_xor2(void *__restrict__ dst_, const void *__restrict__ src1_, const void *__restrict__ src2_,
|
|
||||||
size_t n)
|
|
||||||
{
|
|
||||||
unsigned char *dst = (unsigned char *) dst_;
|
|
||||||
const unsigned char *src1 = (const unsigned char *) src1_;
|
|
||||||
const unsigned char *src2 = (const unsigned char *) src2_;
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
for (i = 0; i < n; i++) {
|
|
||||||
dst[i] = src1[i] ^ src2[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static const uint8_t zero[64] = { 0 };
|
|
||||||
@ -1,221 +0,0 @@
|
|||||||
int
|
|
||||||
hydro_init(void)
|
|
||||||
{
|
|
||||||
hydro_random_ensure_initialized();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
hydro_memzero(void *pnt, size_t len)
|
|
||||||
{
|
|
||||||
#ifdef HAVE_EXPLICIT_BZERO
|
|
||||||
explicit_bzero(pnt, len);
|
|
||||||
#else
|
|
||||||
volatile unsigned char *volatile pnt_ = (volatile unsigned char *volatile) pnt;
|
|
||||||
size_t i = (size_t) 0U;
|
|
||||||
|
|
||||||
while (i < len) {
|
|
||||||
pnt_[i++] = 0U;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
hydro_increment(uint8_t *n, size_t len)
|
|
||||||
{
|
|
||||||
size_t i;
|
|
||||||
uint_fast16_t c = 1U;
|
|
||||||
|
|
||||||
for (i = 0; i < len; i++) {
|
|
||||||
c += (uint_fast16_t) n[i];
|
|
||||||
n[i] = (uint8_t) c;
|
|
||||||
c >>= 8;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
char *
|
|
||||||
hydro_bin2hex(char *hex, size_t hex_maxlen, const uint8_t *bin, size_t bin_len)
|
|
||||||
{
|
|
||||||
size_t i = (size_t) 0U;
|
|
||||||
unsigned int x;
|
|
||||||
int b;
|
|
||||||
int c;
|
|
||||||
|
|
||||||
if (bin_len >= SIZE_MAX / 2 || hex_maxlen <= bin_len * 2U) {
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
while (i < bin_len) {
|
|
||||||
c = bin[i] & 0xf;
|
|
||||||
b = bin[i] >> 4;
|
|
||||||
x = (unsigned char) (87U + c + (((c - 10U) >> 8) & ~38U)) << 8 |
|
|
||||||
(unsigned char) (87U + b + (((b - 10U) >> 8) & ~38U));
|
|
||||||
hex[i * 2U] = (char) x;
|
|
||||||
x >>= 8;
|
|
||||||
hex[i * 2U + 1U] = (char) x;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
hex[i * 2U] = 0U;
|
|
||||||
|
|
||||||
return hex;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
hydro_hex2bin(uint8_t *bin, size_t bin_maxlen, const char *hex, size_t hex_len, const char *ignore,
|
|
||||||
const char **hex_end_p)
|
|
||||||
{
|
|
||||||
size_t bin_pos = (size_t) 0U;
|
|
||||||
size_t hex_pos = (size_t) 0U;
|
|
||||||
int ret = 0;
|
|
||||||
unsigned char c;
|
|
||||||
unsigned char c_alpha0, c_alpha;
|
|
||||||
unsigned char c_num0, c_num;
|
|
||||||
uint8_t c_acc = 0U;
|
|
||||||
uint8_t c_val;
|
|
||||||
unsigned char state = 0U;
|
|
||||||
|
|
||||||
while (hex_pos < hex_len) {
|
|
||||||
c = (unsigned char) hex[hex_pos];
|
|
||||||
c_num = c ^ 48U;
|
|
||||||
c_num0 = (c_num - 10U) >> 8;
|
|
||||||
c_alpha = (c & ~32U) - 55U;
|
|
||||||
c_alpha0 = ((c_alpha - 10U) ^ (c_alpha - 16U)) >> 8;
|
|
||||||
if ((c_num0 | c_alpha0) == 0U) {
|
|
||||||
if (ignore != NULL && state == 0U && strchr(ignore, c) != NULL) {
|
|
||||||
hex_pos++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
c_val = (uint8_t) ((c_num0 & c_num) | (c_alpha0 & c_alpha));
|
|
||||||
if (bin_pos >= bin_maxlen) {
|
|
||||||
ret = -1;
|
|
||||||
errno = ERANGE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (state == 0U) {
|
|
||||||
c_acc = c_val * 16U;
|
|
||||||
} else {
|
|
||||||
bin[bin_pos++] = c_acc | c_val;
|
|
||||||
}
|
|
||||||
state = ~state;
|
|
||||||
hex_pos++;
|
|
||||||
}
|
|
||||||
if (state != 0U) {
|
|
||||||
hex_pos--;
|
|
||||||
errno = EINVAL;
|
|
||||||
ret = -1;
|
|
||||||
}
|
|
||||||
if (ret != 0) {
|
|
||||||
bin_pos = (size_t) 0U;
|
|
||||||
}
|
|
||||||
if (hex_end_p != NULL) {
|
|
||||||
*hex_end_p = &hex[hex_pos];
|
|
||||||
} else if (hex_pos != hex_len) {
|
|
||||||
errno = EINVAL;
|
|
||||||
ret = -1;
|
|
||||||
}
|
|
||||||
if (ret != 0) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
return (int) bin_pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
hydro_equal(const void *b1_, const void *b2_, size_t len)
|
|
||||||
{
|
|
||||||
const volatile uint8_t *volatile b1 = (const volatile uint8_t *volatile) b1_;
|
|
||||||
const uint8_t *b2 = (const uint8_t *) b2_;
|
|
||||||
size_t i;
|
|
||||||
uint8_t d = (uint8_t) 0U;
|
|
||||||
|
|
||||||
if (b1 == b2) {
|
|
||||||
d = ~d;
|
|
||||||
}
|
|
||||||
for (i = 0U; i < len; i++) {
|
|
||||||
d |= b1[i] ^ b2[i];
|
|
||||||
}
|
|
||||||
return (bool) (1 & ((d - 1) >> 8));
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
hydro_compare(const uint8_t *b1_, const uint8_t *b2_, size_t len)
|
|
||||||
{
|
|
||||||
const volatile uint8_t *volatile b1 = (const volatile uint8_t *volatile) b1_;
|
|
||||||
const uint8_t *b2 = (const uint8_t *) b2_;
|
|
||||||
uint8_t gt = 0U;
|
|
||||||
uint8_t eq = 1U;
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
i = len;
|
|
||||||
while (i != 0U) {
|
|
||||||
i--;
|
|
||||||
gt |= ((b2[i] - b1[i]) >> 8) & eq;
|
|
||||||
eq &= ((b2[i] ^ b1[i]) - 1) >> 8;
|
|
||||||
}
|
|
||||||
return (int) (gt + gt + eq) - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
hydro_pad(unsigned char *buf, size_t unpadded_buflen, size_t blocksize, size_t max_buflen)
|
|
||||||
{
|
|
||||||
unsigned char *tail;
|
|
||||||
size_t i;
|
|
||||||
size_t xpadlen;
|
|
||||||
size_t xpadded_len;
|
|
||||||
volatile unsigned char mask;
|
|
||||||
unsigned char barrier_mask;
|
|
||||||
|
|
||||||
if (blocksize <= 0U || max_buflen > INT_MAX) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
xpadlen = blocksize - 1U;
|
|
||||||
if ((blocksize & (blocksize - 1U)) == 0U) {
|
|
||||||
xpadlen -= unpadded_buflen & (blocksize - 1U);
|
|
||||||
} else {
|
|
||||||
xpadlen -= unpadded_buflen % blocksize;
|
|
||||||
}
|
|
||||||
if ((size_t) SIZE_MAX - unpadded_buflen <= xpadlen) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
xpadded_len = unpadded_buflen + xpadlen;
|
|
||||||
if (xpadded_len >= max_buflen) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
tail = &buf[xpadded_len];
|
|
||||||
mask = 0U;
|
|
||||||
for (i = 0; i < blocksize; i++) {
|
|
||||||
barrier_mask = (unsigned char) (((i ^ xpadlen) - 1U) >> ((sizeof(size_t) - 1U) * CHAR_BIT));
|
|
||||||
*(tail - i) = ((*(tail - i)) & mask) | (0x80 & barrier_mask);
|
|
||||||
mask |= barrier_mask;
|
|
||||||
}
|
|
||||||
return (int) (xpadded_len + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
hydro_unpad(const unsigned char *buf, size_t padded_buflen, size_t blocksize)
|
|
||||||
{
|
|
||||||
const unsigned char *tail;
|
|
||||||
unsigned char acc = 0U;
|
|
||||||
unsigned char c;
|
|
||||||
unsigned char valid = 0U;
|
|
||||||
volatile size_t pad_len = 0U;
|
|
||||||
size_t i;
|
|
||||||
size_t is_barrier;
|
|
||||||
|
|
||||||
if (padded_buflen < blocksize || blocksize <= 0U) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
tail = &buf[padded_buflen - 1U];
|
|
||||||
|
|
||||||
for (i = 0U; i < blocksize; i++) {
|
|
||||||
c = *(tail - i);
|
|
||||||
is_barrier = (((acc - 1U) & (pad_len - 1U) & ((c ^ 0x80) - 1U)) >> 8) & 1U;
|
|
||||||
acc |= c;
|
|
||||||
pad_len |= i & (1U + ~is_barrier);
|
|
||||||
valid |= (unsigned char) is_barrier;
|
|
||||||
}
|
|
||||||
if (valid == 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return (int) (padded_buflen - 1 - pad_len);
|
|
||||||
}
|
|
||||||
@ -1,25 +0,0 @@
|
|||||||
#ifdef __SSE2__
|
|
||||||
# include "gimli-core/sse2.h"
|
|
||||||
#else
|
|
||||||
# include "gimli-core/portable.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void
|
|
||||||
gimli_core_u8(uint8_t state_u8[gimli_BLOCKBYTES], uint8_t tag)
|
|
||||||
{
|
|
||||||
state_u8[gimli_BLOCKBYTES - 1] ^= tag;
|
|
||||||
#ifndef NATIVE_LITTLE_ENDIAN
|
|
||||||
uint32_t state_u32[12];
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < 12; i++) {
|
|
||||||
state_u32[i] = LOAD32_LE(&state_u8[i * 4]);
|
|
||||||
}
|
|
||||||
gimli_core(state_u32);
|
|
||||||
for (i = 0; i < 12; i++) {
|
|
||||||
STORE32_LE(&state_u8[i * 4], state_u32[i]);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
gimli_core((uint32_t *) (void *) state_u8); /* state_u8 must be properly aligned */
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
@ -1,39 +0,0 @@
|
|||||||
static void
|
|
||||||
gimli_core(uint32_t state[gimli_BLOCKBYTES / 4])
|
|
||||||
{
|
|
||||||
unsigned int round;
|
|
||||||
unsigned int column;
|
|
||||||
uint32_t x;
|
|
||||||
uint32_t y;
|
|
||||||
uint32_t z;
|
|
||||||
|
|
||||||
for (round = 24; round > 0; round--) {
|
|
||||||
for (column = 0; column < 4; column++) {
|
|
||||||
x = ROTL32(state[column], 24);
|
|
||||||
y = ROTL32(state[4 + column], 9);
|
|
||||||
z = state[8 + column];
|
|
||||||
|
|
||||||
state[8 + column] = x ^ (z << 1) ^ ((y & z) << 2);
|
|
||||||
state[4 + column] = y ^ x ^ ((x | z) << 1);
|
|
||||||
state[column] = z ^ y ^ ((x & y) << 3);
|
|
||||||
}
|
|
||||||
switch (round & 3) {
|
|
||||||
case 0:
|
|
||||||
x = state[0];
|
|
||||||
state[0] = state[1];
|
|
||||||
state[1] = x;
|
|
||||||
x = state[2];
|
|
||||||
state[2] = state[3];
|
|
||||||
state[3] = x;
|
|
||||||
state[0] ^= ((uint32_t) 0x9e377900 | round);
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
x = state[0];
|
|
||||||
state[0] = state[2];
|
|
||||||
state[2] = x;
|
|
||||||
x = state[1];
|
|
||||||
state[1] = state[3];
|
|
||||||
state[3] = x;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,112 +0,0 @@
|
|||||||
#include <emmintrin.h>
|
|
||||||
#ifdef __SSSE3__
|
|
||||||
# include <tmmintrin.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define S 9
|
|
||||||
|
|
||||||
static inline __m128i
|
|
||||||
shift(__m128i x, int bits)
|
|
||||||
{
|
|
||||||
return _mm_slli_epi32(x, bits);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline __m128i
|
|
||||||
rotate(__m128i x, int bits)
|
|
||||||
{
|
|
||||||
return _mm_slli_epi32(x, bits) | _mm_srli_epi32(x, 32 - bits);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __SSSE3__
|
|
||||||
static inline __m128i
|
|
||||||
rotate24(__m128i x)
|
|
||||||
{
|
|
||||||
return _mm_shuffle_epi8(x, _mm_set_epi8(12, 15, 14, 13, 8, 11, 10, 9, 4, 7, 6, 5, 0, 3, 2, 1));
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
static inline __m128i
|
|
||||||
rotate24(__m128i x)
|
|
||||||
{
|
|
||||||
uint8_t _hydro_attr_aligned_(16) x8[16], y8[16];
|
|
||||||
|
|
||||||
_mm_storeu_si128((__m128i *) (void *) x8, x);
|
|
||||||
|
|
||||||
y8[0] = x8[1];
|
|
||||||
y8[1] = x8[2];
|
|
||||||
y8[2] = x8[3];
|
|
||||||
y8[3] = x8[0];
|
|
||||||
y8[4] = x8[5];
|
|
||||||
y8[5] = x8[6];
|
|
||||||
y8[6] = x8[7];
|
|
||||||
y8[7] = x8[4];
|
|
||||||
y8[8] = x8[9];
|
|
||||||
y8[9] = x8[10];
|
|
||||||
y8[10] = x8[11];
|
|
||||||
y8[11] = x8[8];
|
|
||||||
y8[12] = x8[13];
|
|
||||||
y8[13] = x8[14];
|
|
||||||
y8[14] = x8[15];
|
|
||||||
y8[15] = x8[12];
|
|
||||||
|
|
||||||
return _mm_loadu_si128((const __m128i *) (const void *) y8);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static const uint32_t _hydro_attr_aligned_(16) coeffs[24] = {
|
|
||||||
0x9e377904, 0, 0, 0, 0x9e377908, 0, 0, 0, 0x9e37790c, 0, 0, 0,
|
|
||||||
0x9e377910, 0, 0, 0, 0x9e377914, 0, 0, 0, 0x9e377918, 0, 0, 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
static void
|
|
||||||
gimli_core(uint32_t state[gimli_BLOCKBYTES / 4])
|
|
||||||
{
|
|
||||||
__m128i x = _mm_loadu_si128((const __m128i *) (const void *) &state[0]);
|
|
||||||
__m128i y = _mm_loadu_si128((const __m128i *) (const void *) &state[4]);
|
|
||||||
__m128i z = _mm_loadu_si128((const __m128i *) (const void *) &state[8]);
|
|
||||||
__m128i newy;
|
|
||||||
__m128i newz;
|
|
||||||
int round;
|
|
||||||
|
|
||||||
for (round = 5; round >= 0; round--) {
|
|
||||||
x = rotate24(x);
|
|
||||||
y = rotate(y, S);
|
|
||||||
newz = x ^ shift(z, 1) ^ shift(y & z, 2);
|
|
||||||
newy = y ^ x ^ shift(x | z, 1);
|
|
||||||
x = z ^ y ^ shift(x & y, 3);
|
|
||||||
y = newy;
|
|
||||||
z = newz;
|
|
||||||
|
|
||||||
x = _mm_shuffle_epi32(x, _MM_SHUFFLE(2, 3, 0, 1));
|
|
||||||
x ^= ((const __m128i *) (const void *) coeffs)[round];
|
|
||||||
|
|
||||||
x = rotate24(x);
|
|
||||||
y = rotate(y, S);
|
|
||||||
newz = x ^ shift(z, 1) ^ shift(y & z, 2);
|
|
||||||
newy = y ^ x ^ shift(x | z, 1);
|
|
||||||
x = z ^ y ^ shift(x & y, 3);
|
|
||||||
y = newy;
|
|
||||||
z = newz;
|
|
||||||
|
|
||||||
x = rotate24(x);
|
|
||||||
y = rotate(y, S);
|
|
||||||
newz = x ^ shift(z, 1) ^ shift(y & z, 2);
|
|
||||||
newy = y ^ x ^ shift(x | z, 1);
|
|
||||||
x = z ^ y ^ shift(x & y, 3);
|
|
||||||
y = newy;
|
|
||||||
z = newz;
|
|
||||||
|
|
||||||
x = _mm_shuffle_epi32(x, _MM_SHUFFLE(1, 0, 3, 2));
|
|
||||||
|
|
||||||
x = rotate24(x);
|
|
||||||
y = rotate(y, S);
|
|
||||||
newz = x ^ shift(z, 1) ^ shift(y & z, 2);
|
|
||||||
newy = y ^ x ^ shift(x | z, 1);
|
|
||||||
x = z ^ y ^ shift(x & y, 3);
|
|
||||||
y = newy;
|
|
||||||
z = newz;
|
|
||||||
}
|
|
||||||
|
|
||||||
_mm_storeu_si128((__m128i *) (void *) &state[0], x);
|
|
||||||
_mm_storeu_si128((__m128i *) (void *) &state[4], y);
|
|
||||||
_mm_storeu_si128((__m128i *) (void *) &state[8], z);
|
|
||||||
}
|
|
||||||
@ -1,142 +0,0 @@
|
|||||||
int
|
|
||||||
hydro_hash_update(hydro_hash_state *state, const void *in_, size_t in_len)
|
|
||||||
{
|
|
||||||
const uint8_t *in = (const uint8_t *) in_;
|
|
||||||
uint8_t *buf = (uint8_t *) (void *) state->state;
|
|
||||||
size_t left;
|
|
||||||
size_t ps;
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
while (in_len > 0) {
|
|
||||||
left = gimli_RATE - state->buf_off;
|
|
||||||
if ((ps = in_len) > left) {
|
|
||||||
ps = left;
|
|
||||||
}
|
|
||||||
for (i = 0; i < ps; i++) {
|
|
||||||
buf[state->buf_off + i] ^= in[i];
|
|
||||||
}
|
|
||||||
in += ps;
|
|
||||||
in_len -= ps;
|
|
||||||
state->buf_off += (uint8_t) ps;
|
|
||||||
if (state->buf_off == gimli_RATE) {
|
|
||||||
gimli_core_u8(buf, 0);
|
|
||||||
state->buf_off = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* pad(str_enc("kmac") || str_enc(context)) || pad(str_enc(k)) ||
|
|
||||||
msg || right_enc(msg_len) || 0x00 */
|
|
||||||
|
|
||||||
int
|
|
||||||
hydro_hash_init(hydro_hash_state *state, const char ctx[hydro_hash_CONTEXTBYTES],
|
|
||||||
const uint8_t key[hydro_hash_KEYBYTES])
|
|
||||||
{
|
|
||||||
uint8_t block[64] = { 4, 'k', 'm', 'a', 'c', 8 };
|
|
||||||
size_t p;
|
|
||||||
|
|
||||||
COMPILER_ASSERT(hydro_hash_KEYBYTES <= sizeof block - gimli_RATE - 1);
|
|
||||||
COMPILER_ASSERT(hydro_hash_CONTEXTBYTES == 8);
|
|
||||||
mem_zero(block + 14, sizeof block - 14);
|
|
||||||
memcpy(block + 6, ctx, 8);
|
|
||||||
if (key != NULL) {
|
|
||||||
block[gimli_RATE] = (uint8_t) hydro_hash_KEYBYTES;
|
|
||||||
memcpy(block + gimli_RATE + 1, key, hydro_hash_KEYBYTES);
|
|
||||||
p = (gimli_RATE + 1 + hydro_hash_KEYBYTES + (gimli_RATE - 1)) & ~(size_t) (gimli_RATE - 1);
|
|
||||||
} else {
|
|
||||||
block[gimli_RATE] = (uint8_t) 0;
|
|
||||||
p = (gimli_RATE + 1 + 0 + (gimli_RATE - 1)) & ~(size_t) (gimli_RATE - 1);
|
|
||||||
}
|
|
||||||
mem_zero(state, sizeof *state);
|
|
||||||
hydro_hash_update(state, block, p);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* pad(str_enc("tmac") || str_enc(context)) || pad(str_enc(k)) ||
|
|
||||||
pad(right_enc(tweak)) || msg || right_enc(msg_len) || 0x00 */
|
|
||||||
|
|
||||||
static int
|
|
||||||
hydro_hash_init_with_tweak(hydro_hash_state *state, const char ctx[hydro_hash_CONTEXTBYTES],
|
|
||||||
uint64_t tweak, const uint8_t key[hydro_hash_KEYBYTES])
|
|
||||||
{
|
|
||||||
uint8_t block[80] = { 4, 't', 'm', 'a', 'c', 8 };
|
|
||||||
size_t p;
|
|
||||||
|
|
||||||
COMPILER_ASSERT(hydro_hash_KEYBYTES <= sizeof block - 2 * gimli_RATE - 1);
|
|
||||||
COMPILER_ASSERT(hydro_hash_CONTEXTBYTES == 8);
|
|
||||||
mem_zero(block + 14, sizeof block - 14);
|
|
||||||
memcpy(block + 6, ctx, 8);
|
|
||||||
if (key != NULL) {
|
|
||||||
block[gimli_RATE] = (uint8_t) hydro_hash_KEYBYTES;
|
|
||||||
memcpy(block + gimli_RATE + 1, key, hydro_hash_KEYBYTES);
|
|
||||||
p = (gimli_RATE + 1 + hydro_hash_KEYBYTES + (gimli_RATE - 1)) & ~(size_t) (gimli_RATE - 1);
|
|
||||||
} else {
|
|
||||||
block[gimli_RATE] = (uint8_t) 0;
|
|
||||||
p = (gimli_RATE + 1 + 0 + (gimli_RATE - 1)) & ~(size_t) (gimli_RATE - 1);
|
|
||||||
}
|
|
||||||
block[p] = (uint8_t) sizeof tweak;
|
|
||||||
STORE64_LE(&block[p + 1], tweak);
|
|
||||||
p += gimli_RATE;
|
|
||||||
mem_zero(state, sizeof *state);
|
|
||||||
hydro_hash_update(state, block, p);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
hydro_hash_final(hydro_hash_state *state, uint8_t *out, size_t out_len)
|
|
||||||
{
|
|
||||||
uint8_t lc[4];
|
|
||||||
uint8_t *buf = (uint8_t *) (void *) state->state;
|
|
||||||
size_t i;
|
|
||||||
size_t lc_len;
|
|
||||||
size_t leftover;
|
|
||||||
|
|
||||||
if (out_len == 0) {
|
|
||||||
/* allow callers to finalize without producing output */
|
|
||||||
} else if (out_len < hydro_hash_BYTES_MIN || out_len > hydro_hash_BYTES_MAX || out == NULL) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
COMPILER_ASSERT(hydro_hash_BYTES_MAX <= 0xffff);
|
|
||||||
lc[1] = (uint8_t) out_len;
|
|
||||||
lc[2] = (uint8_t) (out_len >> 8);
|
|
||||||
lc[3] = 0;
|
|
||||||
lc_len = (size_t) (1 + (lc[2] != 0));
|
|
||||||
lc[0] = (uint8_t) lc_len;
|
|
||||||
hydro_hash_update(state, lc, 1 + lc_len + 1);
|
|
||||||
gimli_pad_u8(buf, state->buf_off, gimli_DOMAIN_XOF);
|
|
||||||
for (i = 0; i < out_len / gimli_RATE; i++) {
|
|
||||||
gimli_core_u8(buf, 0);
|
|
||||||
memcpy(out + i * gimli_RATE, buf, gimli_RATE);
|
|
||||||
}
|
|
||||||
leftover = out_len % gimli_RATE;
|
|
||||||
if (leftover != 0) {
|
|
||||||
gimli_core_u8(buf, 0);
|
|
||||||
mem_cpy(out + i * gimli_RATE, buf, leftover);
|
|
||||||
}
|
|
||||||
state->buf_off = gimli_RATE;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
hydro_hash_hash(uint8_t *out, size_t out_len, const void *in_, size_t in_len,
|
|
||||||
const char ctx[hydro_hash_CONTEXTBYTES], const uint8_t key[hydro_hash_KEYBYTES])
|
|
||||||
{
|
|
||||||
hydro_hash_state st;
|
|
||||||
const uint8_t *in = (const uint8_t *) in_;
|
|
||||||
|
|
||||||
if (hydro_hash_init(&st, ctx, key) != 0 || hydro_hash_update(&st, in, in_len) != 0 ||
|
|
||||||
hydro_hash_final(&st, out, out_len) != 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
hydro_hash_keygen(uint8_t key[hydro_hash_KEYBYTES])
|
|
||||||
{
|
|
||||||
hydro_random_buf(key, hydro_hash_KEYBYTES);
|
|
||||||
}
|
|
||||||
@ -1,82 +0,0 @@
|
|||||||
static int hydro_random_init(void);
|
|
||||||
|
|
||||||
/* ---------------- */
|
|
||||||
|
|
||||||
#define gimli_BLOCKBYTES 48
|
|
||||||
#define gimli_CAPACITY 32
|
|
||||||
#define gimli_RATE 16
|
|
||||||
|
|
||||||
#define gimli_TAG_HEADER 0x01
|
|
||||||
#define gimli_TAG_PAYLOAD 0x02
|
|
||||||
#define gimli_TAG_FINAL 0x08
|
|
||||||
#define gimli_TAG_FINAL0 0xf8
|
|
||||||
#define gimli_TAG_KEY0 0xfe
|
|
||||||
#define gimli_TAG_KEY 0xff
|
|
||||||
|
|
||||||
#define gimli_DOMAIN_AEAD 0x0
|
|
||||||
#define gimli_DOMAIN_XOF 0xf
|
|
||||||
|
|
||||||
static void gimli_core_u8(uint8_t state_u8[gimli_BLOCKBYTES], uint8_t tag);
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
gimli_pad_u8(uint8_t buf[gimli_BLOCKBYTES], size_t pos, uint8_t domain)
|
|
||||||
{
|
|
||||||
buf[pos] ^= (domain << 1) | 1;
|
|
||||||
buf[gimli_RATE - 1] ^= 0x80;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
hydro_mem_ct_zero_u32(uint32_t *dst_, size_t n)
|
|
||||||
{
|
|
||||||
volatile uint32_t *volatile dst = (volatile uint32_t *volatile) (void *) dst_;
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
for (i = 0; i < n; i++) {
|
|
||||||
dst[i] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint32_t hydro_mem_ct_cmp_u32(const uint32_t *b1_, const uint32_t *b2,
|
|
||||||
size_t n) _hydro_attr_warn_unused_result_;
|
|
||||||
|
|
||||||
static inline uint32_t
|
|
||||||
hydro_mem_ct_cmp_u32(const uint32_t *b1_, const uint32_t *b2, size_t n)
|
|
||||||
{
|
|
||||||
const volatile uint32_t *volatile b1 = (const volatile uint32_t *volatile) (const void *) b1_;
|
|
||||||
size_t i;
|
|
||||||
uint32_t cv = 0;
|
|
||||||
|
|
||||||
for (i = 0; i < n; i++) {
|
|
||||||
cv |= b1[i] ^ b2[i];
|
|
||||||
}
|
|
||||||
return cv;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ---------------- */
|
|
||||||
|
|
||||||
static int hydro_hash_init_with_tweak(hydro_hash_state *state,
|
|
||||||
const char ctx[hydro_hash_CONTEXTBYTES], uint64_t tweak,
|
|
||||||
const uint8_t key[hydro_hash_KEYBYTES]);
|
|
||||||
|
|
||||||
/* ---------------- */
|
|
||||||
|
|
||||||
#define hydro_secretbox_NONCEBYTES 20
|
|
||||||
|
|
||||||
/* ---------------- */
|
|
||||||
|
|
||||||
#define hydro_x25519_BYTES 32
|
|
||||||
#define hydro_x25519_PUBLICKEYBYTES 32
|
|
||||||
#define hydro_x25519_SECRETKEYBYTES 32
|
|
||||||
|
|
||||||
static int hydro_x25519_scalarmult(uint8_t out[hydro_x25519_BYTES],
|
|
||||||
const uint8_t scalar[hydro_x25519_SECRETKEYBYTES],
|
|
||||||
const uint8_t x1[hydro_x25519_PUBLICKEYBYTES],
|
|
||||||
bool clamp) _hydro_attr_warn_unused_result_;
|
|
||||||
|
|
||||||
static inline int hydro_x25519_scalarmult_base(uint8_t pk[hydro_x25519_PUBLICKEYBYTES],
|
|
||||||
const uint8_t sk[hydro_x25519_SECRETKEYBYTES])
|
|
||||||
_hydro_attr_warn_unused_result_;
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
hydro_x25519_scalarmult_base_uniform(uint8_t pk[hydro_x25519_PUBLICKEYBYTES],
|
|
||||||
const uint8_t sk[hydro_x25519_SECRETKEYBYTES]);
|
|
||||||
@ -1,20 +0,0 @@
|
|||||||
int
|
|
||||||
hydro_kdf_derive_from_key(uint8_t *subkey, size_t subkey_len, uint64_t subkey_id,
|
|
||||||
const char ctx[hydro_kdf_CONTEXTBYTES],
|
|
||||||
const uint8_t key[hydro_kdf_KEYBYTES])
|
|
||||||
{
|
|
||||||
hydro_hash_state st;
|
|
||||||
|
|
||||||
COMPILER_ASSERT(hydro_kdf_CONTEXTBYTES >= hydro_hash_CONTEXTBYTES);
|
|
||||||
COMPILER_ASSERT(hydro_kdf_KEYBYTES >= hydro_hash_KEYBYTES);
|
|
||||||
if (hydro_hash_init_with_tweak(&st, ctx, subkey_id, key) != 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return hydro_hash_final(&st, subkey, subkey_len);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
hydro_kdf_keygen(uint8_t key[hydro_kdf_KEYBYTES])
|
|
||||||
{
|
|
||||||
hydro_random_buf(key, hydro_kdf_KEYBYTES);
|
|
||||||
}
|
|
||||||
@ -1,535 +0,0 @@
|
|||||||
#define hydro_kx_AEAD_KEYBYTES hydro_hash_KEYBYTES
|
|
||||||
#define hydro_kx_AEAD_MACBYTES 16
|
|
||||||
|
|
||||||
#define hydro_kx_CONTEXT "hydro_kx"
|
|
||||||
|
|
||||||
static void
|
|
||||||
hydro_kx_aead_init(uint8_t aead_state[gimli_BLOCKBYTES], uint8_t k[hydro_kx_AEAD_KEYBYTES],
|
|
||||||
hydro_kx_state *state)
|
|
||||||
{
|
|
||||||
static const uint8_t prefix[] = { 6, 'k', 'x', 'x', '2', '5', '6', 0 };
|
|
||||||
|
|
||||||
hydro_hash_final(&state->h_st, k, hydro_kx_AEAD_KEYBYTES);
|
|
||||||
|
|
||||||
mem_zero(aead_state + sizeof prefix, gimli_BLOCKBYTES - sizeof prefix);
|
|
||||||
memcpy(aead_state, prefix, sizeof prefix);
|
|
||||||
gimli_core_u8(aead_state, gimli_TAG_HEADER);
|
|
||||||
|
|
||||||
COMPILER_ASSERT(hydro_kx_AEAD_KEYBYTES == 2 * gimli_RATE);
|
|
||||||
mem_xor(aead_state, k, gimli_RATE);
|
|
||||||
gimli_core_u8(aead_state, gimli_TAG_KEY);
|
|
||||||
mem_xor(aead_state, k + gimli_RATE, gimli_RATE);
|
|
||||||
gimli_core_u8(aead_state, gimli_TAG_KEY);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
hydro_kx_aead_final(uint8_t *aead_state, const uint8_t key[hydro_kx_AEAD_KEYBYTES])
|
|
||||||
{
|
|
||||||
COMPILER_ASSERT(hydro_kx_AEAD_KEYBYTES == gimli_CAPACITY);
|
|
||||||
mem_xor(aead_state + gimli_RATE, key, hydro_kx_AEAD_KEYBYTES);
|
|
||||||
gimli_core_u8(aead_state, gimli_TAG_FINAL);
|
|
||||||
mem_xor(aead_state + gimli_RATE, key, hydro_kx_AEAD_KEYBYTES);
|
|
||||||
gimli_core_u8(aead_state, gimli_TAG_FINAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
hydro_kx_aead_xor_enc(uint8_t aead_state[gimli_BLOCKBYTES], uint8_t *out, const uint8_t *in,
|
|
||||||
size_t inlen)
|
|
||||||
{
|
|
||||||
size_t i;
|
|
||||||
size_t leftover;
|
|
||||||
|
|
||||||
for (i = 0; i < inlen / gimli_RATE; i++) {
|
|
||||||
mem_xor2(&out[i * gimli_RATE], &in[i * gimli_RATE], aead_state, gimli_RATE);
|
|
||||||
memcpy(aead_state, &out[i * gimli_RATE], gimli_RATE);
|
|
||||||
gimli_core_u8(aead_state, gimli_TAG_PAYLOAD);
|
|
||||||
}
|
|
||||||
leftover = inlen % gimli_RATE;
|
|
||||||
if (leftover != 0) {
|
|
||||||
mem_xor2(&out[i * gimli_RATE], &in[i * gimli_RATE], aead_state, leftover);
|
|
||||||
mem_cpy(aead_state, &out[i * gimli_RATE], leftover);
|
|
||||||
}
|
|
||||||
gimli_pad_u8(aead_state, leftover, gimli_DOMAIN_AEAD);
|
|
||||||
gimli_core_u8(aead_state, gimli_TAG_PAYLOAD);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
hydro_kx_aead_xor_dec(uint8_t aead_state[gimli_BLOCKBYTES], uint8_t *out, const uint8_t *in,
|
|
||||||
size_t inlen)
|
|
||||||
{
|
|
||||||
size_t i;
|
|
||||||
size_t leftover;
|
|
||||||
|
|
||||||
for (i = 0; i < inlen / gimli_RATE; i++) {
|
|
||||||
mem_xor2(&out[i * gimli_RATE], &in[i * gimli_RATE], aead_state, gimli_RATE);
|
|
||||||
memcpy(aead_state, &in[i * gimli_RATE], gimli_RATE);
|
|
||||||
gimli_core_u8(aead_state, gimli_TAG_PAYLOAD);
|
|
||||||
}
|
|
||||||
leftover = inlen % gimli_RATE;
|
|
||||||
if (leftover != 0) {
|
|
||||||
mem_xor2(&out[i * gimli_RATE], &in[i * gimli_RATE], aead_state, leftover);
|
|
||||||
mem_cpy(aead_state, &in[i * gimli_RATE], leftover);
|
|
||||||
}
|
|
||||||
gimli_pad_u8(aead_state, leftover, gimli_DOMAIN_AEAD);
|
|
||||||
gimli_core_u8(aead_state, gimli_TAG_PAYLOAD);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
hydro_kx_aead_encrypt(hydro_kx_state *state, uint8_t *c, const uint8_t *m, size_t mlen)
|
|
||||||
{
|
|
||||||
_hydro_attr_aligned_(16) uint8_t aead_state[gimli_BLOCKBYTES];
|
|
||||||
uint8_t k[hydro_kx_AEAD_KEYBYTES];
|
|
||||||
uint8_t *mac = &c[0];
|
|
||||||
uint8_t *ct = &c[hydro_kx_AEAD_MACBYTES];
|
|
||||||
|
|
||||||
hydro_kx_aead_init(aead_state, k, state);
|
|
||||||
hydro_kx_aead_xor_enc(aead_state, ct, m, mlen);
|
|
||||||
hydro_kx_aead_final(aead_state, k);
|
|
||||||
COMPILER_ASSERT(hydro_kx_AEAD_MACBYTES <= gimli_CAPACITY);
|
|
||||||
memcpy(mac, aead_state + gimli_RATE, hydro_kx_AEAD_MACBYTES);
|
|
||||||
hydro_hash_update(&state->h_st, c, mlen + hydro_kx_AEAD_MACBYTES);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int hydro_kx_aead_decrypt(hydro_kx_state *state, uint8_t *m, const uint8_t *c,
|
|
||||||
size_t clen) _hydro_attr_warn_unused_result_;
|
|
||||||
|
|
||||||
static int
|
|
||||||
hydro_kx_aead_decrypt(hydro_kx_state *state, uint8_t *m, const uint8_t *c, size_t clen)
|
|
||||||
{
|
|
||||||
_hydro_attr_aligned_(16) uint32_t int_state[gimli_BLOCKBYTES / 4];
|
|
||||||
uint32_t pub_mac[hydro_kx_AEAD_MACBYTES / 4];
|
|
||||||
uint8_t k[hydro_kx_AEAD_KEYBYTES];
|
|
||||||
uint8_t *aead_state = (uint8_t *) (void *) int_state;
|
|
||||||
const uint8_t *mac;
|
|
||||||
const uint8_t *ct;
|
|
||||||
size_t mlen;
|
|
||||||
uint32_t cv;
|
|
||||||
|
|
||||||
if (clen < hydro_kx_AEAD_MACBYTES) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
mac = &c[0];
|
|
||||||
ct = &c[hydro_kx_AEAD_MACBYTES];
|
|
||||||
mlen = clen - hydro_kx_AEAD_MACBYTES;
|
|
||||||
memcpy(pub_mac, mac, sizeof pub_mac);
|
|
||||||
hydro_kx_aead_init(aead_state, k, state);
|
|
||||||
hydro_hash_update(&state->h_st, c, clen);
|
|
||||||
hydro_kx_aead_xor_dec(aead_state, m, ct, mlen);
|
|
||||||
hydro_kx_aead_final(aead_state, k);
|
|
||||||
COMPILER_ASSERT(hydro_kx_AEAD_MACBYTES <= gimli_CAPACITY);
|
|
||||||
COMPILER_ASSERT(gimli_RATE % 4 == 0);
|
|
||||||
cv = hydro_mem_ct_cmp_u32(int_state + gimli_RATE / 4, pub_mac, hydro_kx_AEAD_MACBYTES / 4);
|
|
||||||
hydro_mem_ct_zero_u32(int_state, gimli_BLOCKBYTES / 4);
|
|
||||||
if (cv != 0) {
|
|
||||||
mem_zero(m, mlen);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -- */
|
|
||||||
|
|
||||||
void
|
|
||||||
hydro_kx_keygen(hydro_kx_keypair *static_kp)
|
|
||||||
{
|
|
||||||
hydro_random_buf(static_kp->sk, hydro_kx_SECRETKEYBYTES);
|
|
||||||
if (hydro_x25519_scalarmult_base(static_kp->pk, static_kp->sk) != 0) {
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
hydro_kx_keygen_deterministic(hydro_kx_keypair *static_kp, const uint8_t seed[hydro_kx_SEEDBYTES])
|
|
||||||
{
|
|
||||||
COMPILER_ASSERT(hydro_kx_SEEDBYTES >= hydro_random_SEEDBYTES);
|
|
||||||
hydro_random_buf_deterministic(static_kp->sk, hydro_kx_SECRETKEYBYTES, seed);
|
|
||||||
if (hydro_x25519_scalarmult_base(static_kp->pk, static_kp->sk) != 0) {
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
hydro_kx_init_state(hydro_kx_state *state, const char *name)
|
|
||||||
{
|
|
||||||
mem_zero(state, sizeof *state);
|
|
||||||
hydro_hash_init(&state->h_st, hydro_kx_CONTEXT, NULL);
|
|
||||||
hydro_hash_update(&state->h_st, name, strlen(name));
|
|
||||||
hydro_hash_final(&state->h_st, NULL, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
hydro_kx_final(hydro_kx_state *state, uint8_t session_k1[hydro_kx_SESSIONKEYBYTES],
|
|
||||||
uint8_t session_k2[hydro_kx_SESSIONKEYBYTES])
|
|
||||||
{
|
|
||||||
uint8_t kdf_key[hydro_kdf_KEYBYTES];
|
|
||||||
|
|
||||||
hydro_hash_final(&state->h_st, kdf_key, sizeof kdf_key);
|
|
||||||
hydro_kdf_derive_from_key(session_k1, hydro_kx_SESSIONKEYBYTES, 0, hydro_kx_CONTEXT, kdf_key);
|
|
||||||
hydro_kdf_derive_from_key(session_k2, hydro_kx_SESSIONKEYBYTES, 1, hydro_kx_CONTEXT, kdf_key);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
hydro_kx_dh(hydro_kx_state *state, const uint8_t sk[hydro_x25519_SECRETKEYBYTES],
|
|
||||||
const uint8_t pk[hydro_x25519_PUBLICKEYBYTES])
|
|
||||||
{
|
|
||||||
uint8_t dh_result[hydro_x25519_BYTES];
|
|
||||||
|
|
||||||
if (hydro_x25519_scalarmult(dh_result, sk, pk, 1) != 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
hydro_hash_update(&state->h_st, dh_result, hydro_x25519_BYTES);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
hydro_kx_eph_keygen(hydro_kx_state *state, hydro_kx_keypair *kp)
|
|
||||||
{
|
|
||||||
hydro_kx_keygen(kp);
|
|
||||||
hydro_hash_update(&state->h_st, kp->pk, sizeof kp->pk);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* NOISE_N */
|
|
||||||
|
|
||||||
int
|
|
||||||
hydro_kx_n_1(hydro_kx_session_keypair *kp, uint8_t packet1[hydro_kx_N_PACKET1BYTES],
|
|
||||||
const uint8_t psk[hydro_kx_PSKBYTES],
|
|
||||||
const uint8_t peer_static_pk[hydro_kx_PUBLICKEYBYTES])
|
|
||||||
{
|
|
||||||
hydro_kx_state state;
|
|
||||||
uint8_t *packet1_eph_pk = &packet1[0];
|
|
||||||
uint8_t *packet1_mac = &packet1[hydro_kx_PUBLICKEYBYTES];
|
|
||||||
|
|
||||||
if (psk == NULL) {
|
|
||||||
psk = zero;
|
|
||||||
}
|
|
||||||
hydro_kx_init_state(&state, "Noise_Npsk0_hydro1");
|
|
||||||
hydro_hash_update(&state.h_st, peer_static_pk, hydro_x25519_PUBLICKEYBYTES);
|
|
||||||
|
|
||||||
hydro_hash_update(&state.h_st, psk, hydro_kx_PSKBYTES);
|
|
||||||
hydro_kx_eph_keygen(&state, &state.eph_kp);
|
|
||||||
if (hydro_kx_dh(&state, state.eph_kp.sk, peer_static_pk) != 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
hydro_kx_aead_encrypt(&state, packet1_mac, NULL, 0);
|
|
||||||
memcpy(packet1_eph_pk, state.eph_kp.pk, sizeof state.eph_kp.pk);
|
|
||||||
|
|
||||||
hydro_kx_final(&state, kp->rx, kp->tx);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
hydro_kx_n_2(hydro_kx_session_keypair *kp, const uint8_t packet1[hydro_kx_N_PACKET1BYTES],
|
|
||||||
const uint8_t psk[hydro_kx_PSKBYTES], const hydro_kx_keypair *static_kp)
|
|
||||||
{
|
|
||||||
hydro_kx_state state;
|
|
||||||
const uint8_t *peer_eph_pk = &packet1[0];
|
|
||||||
const uint8_t *packet1_mac = &packet1[hydro_kx_PUBLICKEYBYTES];
|
|
||||||
|
|
||||||
if (psk == NULL) {
|
|
||||||
psk = zero;
|
|
||||||
}
|
|
||||||
hydro_kx_init_state(&state, "Noise_Npsk0_hydro1");
|
|
||||||
hydro_hash_update(&state.h_st, static_kp->pk, hydro_kx_PUBLICKEYBYTES);
|
|
||||||
|
|
||||||
hydro_hash_update(&state.h_st, psk, hydro_kx_PSKBYTES);
|
|
||||||
hydro_hash_update(&state.h_st, peer_eph_pk, hydro_x25519_PUBLICKEYBYTES);
|
|
||||||
if (hydro_kx_dh(&state, static_kp->sk, peer_eph_pk) != 0 ||
|
|
||||||
hydro_kx_aead_decrypt(&state, NULL, packet1_mac, hydro_kx_AEAD_MACBYTES) != 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
hydro_kx_final(&state, kp->tx, kp->rx);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* NOISE_KK */
|
|
||||||
|
|
||||||
int
|
|
||||||
hydro_kx_kk_1(hydro_kx_state *state, uint8_t packet1[hydro_kx_KK_PACKET1BYTES],
|
|
||||||
const uint8_t peer_static_pk[hydro_kx_PUBLICKEYBYTES],
|
|
||||||
const hydro_kx_keypair *static_kp)
|
|
||||||
{
|
|
||||||
uint8_t *packet1_eph_pk = &packet1[0];
|
|
||||||
uint8_t *packet1_mac = &packet1[hydro_kx_PUBLICKEYBYTES];
|
|
||||||
|
|
||||||
hydro_kx_init_state(state, "Noise_KK_hydro1");
|
|
||||||
hydro_hash_update(&state->h_st, static_kp->pk, hydro_kx_PUBLICKEYBYTES);
|
|
||||||
hydro_hash_update(&state->h_st, peer_static_pk, hydro_kx_PUBLICKEYBYTES);
|
|
||||||
|
|
||||||
hydro_kx_eph_keygen(state, &state->eph_kp);
|
|
||||||
if (hydro_kx_dh(state, state->eph_kp.sk, peer_static_pk) != 0 ||
|
|
||||||
hydro_kx_dh(state, static_kp->sk, peer_static_pk) != 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
hydro_kx_aead_encrypt(state, packet1_mac, NULL, 0);
|
|
||||||
memcpy(packet1_eph_pk, state->eph_kp.pk, sizeof state->eph_kp.pk);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
hydro_kx_kk_2(hydro_kx_session_keypair *kp, uint8_t packet2[hydro_kx_KK_PACKET2BYTES],
|
|
||||||
const uint8_t packet1[hydro_kx_KK_PACKET1BYTES],
|
|
||||||
const uint8_t peer_static_pk[hydro_kx_PUBLICKEYBYTES],
|
|
||||||
const hydro_kx_keypair *static_kp)
|
|
||||||
{
|
|
||||||
hydro_kx_state state;
|
|
||||||
const uint8_t *peer_eph_pk = &packet1[0];
|
|
||||||
const uint8_t *packet1_mac = &packet1[hydro_kx_PUBLICKEYBYTES];
|
|
||||||
uint8_t *packet2_eph_pk = &packet2[0];
|
|
||||||
uint8_t *packet2_mac = &packet2[hydro_kx_PUBLICKEYBYTES];
|
|
||||||
|
|
||||||
hydro_kx_init_state(&state, "Noise_KK_hydro1");
|
|
||||||
hydro_hash_update(&state.h_st, peer_static_pk, hydro_kx_PUBLICKEYBYTES);
|
|
||||||
hydro_hash_update(&state.h_st, static_kp->pk, hydro_kx_PUBLICKEYBYTES);
|
|
||||||
|
|
||||||
hydro_hash_update(&state.h_st, peer_eph_pk, hydro_kx_PUBLICKEYBYTES);
|
|
||||||
if (hydro_kx_dh(&state, static_kp->sk, peer_eph_pk) != 0 ||
|
|
||||||
hydro_kx_dh(&state, static_kp->sk, peer_static_pk) != 0 ||
|
|
||||||
hydro_kx_aead_decrypt(&state, NULL, packet1_mac, hydro_kx_AEAD_MACBYTES) != 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
hydro_kx_eph_keygen(&state, &state.eph_kp);
|
|
||||||
if (hydro_kx_dh(&state, state.eph_kp.sk, peer_eph_pk) != 0 ||
|
|
||||||
hydro_kx_dh(&state, state.eph_kp.sk, peer_static_pk) != 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
hydro_kx_aead_encrypt(&state, packet2_mac, NULL, 0);
|
|
||||||
hydro_kx_final(&state, kp->tx, kp->rx);
|
|
||||||
memcpy(packet2_eph_pk, state.eph_kp.pk, sizeof state.eph_kp.pk);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
hydro_kx_kk_3(hydro_kx_state *state, hydro_kx_session_keypair *kp,
|
|
||||||
const uint8_t packet2[hydro_kx_KK_PACKET2BYTES], const hydro_kx_keypair *static_kp)
|
|
||||||
{
|
|
||||||
const uint8_t *peer_eph_pk = packet2;
|
|
||||||
const uint8_t *packet2_mac = &packet2[hydro_kx_PUBLICKEYBYTES];
|
|
||||||
|
|
||||||
hydro_hash_update(&state->h_st, peer_eph_pk, hydro_kx_PUBLICKEYBYTES);
|
|
||||||
if (hydro_kx_dh(state, state->eph_kp.sk, peer_eph_pk) != 0 ||
|
|
||||||
hydro_kx_dh(state, static_kp->sk, peer_eph_pk) != 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hydro_kx_aead_decrypt(state, NULL, packet2_mac, hydro_kx_AEAD_MACBYTES) != 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
hydro_kx_final(state, kp->rx, kp->tx);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* NOISE_XX */
|
|
||||||
|
|
||||||
int
|
|
||||||
hydro_kx_xx_1(hydro_kx_state *state, uint8_t packet1[hydro_kx_XX_PACKET1BYTES],
|
|
||||||
const uint8_t psk[hydro_kx_PSKBYTES])
|
|
||||||
{
|
|
||||||
uint8_t *packet1_eph_pk = &packet1[0];
|
|
||||||
uint8_t *packet1_mac = &packet1[hydro_kx_PUBLICKEYBYTES];
|
|
||||||
|
|
||||||
if (psk == NULL) {
|
|
||||||
psk = zero;
|
|
||||||
}
|
|
||||||
hydro_kx_init_state(state, "Noise_XXpsk0+psk3_hydro1");
|
|
||||||
|
|
||||||
hydro_kx_eph_keygen(state, &state->eph_kp);
|
|
||||||
hydro_hash_update(&state->h_st, psk, hydro_kx_PSKBYTES);
|
|
||||||
memcpy(packet1_eph_pk, state->eph_kp.pk, sizeof state->eph_kp.pk);
|
|
||||||
hydro_kx_aead_encrypt(state, packet1_mac, NULL, 0);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
hydro_kx_xx_2(hydro_kx_state *state, uint8_t packet2[hydro_kx_XX_PACKET2BYTES],
|
|
||||||
const uint8_t packet1[hydro_kx_XX_PACKET1BYTES], const uint8_t psk[hydro_kx_PSKBYTES],
|
|
||||||
const hydro_kx_keypair *static_kp)
|
|
||||||
{
|
|
||||||
const uint8_t *peer_eph_pk = &packet1[0];
|
|
||||||
const uint8_t *packet1_mac = &packet1[hydro_kx_PUBLICKEYBYTES];
|
|
||||||
uint8_t *packet2_eph_pk = &packet2[0];
|
|
||||||
uint8_t *packet2_enc_static_pk = &packet2[hydro_kx_PUBLICKEYBYTES];
|
|
||||||
uint8_t *packet2_mac =
|
|
||||||
&packet2[hydro_kx_PUBLICKEYBYTES + hydro_kx_PUBLICKEYBYTES + hydro_kx_AEAD_MACBYTES];
|
|
||||||
|
|
||||||
if (psk == NULL) {
|
|
||||||
psk = zero;
|
|
||||||
}
|
|
||||||
hydro_kx_init_state(state, "Noise_XXpsk0+psk3_hydro1");
|
|
||||||
|
|
||||||
hydro_hash_update(&state->h_st, peer_eph_pk, hydro_kx_PUBLICKEYBYTES);
|
|
||||||
hydro_hash_update(&state->h_st, psk, hydro_kx_PSKBYTES);
|
|
||||||
if (hydro_kx_aead_decrypt(state, NULL, packet1_mac, hydro_kx_AEAD_MACBYTES) != 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
hydro_kx_eph_keygen(state, &state->eph_kp);
|
|
||||||
if (hydro_kx_dh(state, state->eph_kp.sk, peer_eph_pk) != 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
hydro_kx_aead_encrypt(state, packet2_enc_static_pk, static_kp->pk, sizeof static_kp->pk);
|
|
||||||
if (hydro_kx_dh(state, static_kp->sk, peer_eph_pk) != 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
hydro_kx_aead_encrypt(state, packet2_mac, NULL, 0);
|
|
||||||
|
|
||||||
memcpy(packet2_eph_pk, state->eph_kp.pk, sizeof state->eph_kp.pk);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
hydro_kx_xx_3(hydro_kx_state *state, hydro_kx_session_keypair *kp,
|
|
||||||
uint8_t packet3[hydro_kx_XX_PACKET3BYTES],
|
|
||||||
uint8_t peer_static_pk[hydro_kx_PUBLICKEYBYTES],
|
|
||||||
const uint8_t packet2[hydro_kx_XX_PACKET2BYTES], const uint8_t psk[hydro_kx_PSKBYTES],
|
|
||||||
const hydro_kx_keypair *static_kp)
|
|
||||||
{
|
|
||||||
uint8_t peer_static_pk_[hydro_kx_PUBLICKEYBYTES];
|
|
||||||
const uint8_t *peer_eph_pk = &packet2[0];
|
|
||||||
const uint8_t *peer_enc_static_pk = &packet2[hydro_kx_PUBLICKEYBYTES];
|
|
||||||
const uint8_t *packet2_mac =
|
|
||||||
&packet2[hydro_kx_PUBLICKEYBYTES + hydro_kx_PUBLICKEYBYTES + hydro_kx_AEAD_MACBYTES];
|
|
||||||
uint8_t *packet3_enc_static_pk = &packet3[0];
|
|
||||||
uint8_t *packet3_mac = &packet3[hydro_kx_PUBLICKEYBYTES + hydro_kx_AEAD_MACBYTES];
|
|
||||||
|
|
||||||
if (psk == NULL) {
|
|
||||||
psk = zero;
|
|
||||||
}
|
|
||||||
if (peer_static_pk == NULL) {
|
|
||||||
peer_static_pk = peer_static_pk_;
|
|
||||||
}
|
|
||||||
hydro_hash_update(&state->h_st, peer_eph_pk, hydro_kx_PUBLICKEYBYTES);
|
|
||||||
if (hydro_kx_dh(state, state->eph_kp.sk, peer_eph_pk) != 0 ||
|
|
||||||
hydro_kx_aead_decrypt(state, peer_static_pk, peer_enc_static_pk,
|
|
||||||
hydro_kx_PUBLICKEYBYTES + hydro_kx_AEAD_MACBYTES) != 0 ||
|
|
||||||
hydro_kx_dh(state, state->eph_kp.sk, peer_static_pk) != 0 ||
|
|
||||||
hydro_kx_aead_decrypt(state, NULL, packet2_mac, hydro_kx_AEAD_MACBYTES) != 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
hydro_kx_aead_encrypt(state, packet3_enc_static_pk, static_kp->pk, sizeof static_kp->pk);
|
|
||||||
if (hydro_kx_dh(state, static_kp->sk, peer_eph_pk) != 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
hydro_hash_update(&state->h_st, psk, hydro_kx_PSKBYTES);
|
|
||||||
hydro_kx_aead_encrypt(state, packet3_mac, NULL, 0);
|
|
||||||
hydro_kx_final(state, kp->rx, kp->tx);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
hydro_kx_xx_4(hydro_kx_state *state, hydro_kx_session_keypair *kp,
|
|
||||||
uint8_t peer_static_pk[hydro_kx_PUBLICKEYBYTES],
|
|
||||||
const uint8_t packet3[hydro_kx_XX_PACKET3BYTES], const uint8_t psk[hydro_kx_PSKBYTES])
|
|
||||||
{
|
|
||||||
uint8_t peer_static_pk_[hydro_kx_PUBLICKEYBYTES];
|
|
||||||
const uint8_t *peer_enc_static_pk = &packet3[0];
|
|
||||||
const uint8_t *packet3_mac = &packet3[hydro_kx_PUBLICKEYBYTES + hydro_kx_AEAD_MACBYTES];
|
|
||||||
|
|
||||||
if (psk == NULL) {
|
|
||||||
psk = zero;
|
|
||||||
}
|
|
||||||
if (peer_static_pk == NULL) {
|
|
||||||
peer_static_pk = peer_static_pk_;
|
|
||||||
}
|
|
||||||
if (hydro_kx_aead_decrypt(state, peer_static_pk, peer_enc_static_pk,
|
|
||||||
hydro_kx_PUBLICKEYBYTES + hydro_kx_AEAD_MACBYTES) != 0 ||
|
|
||||||
hydro_kx_dh(state, state->eph_kp.sk, peer_static_pk) != 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
hydro_hash_update(&state->h_st, psk, hydro_kx_PSKBYTES);
|
|
||||||
if (hydro_kx_aead_decrypt(state, NULL, packet3_mac, hydro_kx_AEAD_MACBYTES) != 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
hydro_kx_final(state, kp->tx, kp->rx);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* NOISE_NK */
|
|
||||||
|
|
||||||
int
|
|
||||||
hydro_kx_nk_1(hydro_kx_state *state, uint8_t packet1[hydro_kx_NK_PACKET1BYTES],
|
|
||||||
const uint8_t psk[hydro_kx_PSKBYTES],
|
|
||||||
const uint8_t peer_static_pk[hydro_kx_PUBLICKEYBYTES])
|
|
||||||
{
|
|
||||||
uint8_t *packet1_eph_pk = &packet1[0];
|
|
||||||
uint8_t *packet1_mac = &packet1[hydro_kx_PUBLICKEYBYTES];
|
|
||||||
|
|
||||||
if (psk == NULL) {
|
|
||||||
psk = zero;
|
|
||||||
}
|
|
||||||
hydro_kx_init_state(state, "Noise_NKpsk0_hydro1");
|
|
||||||
hydro_hash_update(&state->h_st, peer_static_pk, hydro_x25519_PUBLICKEYBYTES);
|
|
||||||
|
|
||||||
hydro_hash_update(&state->h_st, psk, hydro_kx_PSKBYTES);
|
|
||||||
hydro_kx_eph_keygen(state, &state->eph_kp);
|
|
||||||
if (hydro_kx_dh(state, state->eph_kp.sk, peer_static_pk) != 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
hydro_kx_aead_encrypt(state, packet1_mac, NULL, 0);
|
|
||||||
memcpy(packet1_eph_pk, state->eph_kp.pk, sizeof state->eph_kp.pk);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
hydro_kx_nk_2(hydro_kx_session_keypair *kp, uint8_t packet2[hydro_kx_NK_PACKET2BYTES],
|
|
||||||
const uint8_t packet1[hydro_kx_NK_PACKET1BYTES], const uint8_t psk[hydro_kx_PSKBYTES],
|
|
||||||
const hydro_kx_keypair *static_kp)
|
|
||||||
{
|
|
||||||
hydro_kx_state state;
|
|
||||||
const uint8_t *peer_eph_pk = &packet1[0];
|
|
||||||
const uint8_t *packet1_mac = &packet1[hydro_kx_PUBLICKEYBYTES];
|
|
||||||
uint8_t *packet2_eph_pk = &packet2[0];
|
|
||||||
uint8_t *packet2_mac = &packet2[hydro_kx_PUBLICKEYBYTES];
|
|
||||||
|
|
||||||
if (psk == NULL) {
|
|
||||||
psk = zero;
|
|
||||||
}
|
|
||||||
hydro_kx_init_state(&state, "Noise_NKpsk0_hydro1");
|
|
||||||
hydro_hash_update(&state.h_st, static_kp->pk, hydro_kx_PUBLICKEYBYTES);
|
|
||||||
|
|
||||||
hydro_hash_update(&state.h_st, psk, hydro_kx_PSKBYTES);
|
|
||||||
hydro_hash_update(&state.h_st, peer_eph_pk, hydro_x25519_PUBLICKEYBYTES);
|
|
||||||
if (hydro_kx_dh(&state, static_kp->sk, peer_eph_pk) != 0 ||
|
|
||||||
hydro_kx_aead_decrypt(&state, NULL, packet1_mac, hydro_kx_AEAD_MACBYTES) != 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
hydro_kx_eph_keygen(&state, &state.eph_kp);
|
|
||||||
if (hydro_kx_dh(&state, state.eph_kp.sk, peer_eph_pk) != 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
hydro_kx_aead_encrypt(&state, packet2_mac, NULL, 0);
|
|
||||||
hydro_kx_final(&state, kp->tx, kp->rx);
|
|
||||||
memcpy(packet2_eph_pk, state.eph_kp.pk, sizeof state.eph_kp.pk);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
hydro_kx_nk_3(hydro_kx_state *state, hydro_kx_session_keypair *kp,
|
|
||||||
const uint8_t packet2[hydro_kx_NK_PACKET2BYTES])
|
|
||||||
{
|
|
||||||
const uint8_t *peer_eph_pk = &packet2[0];
|
|
||||||
const uint8_t *packet2_mac = &packet2[hydro_kx_PUBLICKEYBYTES];
|
|
||||||
|
|
||||||
hydro_hash_update(&state->h_st, peer_eph_pk, hydro_x25519_PUBLICKEYBYTES);
|
|
||||||
if (hydro_kx_dh(state, state->eph_kp.sk, peer_eph_pk) != 0 ||
|
|
||||||
hydro_kx_aead_decrypt(state, NULL, packet2_mac, hydro_kx_AEAD_MACBYTES) != 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
hydro_kx_final(state, kp->rx, kp->tx);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@ -1,281 +0,0 @@
|
|||||||
#define hydro_pwhash_ENC_ALGBYTES 1
|
|
||||||
#define hydro_pwhash_HASH_ALGBYTES 1
|
|
||||||
#define hydro_pwhash_THREADSBYTES 1
|
|
||||||
#define hydro_pwhash_OPSLIMITBYTES 8
|
|
||||||
#define hydro_pwhash_MEMLIMITBYTES 8
|
|
||||||
#define hydro_pwhash_HASHBYTES 32
|
|
||||||
#define hydro_pwhash_SALTBYTES 16
|
|
||||||
#define hydro_pwhash_PARAMSBYTES \
|
|
||||||
(hydro_pwhash_HASH_ALGBYTES + hydro_pwhash_THREADSBYTES + hydro_pwhash_OPSLIMITBYTES + \
|
|
||||||
hydro_pwhash_MEMLIMITBYTES + hydro_pwhash_SALTBYTES + hydro_pwhash_HASHBYTES)
|
|
||||||
#define hydro_pwhash_ENC_ALG 0x01
|
|
||||||
#define hydro_pwhash_HASH_ALG 0x01
|
|
||||||
#define hydro_pwhash_CONTEXT "hydro_pw"
|
|
||||||
|
|
||||||
static int
|
|
||||||
_hydro_pwhash_hash(uint8_t out[hydro_random_SEEDBYTES], size_t h_len,
|
|
||||||
const uint8_t salt[hydro_pwhash_SALTBYTES], const char *passwd,
|
|
||||||
size_t passwd_len, const char ctx[hydro_pwhash_CONTEXTBYTES],
|
|
||||||
const uint8_t master_key[hydro_pwhash_MASTERKEYBYTES], uint64_t opslimit,
|
|
||||||
size_t memlimit, uint8_t threads)
|
|
||||||
{
|
|
||||||
_hydro_attr_aligned_(16) uint8_t state[gimli_BLOCKBYTES];
|
|
||||||
hydro_hash_state h_st;
|
|
||||||
uint8_t tmp64_u8[8];
|
|
||||||
uint64_t i;
|
|
||||||
uint8_t tmp8;
|
|
||||||
|
|
||||||
COMPILER_ASSERT(hydro_pwhash_MASTERKEYBYTES >= hydro_hash_KEYBYTES);
|
|
||||||
hydro_hash_init(&h_st, ctx, master_key);
|
|
||||||
|
|
||||||
STORE64_LE(tmp64_u8, (uint64_t) passwd_len);
|
|
||||||
hydro_hash_update(&h_st, tmp64_u8, sizeof tmp64_u8);
|
|
||||||
hydro_hash_update(&h_st, passwd, passwd_len);
|
|
||||||
|
|
||||||
hydro_hash_update(&h_st, salt, hydro_pwhash_SALTBYTES);
|
|
||||||
|
|
||||||
tmp8 = hydro_pwhash_HASH_ALG;
|
|
||||||
hydro_hash_update(&h_st, &tmp8, 1);
|
|
||||||
|
|
||||||
hydro_hash_update(&h_st, &threads, 1);
|
|
||||||
|
|
||||||
STORE64_LE(tmp64_u8, (uint64_t) memlimit);
|
|
||||||
hydro_hash_update(&h_st, tmp64_u8, sizeof tmp64_u8);
|
|
||||||
|
|
||||||
STORE64_LE(tmp64_u8, (uint64_t) h_len);
|
|
||||||
hydro_hash_update(&h_st, tmp64_u8, sizeof tmp64_u8);
|
|
||||||
|
|
||||||
hydro_hash_final(&h_st, (uint8_t *) (void *) &state, sizeof state);
|
|
||||||
|
|
||||||
gimli_core_u8(state, 1);
|
|
||||||
COMPILER_ASSERT(gimli_RATE >= 8);
|
|
||||||
for (i = 0; i < opslimit; i++) {
|
|
||||||
mem_zero(state, gimli_RATE);
|
|
||||||
STORE64_LE(state, i);
|
|
||||||
gimli_core_u8(state, 0);
|
|
||||||
}
|
|
||||||
mem_zero(state, gimli_RATE);
|
|
||||||
|
|
||||||
COMPILER_ASSERT(hydro_random_SEEDBYTES == gimli_CAPACITY);
|
|
||||||
memcpy(out, state + gimli_RATE, hydro_random_SEEDBYTES);
|
|
||||||
hydro_memzero(state, sizeof state);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
hydro_pwhash_keygen(uint8_t master_key[hydro_pwhash_MASTERKEYBYTES])
|
|
||||||
{
|
|
||||||
hydro_random_buf(master_key, hydro_pwhash_MASTERKEYBYTES);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
hydro_pwhash_deterministic(uint8_t *h, size_t h_len, const char *passwd, size_t passwd_len,
|
|
||||||
const char ctx[hydro_pwhash_CONTEXTBYTES],
|
|
||||||
const uint8_t master_key[hydro_pwhash_MASTERKEYBYTES], uint64_t opslimit,
|
|
||||||
size_t memlimit, uint8_t threads)
|
|
||||||
{
|
|
||||||
uint8_t seed[hydro_random_SEEDBYTES];
|
|
||||||
|
|
||||||
COMPILER_ASSERT(sizeof zero >= hydro_pwhash_SALTBYTES);
|
|
||||||
COMPILER_ASSERT(sizeof zero >= hydro_pwhash_MASTERKEYBYTES);
|
|
||||||
|
|
||||||
(void) memlimit;
|
|
||||||
if (_hydro_pwhash_hash(seed, h_len, zero, passwd, passwd_len, ctx, master_key, opslimit,
|
|
||||||
memlimit, threads) != 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
hydro_random_buf_deterministic(h, h_len, seed);
|
|
||||||
hydro_memzero(seed, sizeof seed);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
hydro_pwhash_create(uint8_t stored[hydro_pwhash_STOREDBYTES], const char *passwd, size_t passwd_len,
|
|
||||||
const uint8_t master_key[hydro_pwhash_MASTERKEYBYTES], uint64_t opslimit,
|
|
||||||
size_t memlimit, uint8_t threads)
|
|
||||||
{
|
|
||||||
uint8_t *const enc_alg = &stored[0];
|
|
||||||
uint8_t *const secretbox = &enc_alg[hydro_pwhash_ENC_ALGBYTES];
|
|
||||||
uint8_t *const hash_alg = &secretbox[hydro_secretbox_HEADERBYTES];
|
|
||||||
uint8_t *const threads_u8 = &hash_alg[hydro_pwhash_HASH_ALGBYTES];
|
|
||||||
uint8_t *const opslimit_u8 = &threads_u8[hydro_pwhash_THREADSBYTES];
|
|
||||||
uint8_t *const memlimit_u8 = &opslimit_u8[hydro_pwhash_OPSLIMITBYTES];
|
|
||||||
uint8_t *const salt = &memlimit_u8[hydro_pwhash_MEMLIMITBYTES];
|
|
||||||
uint8_t *const h = &salt[hydro_pwhash_SALTBYTES];
|
|
||||||
|
|
||||||
COMPILER_ASSERT(hydro_pwhash_STOREDBYTES >= hydro_pwhash_ENC_ALGBYTES +
|
|
||||||
hydro_secretbox_HEADERBYTES +
|
|
||||||
hydro_pwhash_PARAMSBYTES);
|
|
||||||
(void) memlimit;
|
|
||||||
mem_zero(stored, hydro_pwhash_STOREDBYTES);
|
|
||||||
*enc_alg = hydro_pwhash_ENC_ALG;
|
|
||||||
*hash_alg = hydro_pwhash_HASH_ALG;
|
|
||||||
*threads_u8 = threads;
|
|
||||||
STORE64_LE(opslimit_u8, opslimit);
|
|
||||||
STORE64_LE(memlimit_u8, (uint64_t) memlimit);
|
|
||||||
hydro_random_buf(salt, hydro_pwhash_SALTBYTES);
|
|
||||||
|
|
||||||
COMPILER_ASSERT(sizeof zero >= hydro_pwhash_MASTERKEYBYTES);
|
|
||||||
if (_hydro_pwhash_hash(h, hydro_pwhash_HASHBYTES, salt, passwd, passwd_len,
|
|
||||||
hydro_pwhash_CONTEXT, zero, opslimit, memlimit, threads) != 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
COMPILER_ASSERT(hydro_pwhash_MASTERKEYBYTES == hydro_secretbox_KEYBYTES);
|
|
||||||
|
|
||||||
return hydro_secretbox_encrypt(secretbox, hash_alg, hydro_pwhash_PARAMSBYTES,
|
|
||||||
(uint64_t) *enc_alg, hydro_pwhash_CONTEXT, master_key);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
_hydro_pwhash_verify(uint8_t computed_h[hydro_pwhash_HASHBYTES],
|
|
||||||
const uint8_t stored[hydro_pwhash_STOREDBYTES], const char *passwd,
|
|
||||||
size_t passwd_len, const uint8_t master_key[hydro_pwhash_MASTERKEYBYTES],
|
|
||||||
uint64_t opslimit_max, size_t memlimit_max, uint8_t threads_max)
|
|
||||||
{
|
|
||||||
const uint8_t *const enc_alg = &stored[0];
|
|
||||||
const uint8_t *const secretbox = &enc_alg[hydro_pwhash_ENC_ALGBYTES];
|
|
||||||
|
|
||||||
uint8_t params[hydro_pwhash_PARAMSBYTES];
|
|
||||||
uint8_t *const hash_alg = ¶ms[0];
|
|
||||||
uint8_t *const threads_u8 = &hash_alg[hydro_pwhash_HASH_ALGBYTES];
|
|
||||||
uint8_t *const opslimit_u8 = &threads_u8[hydro_pwhash_THREADSBYTES];
|
|
||||||
uint8_t *const memlimit_u8 = &opslimit_u8[hydro_pwhash_OPSLIMITBYTES];
|
|
||||||
uint8_t *const salt = &memlimit_u8[hydro_pwhash_MEMLIMITBYTES];
|
|
||||||
uint8_t *const h = &salt[hydro_pwhash_SALTBYTES];
|
|
||||||
|
|
||||||
uint64_t opslimit;
|
|
||||||
size_t memlimit;
|
|
||||||
uint8_t threads;
|
|
||||||
|
|
||||||
(void) memlimit;
|
|
||||||
if (*enc_alg != hydro_pwhash_ENC_ALG) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (hydro_secretbox_decrypt(params, secretbox,
|
|
||||||
hydro_secretbox_HEADERBYTES + hydro_pwhash_PARAMSBYTES,
|
|
||||||
(uint64_t) *enc_alg, hydro_pwhash_CONTEXT, master_key) != 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (*hash_alg != hydro_pwhash_HASH_ALG || (opslimit = LOAD64_LE(opslimit_u8)) > opslimit_max ||
|
|
||||||
(memlimit = (size_t) LOAD64_LE(memlimit_u8)) > memlimit_max ||
|
|
||||||
(threads = *threads_u8) > threads_max) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (_hydro_pwhash_hash(computed_h, hydro_pwhash_HASHBYTES, salt, passwd, passwd_len,
|
|
||||||
hydro_pwhash_CONTEXT, zero, opslimit, memlimit, threads) == 0 &&
|
|
||||||
hydro_equal(computed_h, h, hydro_pwhash_HASHBYTES) == 1) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
hydro_pwhash_verify(const uint8_t stored[hydro_pwhash_STOREDBYTES], const char *passwd,
|
|
||||||
size_t passwd_len, const uint8_t master_key[hydro_pwhash_MASTERKEYBYTES],
|
|
||||||
uint64_t opslimit_max, size_t memlimit_max, uint8_t threads_max)
|
|
||||||
{
|
|
||||||
uint8_t computed_h[hydro_pwhash_HASHBYTES];
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = _hydro_pwhash_verify(computed_h, stored, passwd, passwd_len, master_key, opslimit_max,
|
|
||||||
memlimit_max, threads_max);
|
|
||||||
hydro_memzero(computed_h, sizeof computed_h);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
hydro_pwhash_derive_static_key(uint8_t *static_key, size_t static_key_len,
|
|
||||||
const uint8_t stored[hydro_pwhash_STOREDBYTES], const char *passwd,
|
|
||||||
size_t passwd_len, const char ctx[hydro_pwhash_CONTEXTBYTES],
|
|
||||||
const uint8_t master_key[hydro_pwhash_MASTERKEYBYTES],
|
|
||||||
uint64_t opslimit_max, size_t memlimit_max, uint8_t threads_max)
|
|
||||||
{
|
|
||||||
uint8_t computed_h[hydro_pwhash_HASHBYTES];
|
|
||||||
|
|
||||||
if (_hydro_pwhash_verify(computed_h, stored, passwd, passwd_len, master_key, opslimit_max,
|
|
||||||
memlimit_max, threads_max) != 0) {
|
|
||||||
hydro_memzero(computed_h, sizeof computed_h);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
COMPILER_ASSERT(hydro_kdf_CONTEXTBYTES <= hydro_pwhash_CONTEXTBYTES);
|
|
||||||
COMPILER_ASSERT(hydro_kdf_KEYBYTES <= hydro_pwhash_HASHBYTES);
|
|
||||||
hydro_kdf_derive_from_key(static_key, static_key_len, 0, ctx, computed_h);
|
|
||||||
hydro_memzero(computed_h, sizeof computed_h);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
hydro_pwhash_reencrypt(uint8_t stored[hydro_pwhash_STOREDBYTES],
|
|
||||||
const uint8_t master_key[hydro_pwhash_MASTERKEYBYTES],
|
|
||||||
const uint8_t new_master_key[hydro_pwhash_MASTERKEYBYTES])
|
|
||||||
{
|
|
||||||
uint8_t *const enc_alg = &stored[0];
|
|
||||||
uint8_t *const secretbox = &enc_alg[hydro_pwhash_ENC_ALGBYTES];
|
|
||||||
uint8_t *const params = &secretbox[hydro_secretbox_HEADERBYTES];
|
|
||||||
|
|
||||||
if (*enc_alg != hydro_pwhash_ENC_ALG) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (hydro_secretbox_decrypt(secretbox, secretbox,
|
|
||||||
hydro_secretbox_HEADERBYTES + hydro_pwhash_PARAMSBYTES,
|
|
||||||
(uint64_t) *enc_alg, hydro_pwhash_CONTEXT, master_key) != 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
memmove(params, secretbox, hydro_pwhash_PARAMSBYTES);
|
|
||||||
return hydro_secretbox_encrypt(secretbox, params, hydro_pwhash_PARAMSBYTES, (uint64_t) *enc_alg,
|
|
||||||
hydro_pwhash_CONTEXT, new_master_key);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
hydro_pwhash_upgrade(uint8_t stored[hydro_pwhash_STOREDBYTES],
|
|
||||||
const uint8_t master_key[hydro_pwhash_MASTERKEYBYTES], uint64_t opslimit,
|
|
||||||
size_t memlimit, uint8_t threads)
|
|
||||||
{
|
|
||||||
uint8_t *const enc_alg = &stored[0];
|
|
||||||
uint8_t *const secretbox = &enc_alg[hydro_pwhash_ENC_ALGBYTES];
|
|
||||||
uint8_t *const params = &secretbox[hydro_secretbox_HEADERBYTES];
|
|
||||||
uint8_t *const hash_alg = ¶ms[0];
|
|
||||||
uint8_t *const threads_u8 = &hash_alg[hydro_pwhash_HASH_ALGBYTES];
|
|
||||||
uint8_t *const opslimit_u8 = &threads_u8[hydro_pwhash_THREADSBYTES];
|
|
||||||
uint8_t *const memlimit_u8 = &opslimit_u8[hydro_pwhash_OPSLIMITBYTES];
|
|
||||||
uint8_t *const salt = &memlimit_u8[hydro_pwhash_MEMLIMITBYTES];
|
|
||||||
uint8_t *const h = &salt[hydro_pwhash_SALTBYTES];
|
|
||||||
|
|
||||||
_hydro_attr_aligned_(16) uint8_t state[gimli_BLOCKBYTES];
|
|
||||||
uint64_t i;
|
|
||||||
uint64_t opslimit_prev;
|
|
||||||
|
|
||||||
if (*enc_alg != hydro_pwhash_ENC_ALG) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (hydro_secretbox_decrypt(secretbox, secretbox,
|
|
||||||
hydro_secretbox_HEADERBYTES + hydro_pwhash_PARAMSBYTES,
|
|
||||||
(uint64_t) *enc_alg, hydro_pwhash_CONTEXT, master_key) != 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
memmove(params, secretbox, hydro_pwhash_PARAMSBYTES);
|
|
||||||
opslimit_prev = LOAD64_LE(opslimit_u8);
|
|
||||||
if (*hash_alg != hydro_pwhash_HASH_ALG) {
|
|
||||||
mem_zero(stored, hydro_pwhash_STOREDBYTES);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
COMPILER_ASSERT(hydro_random_SEEDBYTES == gimli_CAPACITY);
|
|
||||||
memcpy(state + gimli_RATE, h, hydro_random_SEEDBYTES);
|
|
||||||
for (i = opslimit_prev; i < opslimit; i++) {
|
|
||||||
mem_zero(state, gimli_RATE);
|
|
||||||
STORE64_LE(state, i);
|
|
||||||
gimli_core_u8(state, 0);
|
|
||||||
}
|
|
||||||
mem_zero(state, gimli_RATE);
|
|
||||||
memcpy(h, state + gimli_RATE, hydro_random_SEEDBYTES);
|
|
||||||
*threads_u8 = threads;
|
|
||||||
STORE64_LE(opslimit_u8, opslimit);
|
|
||||||
STORE64_LE(memlimit_u8, (uint64_t) memlimit);
|
|
||||||
|
|
||||||
return hydro_secretbox_encrypt(secretbox, params, hydro_pwhash_PARAMSBYTES, (uint64_t) *enc_alg,
|
|
||||||
hydro_pwhash_CONTEXT, master_key);
|
|
||||||
}
|
|
||||||
@ -1,162 +0,0 @@
|
|||||||
static TLS struct {
|
|
||||||
_hydro_attr_aligned_(16) uint8_t state[gimli_BLOCKBYTES];
|
|
||||||
uint64_t counter;
|
|
||||||
uint8_t initialized;
|
|
||||||
uint8_t available;
|
|
||||||
} hydro_random_context;
|
|
||||||
|
|
||||||
#if defined(AVR) && !defined(__unix__)
|
|
||||||
# include "random/avr.h"
|
|
||||||
#elif (defined(ESP32) || defined(ESP8266)) && !defined(__unix__)
|
|
||||||
# include "random/esp32.h"
|
|
||||||
#elif defined(PARTICLE) && defined(PLATFORM_ID) && PLATFORM_ID > 2 && !defined(__unix__)
|
|
||||||
# include "random/particle.h"
|
|
||||||
#elif defined(__ZEPHYR__)
|
|
||||||
# include "random/zephyr.h"
|
|
||||||
#elif (defined(NRF52832_XXAA) || defined(NRF52832_XXAB)) && !defined(__unix__)
|
|
||||||
# include "random/nrf52832.h"
|
|
||||||
#elif defined(_WIN32)
|
|
||||||
# include "random/windows.h"
|
|
||||||
#elif defined(__wasi__)
|
|
||||||
# include "random/wasi.h"
|
|
||||||
#elif defined(__linux__) && defined(__KERNEL__)
|
|
||||||
# include "random/linux_kernel.h"
|
|
||||||
#elif defined(__unix__)
|
|
||||||
# include "random/unix.h"
|
|
||||||
#elif defined(TARGET_LIKE_MBED)
|
|
||||||
# include "random/mbed.h"
|
|
||||||
#elif defined(RIOT_VERSION)
|
|
||||||
# include "random/riot.h"
|
|
||||||
#elif defined(STM32F4) || defined(STM32L4)
|
|
||||||
# include "random/stm32.h"
|
|
||||||
#elif defined(__RTTHREAD__)
|
|
||||||
# include "random/rtthread.h"
|
|
||||||
#elif defined(CH32V30x_D8) || defined(CH32V30x_D8C)
|
|
||||||
# include "random/ch32.h"
|
|
||||||
#elif defined(CHIBIOS)
|
|
||||||
# include "random/chibios.h"
|
|
||||||
#elif defined(__CHERIOT__)
|
|
||||||
# include "random/cheriot.h"
|
|
||||||
#elif defined(PICO_BUILD)
|
|
||||||
# ifndef LIB_PICO_RAND
|
|
||||||
# error pico-sdk detected but pico_rand not configured
|
|
||||||
# endif
|
|
||||||
# include "random/pico-sdk.h"
|
|
||||||
#else
|
|
||||||
# error Unsupported platform
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void
|
|
||||||
hydro_random_ensure_initialized(void)
|
|
||||||
{
|
|
||||||
if (hydro_random_context.initialized == 0) {
|
|
||||||
if (hydro_random_init() != 0) {
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
gimli_core_u8(hydro_random_context.state, 0);
|
|
||||||
hydro_random_ratchet();
|
|
||||||
hydro_random_context.initialized = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
hydro_random_ratchet(void)
|
|
||||||
{
|
|
||||||
mem_zero(hydro_random_context.state, gimli_RATE);
|
|
||||||
STORE64_LE(hydro_random_context.state, hydro_random_context.counter);
|
|
||||||
hydro_random_context.counter++;
|
|
||||||
gimli_core_u8(hydro_random_context.state, 0);
|
|
||||||
hydro_random_context.available = gimli_RATE;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t
|
|
||||||
hydro_random_u32(void)
|
|
||||||
{
|
|
||||||
uint32_t v;
|
|
||||||
|
|
||||||
hydro_random_ensure_initialized();
|
|
||||||
if (hydro_random_context.available < 4) {
|
|
||||||
hydro_random_ratchet();
|
|
||||||
}
|
|
||||||
memcpy(&v, &hydro_random_context.state[gimli_RATE - hydro_random_context.available], 4);
|
|
||||||
hydro_random_context.available -= 4;
|
|
||||||
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t
|
|
||||||
hydro_random_uniform(const uint32_t upper_bound)
|
|
||||||
{
|
|
||||||
uint32_t min;
|
|
||||||
uint32_t r;
|
|
||||||
|
|
||||||
if (upper_bound < 2U) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
min = (1U + ~upper_bound) % upper_bound; /* = 2**32 mod upper_bound */
|
|
||||||
do {
|
|
||||||
r = hydro_random_u32();
|
|
||||||
} while (r < min);
|
|
||||||
/* r is now clamped to a set whose size mod upper_bound == 0
|
|
||||||
* the worst case (2**31+1) requires 2 attempts on average */
|
|
||||||
|
|
||||||
return r % upper_bound;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
hydro_random_buf(void *out, size_t out_len)
|
|
||||||
{
|
|
||||||
uint8_t *p = (uint8_t *) out;
|
|
||||||
size_t i;
|
|
||||||
size_t leftover;
|
|
||||||
|
|
||||||
hydro_random_ensure_initialized();
|
|
||||||
for (i = 0; i < out_len / gimli_RATE; i++) {
|
|
||||||
gimli_core_u8(hydro_random_context.state, 0);
|
|
||||||
memcpy(p + i * gimli_RATE, hydro_random_context.state, gimli_RATE);
|
|
||||||
}
|
|
||||||
leftover = out_len % gimli_RATE;
|
|
||||||
if (leftover != 0) {
|
|
||||||
gimli_core_u8(hydro_random_context.state, 0);
|
|
||||||
mem_cpy(p + i * gimli_RATE, hydro_random_context.state, leftover);
|
|
||||||
}
|
|
||||||
hydro_random_ratchet();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
hydro_random_buf_deterministic(void *out, size_t out_len,
|
|
||||||
const uint8_t seed[hydro_random_SEEDBYTES])
|
|
||||||
{
|
|
||||||
static const uint8_t prefix[] = { 7, 'd', 'r', 'b', 'g', '2', '5', '6' };
|
|
||||||
_hydro_attr_aligned_(16) uint8_t state[gimli_BLOCKBYTES];
|
|
||||||
uint8_t *p = (uint8_t *) out;
|
|
||||||
size_t i;
|
|
||||||
size_t leftover;
|
|
||||||
|
|
||||||
mem_zero(state, gimli_BLOCKBYTES);
|
|
||||||
COMPILER_ASSERT(sizeof prefix + 8 <= gimli_RATE);
|
|
||||||
memcpy(state, prefix, sizeof prefix);
|
|
||||||
STORE64_LE(state + sizeof prefix, (uint64_t) out_len);
|
|
||||||
gimli_core_u8(state, 1);
|
|
||||||
COMPILER_ASSERT(hydro_random_SEEDBYTES == gimli_RATE * 2);
|
|
||||||
mem_xor(state, seed, gimli_RATE);
|
|
||||||
gimli_core_u8(state, 2);
|
|
||||||
mem_xor(state, seed + gimli_RATE, gimli_RATE);
|
|
||||||
gimli_core_u8(state, 2);
|
|
||||||
for (i = 0; i < out_len / gimli_RATE; i++) {
|
|
||||||
gimli_core_u8(state, 0);
|
|
||||||
memcpy(p + i * gimli_RATE, state, gimli_RATE);
|
|
||||||
}
|
|
||||||
leftover = out_len % gimli_RATE;
|
|
||||||
if (leftover != 0) {
|
|
||||||
gimli_core_u8(state, 0);
|
|
||||||
mem_cpy(p + i * gimli_RATE, state, leftover);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
hydro_random_reseed(void)
|
|
||||||
{
|
|
||||||
hydro_random_context.initialized = 0;
|
|
||||||
hydro_random_ensure_initialized();
|
|
||||||
}
|
|
||||||
@ -1,63 +0,0 @@
|
|||||||
#include <Arduino.h>
|
|
||||||
|
|
||||||
static bool
|
|
||||||
hydro_random_rbit(uint16_t x)
|
|
||||||
{
|
|
||||||
uint8_t x8;
|
|
||||||
|
|
||||||
x8 = ((uint8_t) (x >> 8)) ^ (uint8_t) x;
|
|
||||||
x8 = (x8 >> 4) ^ (x8 & 0xf);
|
|
||||||
x8 = (x8 >> 2) ^ (x8 & 0x3);
|
|
||||||
x8 = (x8 >> 1) ^ x8;
|
|
||||||
|
|
||||||
return (bool) (x8 & 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
hydro_random_init(void)
|
|
||||||
{
|
|
||||||
const char ctx[hydro_hash_CONTEXTBYTES] = { 'h', 'y', 'd', 'r', 'o', 'P', 'R', 'G' };
|
|
||||||
hydro_hash_state st;
|
|
||||||
uint16_t ebits = 0;
|
|
||||||
uint16_t tc;
|
|
||||||
bool a, b;
|
|
||||||
|
|
||||||
cli();
|
|
||||||
MCUSR = 0;
|
|
||||||
WDTCSR |= _BV(WDCE) | _BV(WDE);
|
|
||||||
WDTCSR = _BV(WDIE);
|
|
||||||
sei();
|
|
||||||
|
|
||||||
hydro_hash_init(&st, ctx, NULL);
|
|
||||||
|
|
||||||
while (ebits < 256) {
|
|
||||||
delay(1);
|
|
||||||
tc = TCNT1;
|
|
||||||
hydro_hash_update(&st, (const uint8_t *) &tc, sizeof tc);
|
|
||||||
a = hydro_random_rbit(tc);
|
|
||||||
delay(1);
|
|
||||||
tc = TCNT1;
|
|
||||||
b = hydro_random_rbit(tc);
|
|
||||||
hydro_hash_update(&st, (const uint8_t *) &tc, sizeof tc);
|
|
||||||
if (a == b) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
hydro_hash_update(&st, (const uint8_t *) &b, sizeof b);
|
|
||||||
ebits++;
|
|
||||||
}
|
|
||||||
|
|
||||||
cli();
|
|
||||||
MCUSR = 0;
|
|
||||||
WDTCSR |= _BV(WDCE) | _BV(WDE);
|
|
||||||
WDTCSR = 0;
|
|
||||||
sei();
|
|
||||||
|
|
||||||
hydro_hash_final(&st, hydro_random_context.state, sizeof hydro_random_context.state);
|
|
||||||
hydro_random_context.counter = ~LOAD64_LE(hydro_random_context.state);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
ISR(WDT_vect)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
@ -1,35 +0,0 @@
|
|||||||
#if defined(CH32V30x_D8) || defined(CH32V30x_D8C)
|
|
||||||
# include <ch32v30x_rng.h>
|
|
||||||
#else
|
|
||||||
# error CH32 implementation missing!
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static int
|
|
||||||
hydro_random_init(void)
|
|
||||||
{
|
|
||||||
const char ctx[hydro_hash_CONTEXTBYTES] = { 'h', 'y', 'd', 'r', 'o', 'P', 'R', 'G' };
|
|
||||||
hydro_hash_state st;
|
|
||||||
uint16_t ebits = 0;
|
|
||||||
|
|
||||||
// Enable RNG clock source
|
|
||||||
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_RNG, ENABLE);
|
|
||||||
|
|
||||||
// RNG Peripheral enable
|
|
||||||
RNG_Cmd(ENABLE);
|
|
||||||
|
|
||||||
hydro_hash_init(&st, ctx, NULL);
|
|
||||||
|
|
||||||
while (ebits < 256) {
|
|
||||||
while (RNG_GetFlagStatus(RNG_FLAG_DRDY) == RESET)
|
|
||||||
;
|
|
||||||
uint32_t r = RNG_GetRandomNumber();
|
|
||||||
|
|
||||||
hydro_hash_update(&st, (const uint32_t *) &r, sizeof r);
|
|
||||||
ebits += 32;
|
|
||||||
}
|
|
||||||
|
|
||||||
hydro_hash_final(&st, hydro_random_context.state, sizeof hydro_random_context.state);
|
|
||||||
hydro_random_context.counter = ~LOAD64_LE(hydro_random_context.state);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@ -1,22 +0,0 @@
|
|||||||
uint32_t rand_32();
|
|
||||||
|
|
||||||
static int
|
|
||||||
hydro_random_init(void)
|
|
||||||
{
|
|
||||||
const char ctx[hydro_hash_CONTEXTBYTES] = { 'h', 'y', 'd', 'r', 'o', 'P', 'R', 'G' };
|
|
||||||
hydro_hash_state st;
|
|
||||||
uint16_t ebits = 0;
|
|
||||||
|
|
||||||
hydro_hash_init(&st, ctx, NULL);
|
|
||||||
|
|
||||||
while (ebits < 256) {
|
|
||||||
uint32_t r = rand_32();
|
|
||||||
hydro_hash_update(&st, (const uint32_t *) &r, sizeof r);
|
|
||||||
ebits += 32;
|
|
||||||
}
|
|
||||||
|
|
||||||
hydro_hash_final(&st, hydro_random_context.state, sizeof hydro_random_context.state);
|
|
||||||
hydro_random_context.counter = ~LOAD64_LE(hydro_random_context.state);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@ -1,23 +0,0 @@
|
|||||||
#include <stdbool.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
/* Declarations from ChibiOS HAL TRNG module */
|
|
||||||
|
|
||||||
extern struct hal_trng_driver TRNGD1;
|
|
||||||
|
|
||||||
void trngStart(struct hal_trng_driver *, const void *);
|
|
||||||
bool trngGenerate(struct hal_trng_driver *, size_t size, uint8_t *);
|
|
||||||
|
|
||||||
static int
|
|
||||||
hydro_random_init(void)
|
|
||||||
{
|
|
||||||
trngStart(&TRNGD1, NULL);
|
|
||||||
|
|
||||||
if (trngGenerate(&TRNGD1, sizeof hydro_random_context.state, hydro_random_context.state)) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
hydro_random_context.counter = ~LOAD64_LE(hydro_random_context.state);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@ -1,32 +0,0 @@
|
|||||||
// Important: RF *must* be activated on ESP board
|
|
||||||
// https://techtutorialsx.com/2017/12/22/esp32-arduino-random-number-generation/
|
|
||||||
#ifdef ESP32
|
|
||||||
# include <esp_system.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef ARDUINO
|
|
||||||
# include <Arduino.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static int
|
|
||||||
hydro_random_init(void)
|
|
||||||
{
|
|
||||||
const char ctx[hydro_hash_CONTEXTBYTES] = { 'h', 'y', 'd', 'r', 'o', 'P', 'R', 'G' };
|
|
||||||
hydro_hash_state st;
|
|
||||||
uint16_t ebits = 0;
|
|
||||||
|
|
||||||
hydro_hash_init(&st, ctx, NULL);
|
|
||||||
|
|
||||||
while (ebits < 256) {
|
|
||||||
uint32_t r = esp_random();
|
|
||||||
|
|
||||||
delay(10);
|
|
||||||
hydro_hash_update(&st, (const uint32_t *) &r, sizeof r);
|
|
||||||
ebits += 32;
|
|
||||||
}
|
|
||||||
|
|
||||||
hydro_hash_final(&st, hydro_random_context.state, sizeof hydro_random_context.state);
|
|
||||||
hydro_random_context.counter = ~LOAD64_LE(hydro_random_context.state);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@ -1,8 +0,0 @@
|
|||||||
static int
|
|
||||||
hydro_random_init(void)
|
|
||||||
{
|
|
||||||
get_random_bytes(hydro_random_context.state, sizeof hydro_random_context.state);
|
|
||||||
hydro_random_context.counter = ~LOAD64_LE(hydro_random_context.state);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@ -1,44 +0,0 @@
|
|||||||
#include <mbedtls/ctr_drbg.h>
|
|
||||||
#include <mbedtls/entropy.h>
|
|
||||||
|
|
||||||
#if defined(MBEDTLS_ENTROPY_C)
|
|
||||||
|
|
||||||
static int
|
|
||||||
hydro_random_init(void)
|
|
||||||
{
|
|
||||||
mbedtls_entropy_context entropy;
|
|
||||||
uint16_t pos = 0;
|
|
||||||
|
|
||||||
mbedtls_entropy_init(&entropy);
|
|
||||||
|
|
||||||
// Pull data directly out of the entropy pool for the state, as it's small enough.
|
|
||||||
if (mbedtls_entropy_func(&entropy, (uint8_t *) &hydro_random_context.counter,
|
|
||||||
sizeof hydro_random_context.counter) != 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
// mbedtls_entropy_func can't provide more than MBEDTLS_ENTROPY_BLOCK_SIZE in one go.
|
|
||||||
// This constant depends of mbedTLS configuration (whether the PRNG is backed by SHA256/SHA512
|
|
||||||
// at this time) Therefore, if necessary, we get entropy multiple times.
|
|
||||||
|
|
||||||
do {
|
|
||||||
const uint8_t dataLeftToConsume = gimli_BLOCKBYTES - pos;
|
|
||||||
const uint8_t currentChunkSize = (dataLeftToConsume > MBEDTLS_ENTROPY_BLOCK_SIZE)
|
|
||||||
? MBEDTLS_ENTROPY_BLOCK_SIZE
|
|
||||||
: dataLeftToConsume;
|
|
||||||
|
|
||||||
// Forces mbedTLS to fetch fresh entropy, then get some to feed libhydrogen.
|
|
||||||
if (mbedtls_entropy_gather(&entropy) != 0 ||
|
|
||||||
mbedtls_entropy_func(&entropy, &hydro_random_context.state[pos], currentChunkSize) !=
|
|
||||||
0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
pos += MBEDTLS_ENTROPY_BLOCK_SIZE;
|
|
||||||
} while (pos < gimli_BLOCKBYTES);
|
|
||||||
|
|
||||||
mbedtls_entropy_free(&entropy);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
# error Need an entropy source
|
|
||||||
#endif
|
|
||||||
@ -1,41 +0,0 @@
|
|||||||
// Important: The SoftDevice *must* be activated to enable reading from the RNG
|
|
||||||
// http://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.nrf52832.ps.v1.1%2Frng.html
|
|
||||||
|
|
||||||
#include <nrf_soc.h>
|
|
||||||
|
|
||||||
static int
|
|
||||||
hydro_random_init(void)
|
|
||||||
{
|
|
||||||
const char ctx[hydro_hash_CONTEXTBYTES] = { 'h', 'y', 'd', 'r', 'o', 'P', 'R', 'G' };
|
|
||||||
hydro_hash_state st;
|
|
||||||
const uint8_t total_bytes = 32;
|
|
||||||
uint8_t remaining_bytes = total_bytes;
|
|
||||||
uint8_t available_bytes;
|
|
||||||
uint8_t rand_buffer[32];
|
|
||||||
|
|
||||||
hydro_hash_init(&st, ctx, NULL);
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
if (sd_rand_application_bytes_available_get(&available_bytes) != NRF_SUCCESS) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (available_bytes > 0) {
|
|
||||||
if (available_bytes > remaining_bytes) {
|
|
||||||
available_bytes = remaining_bytes;
|
|
||||||
}
|
|
||||||
if (sd_rand_application_vector_get(rand_buffer, available_bytes) != NRF_SUCCESS) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
hydro_hash_update(&st, rand_buffer, available_bytes);
|
|
||||||
remaining_bytes -= available_bytes;
|
|
||||||
}
|
|
||||||
if (remaining_bytes <= 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
delay(10);
|
|
||||||
}
|
|
||||||
hydro_hash_final(&st, hydro_random_context.state, sizeof hydro_random_context.state);
|
|
||||||
hydro_random_context.counter = ~LOAD64_LE(hydro_random_context.state);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
// Note: All particle platforms except for the Spark Core have a HW RNG. Only allow building on
|
|
||||||
// supported platforms for now. PLATFORM_ID definitions:
|
|
||||||
// https://github.com/particle-iot/device-os/blob/mesh-develop/hal/shared/platforms.h
|
|
||||||
|
|
||||||
#include <Particle.h>
|
|
||||||
|
|
||||||
static int
|
|
||||||
hydro_random_init(void)
|
|
||||||
{
|
|
||||||
const char ctx[hydro_hash_CONTEXTBYTES] = { 'h', 'y', 'd', 'r', 'o', 'P', 'R', 'G' };
|
|
||||||
hydro_hash_state st;
|
|
||||||
uint16_t ebits = 0;
|
|
||||||
|
|
||||||
hydro_hash_init(&st, ctx, NULL);
|
|
||||||
|
|
||||||
while (ebits < 256) {
|
|
||||||
uint32_t r = HAL_RNG_GetRandomNumber();
|
|
||||||
hydro_hash_update(&st, (const uint32_t *) &r, sizeof r);
|
|
||||||
ebits += 32;
|
|
||||||
}
|
|
||||||
|
|
||||||
hydro_hash_final(&st, hydro_random_context.state, sizeof hydro_random_context.state);
|
|
||||||
hydro_random_context.counter = ~LOAD64_LE(hydro_random_context.state);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@ -1,35 +0,0 @@
|
|||||||
#ifndef RANDOM_PICO_H_
|
|
||||||
#define RANDOM_PICO_H_
|
|
||||||
|
|
||||||
#include "pico/rand.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static int
|
|
||||||
hydro_random_init(void)
|
|
||||||
{
|
|
||||||
const char ctx[hydro_hash_CONTEXTBYTES] = { 'h', 'y', 'd', 'r', 'o', 'P', 'R', 'G' };
|
|
||||||
hydro_hash_state st;
|
|
||||||
uint16_t ebits = 0;
|
|
||||||
|
|
||||||
hydro_hash_init(&st, ctx, NULL);
|
|
||||||
|
|
||||||
while (ebits < 256) {
|
|
||||||
uint32_t r = get_rand_32();
|
|
||||||
hydro_hash_update(&st, (const uint32_t *) &r, sizeof r);
|
|
||||||
ebits += 32;
|
|
||||||
}
|
|
||||||
|
|
||||||
hydro_hash_final(&st, hydro_random_context.state, sizeof hydro_random_context.state);
|
|
||||||
hydro_random_context.counter = ~LOAD64_LE(hydro_random_context.state);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* RANDOM_PICO_H_ */
|
|
||||||
@ -1,10 +0,0 @@
|
|||||||
#include <random.h>
|
|
||||||
|
|
||||||
static int
|
|
||||||
hydro_random_init(void)
|
|
||||||
{
|
|
||||||
random_bytes(hydro_random_context.state, sizeof(hydro_random_context.state));
|
|
||||||
hydro_random_context.counter = ~LOAD64_LE(hydro_random_context.state);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@ -1,38 +0,0 @@
|
|||||||
#include <hw_rng.h>
|
|
||||||
#include <rtthread.h>
|
|
||||||
|
|
||||||
#define DBG_TAG "libhydrogen"
|
|
||||||
#define DBG_LVL DBG_LOG
|
|
||||||
#include <rtdbg.h>
|
|
||||||
|
|
||||||
static int
|
|
||||||
hydrogen_init(void)
|
|
||||||
{
|
|
||||||
if (hydro_init() != 0) {
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
LOG_I("libhydrogen initialized");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
INIT_APP_EXPORT(hydrogen_init);
|
|
||||||
|
|
||||||
static int
|
|
||||||
hydro_random_init(void)
|
|
||||||
{
|
|
||||||
const char ctx[hydro_hash_CONTEXTBYTES] = { 'h', 'y', 'd', 'r', 'o', 'P', 'R', 'G' };
|
|
||||||
hydro_hash_state st;
|
|
||||||
uint16_t ebits = 0;
|
|
||||||
|
|
||||||
hydro_hash_init(&st, ctx, NULL);
|
|
||||||
|
|
||||||
while (ebits < 256) {
|
|
||||||
uint32_t r = rt_hwcrypto_rng_update();
|
|
||||||
hydro_hash_update(&st, (const uint32_t *) &r, sizeof r);
|
|
||||||
ebits += 32;
|
|
||||||
}
|
|
||||||
|
|
||||||
hydro_hash_final(&st, hydro_random_context.state, sizeof hydro_random_context.state);
|
|
||||||
hydro_random_context.counter = ~LOAD64_LE(hydro_random_context.state);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@ -1,63 +0,0 @@
|
|||||||
|
|
||||||
// Use hardware RNG peripheral
|
|
||||||
// Working with HAL, LL Driver (untested)
|
|
||||||
#if defined(STM32F4) || defined(STM32L4)
|
|
||||||
|
|
||||||
# if defined(STM32F4)
|
|
||||||
# include "stm32f4xx.h"
|
|
||||||
# elif defined(STM32L4)
|
|
||||||
# include "stm32l4xx_hal_rng.h"
|
|
||||||
|
|
||||||
static RNG_HandleTypeDef RngHandle;
|
|
||||||
# endif
|
|
||||||
|
|
||||||
static int
|
|
||||||
hydro_random_init(void)
|
|
||||||
{
|
|
||||||
const char ctx[hydro_hash_CONTEXTBYTES] = { 'h', 'y', 'd', 'r', 'o', 'P', 'R', 'G' };
|
|
||||||
hydro_hash_state st;
|
|
||||||
uint16_t ebits = 0;
|
|
||||||
|
|
||||||
__IO uint32_t tmpreg;
|
|
||||||
|
|
||||||
# if defined(STM32F4)
|
|
||||||
// Enable RNG clock source
|
|
||||||
SET_BIT(RCC->AHB2ENR, RCC_AHB2ENR_RNGEN);
|
|
||||||
|
|
||||||
// Delay after an RCC peripheral clock enabling
|
|
||||||
tmpreg = READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_RNGEN);
|
|
||||||
UNUSED(tmpreg);
|
|
||||||
|
|
||||||
// RNG Peripheral enable
|
|
||||||
SET_BIT(RNG->CR, RNG_CR_RNGEN);
|
|
||||||
# elif defined(STM32L4)
|
|
||||||
RngHandle.Instance = RNG;
|
|
||||||
HAL_RNG_Init(&RngHandle);
|
|
||||||
# endif
|
|
||||||
|
|
||||||
hydro_hash_init(&st, ctx, NULL);
|
|
||||||
|
|
||||||
while (ebits < 256) {
|
|
||||||
uint32_t r = 0;
|
|
||||||
# if defined(STM32F4)
|
|
||||||
while (!(READ_BIT(RNG->SR, RNG_SR_DRDY))) {
|
|
||||||
}
|
|
||||||
|
|
||||||
r = RNG->DR;
|
|
||||||
# elif defined(STM32L4)
|
|
||||||
if (HAL_RNG_GenerateRandomNumber(&RngHandle, &r) != HAL_OK) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
# endif
|
|
||||||
hydro_hash_update(&st, (const uint32_t *) &r, sizeof r);
|
|
||||||
ebits += 32;
|
|
||||||
}
|
|
||||||
|
|
||||||
hydro_hash_final(&st, hydro_random_context.state, sizeof hydro_random_context.state);
|
|
||||||
hydro_random_context.counter = ~LOAD64_LE(hydro_random_context.state);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
# error SMT32 implementation missing!
|
|
||||||
#endif
|
|
||||||
@ -1,85 +0,0 @@
|
|||||||
#include <errno.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#ifdef __linux__
|
|
||||||
# include <poll.h>
|
|
||||||
#endif
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#ifdef __linux__
|
|
||||||
static int
|
|
||||||
hydro_random_block_on_dev_random(void)
|
|
||||||
{
|
|
||||||
struct pollfd pfd;
|
|
||||||
int fd;
|
|
||||||
int pret;
|
|
||||||
|
|
||||||
fd = open("/dev/random", O_RDONLY);
|
|
||||||
if (fd == -1) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
pfd.fd = fd;
|
|
||||||
pfd.events = POLLIN;
|
|
||||||
pfd.revents = 0;
|
|
||||||
do {
|
|
||||||
pret = poll(&pfd, 1, -1);
|
|
||||||
} while (pret < 0 && (errno == EINTR || errno == EAGAIN));
|
|
||||||
if (pret != 1) {
|
|
||||||
(void) close(fd);
|
|
||||||
errno = EIO;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return close(fd);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static ssize_t
|
|
||||||
hydro_random_safe_read(const int fd, void *const buf_, size_t len)
|
|
||||||
{
|
|
||||||
unsigned char *buf = (unsigned char *) buf_;
|
|
||||||
ssize_t readnb;
|
|
||||||
|
|
||||||
do {
|
|
||||||
while ((readnb = read(fd, buf, len)) < (ssize_t) 0 && (errno == EINTR || errno == EAGAIN)) {
|
|
||||||
}
|
|
||||||
if (readnb < (ssize_t) 0) {
|
|
||||||
return readnb;
|
|
||||||
}
|
|
||||||
if (readnb == (ssize_t) 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
len -= (size_t) readnb;
|
|
||||||
buf += readnb;
|
|
||||||
} while (len > (ssize_t) 0);
|
|
||||||
|
|
||||||
return (ssize_t) (buf - (unsigned char *) buf_);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
hydro_random_init(void)
|
|
||||||
{
|
|
||||||
uint8_t tmp[gimli_BLOCKBYTES + 8];
|
|
||||||
int fd;
|
|
||||||
int ret = -1;
|
|
||||||
|
|
||||||
#ifdef __linux__
|
|
||||||
if (hydro_random_block_on_dev_random() != 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
do {
|
|
||||||
fd = open("/dev/urandom", O_RDONLY);
|
|
||||||
if (fd == -1 && errno != EINTR) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
} while (fd == -1);
|
|
||||||
if (hydro_random_safe_read(fd, tmp, sizeof tmp) == (ssize_t) sizeof tmp) {
|
|
||||||
memcpy(hydro_random_context.state, tmp, gimli_BLOCKBYTES);
|
|
||||||
memcpy(&hydro_random_context.counter, tmp + gimli_BLOCKBYTES, 8);
|
|
||||||
hydro_memzero(tmp, sizeof tmp);
|
|
||||||
ret = 0;
|
|
||||||
}
|
|
||||||
ret |= close(fd);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
@ -1,12 +0,0 @@
|
|||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
static int
|
|
||||||
hydro_random_init(void)
|
|
||||||
{
|
|
||||||
if (getentropy(hydro_random_context.state, sizeof hydro_random_context.state) != 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
hydro_random_context.counter = ~LOAD64_LE(hydro_random_context.state);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@ -1,20 +0,0 @@
|
|||||||
#include <windows.h>
|
|
||||||
#define RtlGenRandom SystemFunction036
|
|
||||||
#if defined(__cplusplus)
|
|
||||||
extern "C"
|
|
||||||
#endif
|
|
||||||
BOOLEAN NTAPI
|
|
||||||
RtlGenRandom(PVOID RandomBuffer, ULONG RandomBufferLength);
|
|
||||||
#pragma comment(lib, "advapi32.lib")
|
|
||||||
|
|
||||||
static int
|
|
||||||
hydro_random_init(void)
|
|
||||||
{
|
|
||||||
if (!RtlGenRandom((PVOID) hydro_random_context.state,
|
|
||||||
(ULONG) sizeof hydro_random_context.state)) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
hydro_random_context.counter = ~LOAD64_LE(hydro_random_context.state);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@ -1,13 +0,0 @@
|
|||||||
#include <zephyr/random/random.h>
|
|
||||||
|
|
||||||
static int
|
|
||||||
hydro_random_init(void)
|
|
||||||
{
|
|
||||||
if (sys_csrand_get(&hydro_random_context.state, sizeof hydro_random_context.state) != 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
hydro_random_context.counter = ~LOAD64_LE(hydro_random_context.state);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@ -1,236 +0,0 @@
|
|||||||
#define hydro_secretbox_IVBYTES 20
|
|
||||||
#define hydro_secretbox_SIVBYTES 20
|
|
||||||
#define hydro_secretbox_MACBYTES 16
|
|
||||||
|
|
||||||
void
|
|
||||||
hydro_secretbox_keygen(uint8_t key[hydro_secretbox_KEYBYTES])
|
|
||||||
{
|
|
||||||
hydro_random_buf(key, hydro_secretbox_KEYBYTES);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
hydro_secretbox_xor_enc(uint8_t buf[gimli_BLOCKBYTES], uint8_t *out, const uint8_t *in,
|
|
||||||
size_t inlen)
|
|
||||||
{
|
|
||||||
size_t i;
|
|
||||||
size_t leftover;
|
|
||||||
|
|
||||||
for (i = 0; i < inlen / gimli_RATE; i++) {
|
|
||||||
mem_xor2(&out[i * gimli_RATE], &in[i * gimli_RATE], buf, gimli_RATE);
|
|
||||||
memcpy(buf, &out[i * gimli_RATE], gimli_RATE);
|
|
||||||
gimli_core_u8(buf, gimli_TAG_PAYLOAD);
|
|
||||||
}
|
|
||||||
leftover = inlen % gimli_RATE;
|
|
||||||
if (leftover != 0) {
|
|
||||||
mem_xor2(&out[i * gimli_RATE], &in[i * gimli_RATE], buf, leftover);
|
|
||||||
mem_cpy(buf, &out[i * gimli_RATE], leftover);
|
|
||||||
}
|
|
||||||
gimli_pad_u8(buf, leftover, gimli_DOMAIN_AEAD);
|
|
||||||
gimli_core_u8(buf, gimli_TAG_PAYLOAD);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
hydro_secretbox_xor_dec(uint8_t buf[gimli_BLOCKBYTES], uint8_t *out, const uint8_t *in,
|
|
||||||
size_t inlen)
|
|
||||||
{
|
|
||||||
size_t i;
|
|
||||||
size_t leftover;
|
|
||||||
|
|
||||||
for (i = 0; i < inlen / gimli_RATE; i++) {
|
|
||||||
mem_xor2(&out[i * gimli_RATE], &in[i * gimli_RATE], buf, gimli_RATE);
|
|
||||||
memcpy(buf, &in[i * gimli_RATE], gimli_RATE);
|
|
||||||
gimli_core_u8(buf, gimli_TAG_PAYLOAD);
|
|
||||||
}
|
|
||||||
leftover = inlen % gimli_RATE;
|
|
||||||
if (leftover != 0) {
|
|
||||||
mem_xor2(&out[i * gimli_RATE], &in[i * gimli_RATE], buf, leftover);
|
|
||||||
mem_cpy(buf, &in[i * gimli_RATE], leftover);
|
|
||||||
}
|
|
||||||
gimli_pad_u8(buf, leftover, gimli_DOMAIN_AEAD);
|
|
||||||
gimli_core_u8(buf, gimli_TAG_PAYLOAD);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
hydro_secretbox_setup(uint8_t buf[gimli_BLOCKBYTES], uint64_t msg_id,
|
|
||||||
const char ctx[hydro_secretbox_CONTEXTBYTES],
|
|
||||||
const uint8_t key[hydro_secretbox_KEYBYTES],
|
|
||||||
const uint8_t iv[hydro_secretbox_IVBYTES], uint8_t key_tag)
|
|
||||||
{
|
|
||||||
static const uint8_t prefix[] = { 6, 's', 'b', 'x', '2', '5', '6', 8 };
|
|
||||||
uint8_t msg_id_le[8];
|
|
||||||
|
|
||||||
mem_zero(buf, gimli_BLOCKBYTES);
|
|
||||||
COMPILER_ASSERT(hydro_secretbox_CONTEXTBYTES == 8);
|
|
||||||
COMPILER_ASSERT(sizeof prefix + hydro_secretbox_CONTEXTBYTES <= gimli_RATE);
|
|
||||||
memcpy(buf, prefix, sizeof prefix);
|
|
||||||
memcpy(buf + sizeof prefix, ctx, hydro_secretbox_CONTEXTBYTES);
|
|
||||||
COMPILER_ASSERT(sizeof prefix + hydro_secretbox_CONTEXTBYTES == gimli_RATE);
|
|
||||||
gimli_core_u8(buf, gimli_TAG_HEADER);
|
|
||||||
|
|
||||||
COMPILER_ASSERT(hydro_secretbox_KEYBYTES == 2 * gimli_RATE);
|
|
||||||
mem_xor(buf, key, gimli_RATE);
|
|
||||||
gimli_core_u8(buf, key_tag);
|
|
||||||
mem_xor(buf, key + gimli_RATE, gimli_RATE);
|
|
||||||
gimli_core_u8(buf, key_tag);
|
|
||||||
|
|
||||||
COMPILER_ASSERT(hydro_secretbox_IVBYTES < gimli_RATE * 2);
|
|
||||||
buf[0] ^= hydro_secretbox_IVBYTES;
|
|
||||||
mem_xor(&buf[1], iv, gimli_RATE - 1);
|
|
||||||
gimli_core_u8(buf, gimli_TAG_HEADER);
|
|
||||||
mem_xor(buf, iv + gimli_RATE - 1, hydro_secretbox_IVBYTES - (gimli_RATE - 1));
|
|
||||||
STORE64_LE(msg_id_le, msg_id);
|
|
||||||
COMPILER_ASSERT(hydro_secretbox_IVBYTES - gimli_RATE + 8 <= gimli_RATE);
|
|
||||||
mem_xor(buf + hydro_secretbox_IVBYTES - gimli_RATE, msg_id_le, 8);
|
|
||||||
gimli_core_u8(buf, gimli_TAG_HEADER);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
hydro_secretbox_final(uint8_t *buf, const uint8_t key[hydro_secretbox_KEYBYTES], uint8_t tag)
|
|
||||||
{
|
|
||||||
COMPILER_ASSERT(hydro_secretbox_KEYBYTES == gimli_CAPACITY);
|
|
||||||
mem_xor(buf + gimli_RATE, key, hydro_secretbox_KEYBYTES);
|
|
||||||
gimli_core_u8(buf, tag);
|
|
||||||
mem_xor(buf + gimli_RATE, key, hydro_secretbox_KEYBYTES);
|
|
||||||
gimli_core_u8(buf, tag);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
hydro_secretbox_encrypt_iv(uint8_t *c, const void *m_, size_t mlen, uint64_t msg_id,
|
|
||||||
const char ctx[hydro_secretbox_CONTEXTBYTES],
|
|
||||||
const uint8_t key[hydro_secretbox_KEYBYTES],
|
|
||||||
const uint8_t iv[hydro_secretbox_IVBYTES])
|
|
||||||
{
|
|
||||||
_hydro_attr_aligned_(16) uint32_t state[gimli_BLOCKBYTES / 4];
|
|
||||||
uint8_t *buf = (uint8_t *) (void *) state;
|
|
||||||
const uint8_t *m = (const uint8_t *) m_;
|
|
||||||
uint8_t *siv = &c[0];
|
|
||||||
uint8_t *mac = &c[hydro_secretbox_SIVBYTES];
|
|
||||||
uint8_t *ct = &c[hydro_secretbox_SIVBYTES + hydro_secretbox_MACBYTES];
|
|
||||||
size_t i;
|
|
||||||
size_t leftover;
|
|
||||||
|
|
||||||
if (c == m) {
|
|
||||||
memmove(c + hydro_secretbox_HEADERBYTES, m, mlen);
|
|
||||||
m = c + hydro_secretbox_HEADERBYTES;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* first pass: compute the SIV */
|
|
||||||
|
|
||||||
hydro_secretbox_setup(buf, msg_id, ctx, key, iv, gimli_TAG_KEY0);
|
|
||||||
for (i = 0; i < mlen / gimli_RATE; i++) {
|
|
||||||
mem_xor(buf, &m[i * gimli_RATE], gimli_RATE);
|
|
||||||
gimli_core_u8(buf, gimli_TAG_PAYLOAD);
|
|
||||||
}
|
|
||||||
leftover = mlen % gimli_RATE;
|
|
||||||
if (leftover != 0) {
|
|
||||||
mem_xor(buf, &m[i * gimli_RATE], leftover);
|
|
||||||
}
|
|
||||||
gimli_pad_u8(buf, leftover, gimli_DOMAIN_XOF);
|
|
||||||
gimli_core_u8(buf, gimli_TAG_PAYLOAD);
|
|
||||||
|
|
||||||
hydro_secretbox_final(buf, key, gimli_TAG_FINAL0);
|
|
||||||
COMPILER_ASSERT(hydro_secretbox_SIVBYTES <= gimli_CAPACITY);
|
|
||||||
memcpy(siv, buf + gimli_RATE, hydro_secretbox_SIVBYTES);
|
|
||||||
|
|
||||||
/* second pass: encrypt the message, mix the key, squeeze an extra block for
|
|
||||||
* the MAC */
|
|
||||||
|
|
||||||
COMPILER_ASSERT(hydro_secretbox_SIVBYTES == hydro_secretbox_IVBYTES);
|
|
||||||
hydro_secretbox_setup(buf, msg_id, ctx, key, siv, gimli_TAG_KEY);
|
|
||||||
hydro_secretbox_xor_enc(buf, ct, m, mlen);
|
|
||||||
|
|
||||||
hydro_secretbox_final(buf, key, gimli_TAG_FINAL);
|
|
||||||
COMPILER_ASSERT(hydro_secretbox_MACBYTES <= gimli_CAPACITY);
|
|
||||||
memcpy(mac, buf + gimli_RATE, hydro_secretbox_MACBYTES);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
hydro_secretbox_probe_create(uint8_t probe[hydro_secretbox_PROBEBYTES], const uint8_t *c,
|
|
||||||
size_t c_len, const char ctx[hydro_secretbox_CONTEXTBYTES],
|
|
||||||
const uint8_t key[hydro_secretbox_KEYBYTES])
|
|
||||||
{
|
|
||||||
const uint8_t *mac;
|
|
||||||
|
|
||||||
if (c_len < hydro_secretbox_HEADERBYTES) {
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
mac = &c[hydro_secretbox_SIVBYTES];
|
|
||||||
COMPILER_ASSERT(hydro_secretbox_CONTEXTBYTES >= hydro_hash_CONTEXTBYTES);
|
|
||||||
COMPILER_ASSERT(hydro_secretbox_KEYBYTES >= hydro_hash_KEYBYTES);
|
|
||||||
hydro_hash_hash(probe, hydro_secretbox_PROBEBYTES, mac, hydro_secretbox_MACBYTES, ctx, key);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
hydro_secretbox_probe_verify(const uint8_t probe[hydro_secretbox_PROBEBYTES], const uint8_t *c,
|
|
||||||
size_t c_len, const char ctx[hydro_secretbox_CONTEXTBYTES],
|
|
||||||
const uint8_t key[hydro_secretbox_KEYBYTES])
|
|
||||||
{
|
|
||||||
uint8_t computed_probe[hydro_secretbox_PROBEBYTES];
|
|
||||||
const uint8_t *mac;
|
|
||||||
|
|
||||||
if (c_len < hydro_secretbox_HEADERBYTES) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
mac = &c[hydro_secretbox_SIVBYTES];
|
|
||||||
hydro_hash_hash(computed_probe, hydro_secretbox_PROBEBYTES, mac, hydro_secretbox_MACBYTES, ctx,
|
|
||||||
key);
|
|
||||||
if (hydro_equal(computed_probe, probe, hydro_secretbox_PROBEBYTES) == 1) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
hydro_memzero(computed_probe, hydro_secretbox_PROBEBYTES);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
hydro_secretbox_encrypt(uint8_t *c, const void *m_, size_t mlen, uint64_t msg_id,
|
|
||||||
const char ctx[hydro_secretbox_CONTEXTBYTES],
|
|
||||||
const uint8_t key[hydro_secretbox_KEYBYTES])
|
|
||||||
{
|
|
||||||
uint8_t iv[hydro_secretbox_IVBYTES];
|
|
||||||
|
|
||||||
hydro_random_buf(iv, sizeof iv);
|
|
||||||
|
|
||||||
return hydro_secretbox_encrypt_iv(c, m_, mlen, msg_id, ctx, key, iv);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
hydro_secretbox_decrypt(void *m_, const uint8_t *c, size_t clen, uint64_t msg_id,
|
|
||||||
const char ctx[hydro_secretbox_CONTEXTBYTES],
|
|
||||||
const uint8_t key[hydro_secretbox_KEYBYTES])
|
|
||||||
{
|
|
||||||
_hydro_attr_aligned_(16) uint32_t state[gimli_BLOCKBYTES / 4];
|
|
||||||
uint32_t pub_mac[hydro_secretbox_MACBYTES / 4];
|
|
||||||
uint8_t *buf = (uint8_t *) (void *) state;
|
|
||||||
const uint8_t *siv;
|
|
||||||
const uint8_t *mac;
|
|
||||||
const uint8_t *ct;
|
|
||||||
uint8_t *m = (uint8_t *) m_;
|
|
||||||
size_t mlen;
|
|
||||||
uint32_t cv;
|
|
||||||
|
|
||||||
if (clen < hydro_secretbox_HEADERBYTES) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
siv = &c[0];
|
|
||||||
mac = &c[hydro_secretbox_SIVBYTES];
|
|
||||||
ct = &c[hydro_secretbox_SIVBYTES + hydro_secretbox_MACBYTES];
|
|
||||||
|
|
||||||
mlen = clen - hydro_secretbox_HEADERBYTES;
|
|
||||||
memcpy(pub_mac, mac, sizeof pub_mac);
|
|
||||||
COMPILER_ASSERT(hydro_secretbox_SIVBYTES == hydro_secretbox_IVBYTES);
|
|
||||||
hydro_secretbox_setup(buf, msg_id, ctx, key, siv, gimli_TAG_KEY);
|
|
||||||
hydro_secretbox_xor_dec(buf, m, ct, mlen);
|
|
||||||
|
|
||||||
hydro_secretbox_final(buf, key, gimli_TAG_FINAL);
|
|
||||||
COMPILER_ASSERT(hydro_secretbox_MACBYTES <= gimli_CAPACITY);
|
|
||||||
COMPILER_ASSERT(gimli_RATE % 4 == 0);
|
|
||||||
cv = hydro_mem_ct_cmp_u32(state + gimli_RATE / 4, pub_mac, hydro_secretbox_MACBYTES / 4);
|
|
||||||
hydro_mem_ct_zero_u32(state, gimli_BLOCKBYTES / 4);
|
|
||||||
if (cv != 0) {
|
|
||||||
mem_zero(m, mlen);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@ -1,207 +0,0 @@
|
|||||||
#define hydro_sign_CHALLENGEBYTES 32
|
|
||||||
#define hydro_sign_NONCEBYTES 32
|
|
||||||
#define hydro_sign_PREHASHBYTES 64
|
|
||||||
|
|
||||||
static void
|
|
||||||
hydro_sign_p2(uint8_t sig[hydro_x25519_BYTES], const uint8_t challenge[hydro_sign_CHALLENGEBYTES],
|
|
||||||
const uint8_t eph_sk[hydro_x25519_BYTES], const uint8_t sk[hydro_x25519_BYTES])
|
|
||||||
{
|
|
||||||
hydro_x25519_scalar_t scalar1, scalar2, scalar3;
|
|
||||||
|
|
||||||
COMPILER_ASSERT(hydro_sign_CHALLENGEBYTES == hydro_x25519_BYTES);
|
|
||||||
hydro_x25519_swapin(scalar1, eph_sk);
|
|
||||||
hydro_x25519_swapin(scalar2, sk);
|
|
||||||
hydro_x25519_swapin(scalar3, challenge);
|
|
||||||
hydro_x25519_sc_montmul(scalar1, scalar2, scalar3);
|
|
||||||
mem_zero(scalar2, sizeof scalar2);
|
|
||||||
hydro_x25519_sc_montmul(scalar2, scalar1, hydro_x25519_sc_r2);
|
|
||||||
hydro_x25519_swapout(sig, scalar2);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
hydro_sign_challenge(uint8_t challenge[hydro_sign_CHALLENGEBYTES],
|
|
||||||
const uint8_t nonce[hydro_sign_NONCEBYTES],
|
|
||||||
const uint8_t pk[hydro_sign_PUBLICKEYBYTES],
|
|
||||||
const uint8_t prehash[hydro_sign_PREHASHBYTES])
|
|
||||||
{
|
|
||||||
hydro_hash_state st;
|
|
||||||
|
|
||||||
hydro_hash_init(&st, (const char *) zero, NULL);
|
|
||||||
hydro_hash_update(&st, nonce, hydro_sign_NONCEBYTES);
|
|
||||||
hydro_hash_update(&st, pk, hydro_sign_PUBLICKEYBYTES);
|
|
||||||
hydro_hash_update(&st, prehash, hydro_sign_PREHASHBYTES);
|
|
||||||
hydro_hash_final(&st, challenge, hydro_sign_CHALLENGEBYTES);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
hydro_sign_prehash(uint8_t csig[hydro_sign_BYTES], const uint8_t prehash[hydro_sign_PREHASHBYTES],
|
|
||||||
const uint8_t sk[hydro_sign_SECRETKEYBYTES])
|
|
||||||
{
|
|
||||||
hydro_hash_state st;
|
|
||||||
uint8_t challenge[hydro_sign_CHALLENGEBYTES];
|
|
||||||
const uint8_t *pk = &sk[hydro_x25519_SECRETKEYBYTES];
|
|
||||||
uint8_t *nonce = &csig[0];
|
|
||||||
uint8_t *sig = &csig[hydro_sign_NONCEBYTES];
|
|
||||||
uint8_t *eph_sk = sig;
|
|
||||||
|
|
||||||
hydro_random_buf(eph_sk, hydro_x25519_SECRETKEYBYTES);
|
|
||||||
COMPILER_ASSERT(hydro_x25519_SECRETKEYBYTES == hydro_hash_KEYBYTES);
|
|
||||||
hydro_hash_init(&st, (const char *) zero, sk);
|
|
||||||
hydro_hash_update(&st, eph_sk, hydro_x25519_SECRETKEYBYTES);
|
|
||||||
hydro_hash_update(&st, prehash, hydro_sign_PREHASHBYTES);
|
|
||||||
hydro_hash_final(&st, eph_sk, hydro_x25519_SECRETKEYBYTES);
|
|
||||||
|
|
||||||
hydro_x25519_scalarmult_base_uniform(nonce, eph_sk);
|
|
||||||
hydro_sign_challenge(challenge, nonce, pk, prehash);
|
|
||||||
|
|
||||||
COMPILER_ASSERT(hydro_sign_BYTES == hydro_sign_NONCEBYTES + hydro_x25519_SECRETKEYBYTES);
|
|
||||||
COMPILER_ASSERT(hydro_x25519_SECRETKEYBYTES <= hydro_sign_CHALLENGEBYTES);
|
|
||||||
hydro_sign_p2(sig, challenge, eph_sk, sk);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
hydro_sign_verify_core(hydro_x25519_fe xs[5], const hydro_x25519_limb_t *other1,
|
|
||||||
const uint8_t other2[hydro_x25519_BYTES])
|
|
||||||
{
|
|
||||||
hydro_x25519_limb_t *z2 = xs[1], *x3 = xs[2], *z3 = xs[3];
|
|
||||||
hydro_x25519_fe xo2;
|
|
||||||
const hydro_x25519_limb_t sixteen = 16;
|
|
||||||
|
|
||||||
hydro_x25519_swapin(xo2, other2);
|
|
||||||
memcpy(x3, other1, 2 * sizeof(hydro_x25519_fe));
|
|
||||||
hydro_x25519_ladder_part1(xs);
|
|
||||||
|
|
||||||
/* Here z2 = t2^2 */
|
|
||||||
hydro_x25519_mul1(z2, other1);
|
|
||||||
hydro_x25519_mul1(z2, other1 + hydro_x25519_NLIMBS);
|
|
||||||
hydro_x25519_mul1(z2, xo2);
|
|
||||||
|
|
||||||
hydro_x25519_mul(z2, z2, &sixteen, 1);
|
|
||||||
|
|
||||||
hydro_x25519_mul1(z3, xo2);
|
|
||||||
hydro_x25519_sub(z3, z3, x3);
|
|
||||||
hydro_x25519_sqr1(z3);
|
|
||||||
|
|
||||||
/* check equality */
|
|
||||||
hydro_x25519_sub(z3, z3, z2);
|
|
||||||
|
|
||||||
/* canon(z2): both sides are zero. canon(z3): the two sides are equal. */
|
|
||||||
/* Reject sigs where both sides are zero. */
|
|
||||||
return hydro_x25519_canon(z2) | ~hydro_x25519_canon(z3);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
hydro_sign_verify_p2(const uint8_t sig[hydro_x25519_BYTES],
|
|
||||||
const uint8_t challenge[hydro_sign_CHALLENGEBYTES],
|
|
||||||
const uint8_t nonce[hydro_sign_NONCEBYTES],
|
|
||||||
const uint8_t pk[hydro_x25519_BYTES])
|
|
||||||
{
|
|
||||||
hydro_x25519_fe xs[7];
|
|
||||||
|
|
||||||
hydro_x25519_core(xs, challenge, pk, 0);
|
|
||||||
hydro_x25519_core(xs + 2, sig, hydro_x25519_BASE_POINT, 0);
|
|
||||||
|
|
||||||
return hydro_sign_verify_core(xs + 2, xs[0], nonce);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
hydro_sign_verify_challenge(const uint8_t csig[hydro_sign_BYTES],
|
|
||||||
const uint8_t challenge[hydro_sign_CHALLENGEBYTES],
|
|
||||||
const uint8_t pk[hydro_sign_PUBLICKEYBYTES])
|
|
||||||
{
|
|
||||||
const uint8_t *nonce = &csig[0];
|
|
||||||
const uint8_t *sig = &csig[hydro_sign_NONCEBYTES];
|
|
||||||
|
|
||||||
return hydro_sign_verify_p2(sig, challenge, nonce, pk);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
hydro_sign_keygen(hydro_sign_keypair *kp)
|
|
||||||
{
|
|
||||||
uint8_t *pk_copy = &kp->sk[hydro_x25519_SECRETKEYBYTES];
|
|
||||||
|
|
||||||
COMPILER_ASSERT(hydro_sign_SECRETKEYBYTES ==
|
|
||||||
hydro_x25519_SECRETKEYBYTES + hydro_x25519_PUBLICKEYBYTES);
|
|
||||||
COMPILER_ASSERT(hydro_sign_PUBLICKEYBYTES == hydro_x25519_PUBLICKEYBYTES);
|
|
||||||
hydro_random_buf(kp->sk, hydro_x25519_SECRETKEYBYTES);
|
|
||||||
hydro_x25519_scalarmult_base_uniform(kp->pk, kp->sk);
|
|
||||||
memcpy(pk_copy, kp->pk, hydro_x25519_PUBLICKEYBYTES);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
hydro_sign_keygen_deterministic(hydro_sign_keypair *kp, const uint8_t seed[hydro_sign_SEEDBYTES])
|
|
||||||
{
|
|
||||||
uint8_t *pk_copy = &kp->sk[hydro_x25519_SECRETKEYBYTES];
|
|
||||||
|
|
||||||
COMPILER_ASSERT(hydro_sign_SEEDBYTES >= hydro_random_SEEDBYTES);
|
|
||||||
hydro_random_buf_deterministic(kp->sk, hydro_x25519_SECRETKEYBYTES, seed);
|
|
||||||
hydro_x25519_scalarmult_base_uniform(kp->pk, kp->sk);
|
|
||||||
memcpy(pk_copy, kp->pk, hydro_x25519_PUBLICKEYBYTES);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
hydro_sign_init(hydro_sign_state *state, const char ctx[hydro_sign_CONTEXTBYTES])
|
|
||||||
{
|
|
||||||
return hydro_hash_init(&state->hash_st, ctx, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
hydro_sign_update(hydro_sign_state *state, const void *m_, size_t mlen)
|
|
||||||
{
|
|
||||||
return hydro_hash_update(&state->hash_st, m_, mlen);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
hydro_sign_final_create(hydro_sign_state *state, uint8_t csig[hydro_sign_BYTES],
|
|
||||||
const uint8_t sk[hydro_sign_SECRETKEYBYTES])
|
|
||||||
{
|
|
||||||
uint8_t prehash[hydro_sign_PREHASHBYTES];
|
|
||||||
|
|
||||||
hydro_hash_final(&state->hash_st, prehash, sizeof prehash);
|
|
||||||
|
|
||||||
return hydro_sign_prehash(csig, prehash, sk);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
hydro_sign_final_verify(hydro_sign_state *state, const uint8_t csig[hydro_sign_BYTES],
|
|
||||||
const uint8_t pk[hydro_sign_PUBLICKEYBYTES])
|
|
||||||
{
|
|
||||||
uint8_t challenge[hydro_sign_CHALLENGEBYTES];
|
|
||||||
uint8_t prehash[hydro_sign_PREHASHBYTES];
|
|
||||||
const uint8_t *nonce = &csig[0];
|
|
||||||
|
|
||||||
hydro_hash_final(&state->hash_st, prehash, sizeof prehash);
|
|
||||||
hydro_sign_challenge(challenge, nonce, pk, prehash);
|
|
||||||
|
|
||||||
return hydro_sign_verify_challenge(csig, challenge, pk);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
hydro_sign_create(uint8_t csig[hydro_sign_BYTES], const void *m_, size_t mlen,
|
|
||||||
const char ctx[hydro_sign_CONTEXTBYTES],
|
|
||||||
const uint8_t sk[hydro_sign_SECRETKEYBYTES])
|
|
||||||
{
|
|
||||||
hydro_sign_state st;
|
|
||||||
|
|
||||||
if (hydro_sign_init(&st, ctx) != 0 || hydro_sign_update(&st, m_, mlen) != 0 ||
|
|
||||||
hydro_sign_final_create(&st, csig, sk) != 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
hydro_sign_verify(const uint8_t csig[hydro_sign_BYTES], const void *m_, size_t mlen,
|
|
||||||
const char ctx[hydro_sign_CONTEXTBYTES],
|
|
||||||
const uint8_t pk[hydro_sign_PUBLICKEYBYTES])
|
|
||||||
{
|
|
||||||
hydro_sign_state st;
|
|
||||||
|
|
||||||
if (hydro_sign_init(&st, ctx) != 0 || hydro_sign_update(&st, m_, mlen) != 0 ||
|
|
||||||
hydro_sign_final_verify(&st, csig, pk) != 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@ -1,386 +0,0 @@
|
|||||||
/*
|
|
||||||
* Based on Michael Hamburg's STROBE reference implementation.
|
|
||||||
* Copyright (c) 2015-2016 Cryptography Research, Inc.
|
|
||||||
* MIT License (MIT)
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if defined(__GNUC__) && defined(__SIZEOF_INT128__)
|
|
||||||
# define hydro_x25519_WBITS 64
|
|
||||||
#else
|
|
||||||
# define hydro_x25519_WBITS 32
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if hydro_x25519_WBITS == 64
|
|
||||||
typedef uint64_t hydro_x25519_limb_t;
|
|
||||||
typedef __uint128_t hydro_x25519_dlimb_t;
|
|
||||||
typedef __int128_t hydro_x25519_sdlimb_t;
|
|
||||||
# define hydro_x25519_eswap_limb(X) LOAD64_LE((const uint8_t *) &(X))
|
|
||||||
# define hydro_x25519_LIMB(x) x##ull
|
|
||||||
#elif hydro_x25519_WBITS == 32
|
|
||||||
typedef uint32_t hydro_x25519_limb_t;
|
|
||||||
typedef uint64_t hydro_x25519_dlimb_t;
|
|
||||||
typedef int64_t hydro_x25519_sdlimb_t;
|
|
||||||
# define hydro_x25519_eswap_limb(X) LOAD32_LE((const uint8_t *) &(X))
|
|
||||||
# define hydro_x25519_LIMB(x) (uint32_t)(x##ull), (uint32_t) ((x##ull) >> 32)
|
|
||||||
#else
|
|
||||||
# error "Need to know hydro_x25519_WBITS"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define hydro_x25519_NLIMBS (256 / hydro_x25519_WBITS)
|
|
||||||
typedef hydro_x25519_limb_t hydro_x25519_fe[hydro_x25519_NLIMBS];
|
|
||||||
|
|
||||||
typedef hydro_x25519_limb_t hydro_x25519_scalar_t[hydro_x25519_NLIMBS];
|
|
||||||
|
|
||||||
static const hydro_x25519_limb_t hydro_x25519_MONTGOMERY_FACTOR =
|
|
||||||
(hydro_x25519_limb_t) 0xd2b51da312547e1bull;
|
|
||||||
|
|
||||||
static const hydro_x25519_scalar_t hydro_x25519_sc_p = { hydro_x25519_LIMB(0x5812631a5cf5d3ed),
|
|
||||||
hydro_x25519_LIMB(0x14def9dea2f79cd6),
|
|
||||||
hydro_x25519_LIMB(0x0000000000000000),
|
|
||||||
hydro_x25519_LIMB(0x1000000000000000) };
|
|
||||||
|
|
||||||
static const hydro_x25519_scalar_t hydro_x25519_sc_r2 = { hydro_x25519_LIMB(0xa40611e3449c0f01),
|
|
||||||
hydro_x25519_LIMB(0xd00e1ba768859347),
|
|
||||||
hydro_x25519_LIMB(0xceec73d217f5be65),
|
|
||||||
hydro_x25519_LIMB(0x0399411b7c309a3d) };
|
|
||||||
|
|
||||||
static const uint8_t hydro_x25519_BASE_POINT[hydro_x25519_BYTES] = { 9 };
|
|
||||||
|
|
||||||
static const hydro_x25519_limb_t hydro_x25519_a24[1] = { 121665 };
|
|
||||||
|
|
||||||
static inline hydro_x25519_limb_t
|
|
||||||
hydro_x25519_umaal(hydro_x25519_limb_t *carry, hydro_x25519_limb_t acc, hydro_x25519_limb_t mand,
|
|
||||||
hydro_x25519_limb_t mier)
|
|
||||||
{
|
|
||||||
hydro_x25519_dlimb_t tmp = (hydro_x25519_dlimb_t) mand * mier + acc + *carry;
|
|
||||||
|
|
||||||
*carry = tmp >> hydro_x25519_WBITS;
|
|
||||||
return (hydro_x25519_limb_t) tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline hydro_x25519_limb_t
|
|
||||||
hydro_x25519_adc(hydro_x25519_limb_t *carry, hydro_x25519_limb_t acc, hydro_x25519_limb_t mand)
|
|
||||||
{
|
|
||||||
hydro_x25519_dlimb_t total = (hydro_x25519_dlimb_t) *carry + acc + mand;
|
|
||||||
|
|
||||||
*carry = total >> hydro_x25519_WBITS;
|
|
||||||
return (hydro_x25519_limb_t) total;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline hydro_x25519_limb_t
|
|
||||||
hydro_x25519_adc0(hydro_x25519_limb_t *carry, hydro_x25519_limb_t acc)
|
|
||||||
{
|
|
||||||
hydro_x25519_dlimb_t total = (hydro_x25519_dlimb_t) *carry + acc;
|
|
||||||
|
|
||||||
*carry = total >> hydro_x25519_WBITS;
|
|
||||||
return (hydro_x25519_limb_t) total;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
hydro_x25519_propagate(hydro_x25519_fe x, hydro_x25519_limb_t over)
|
|
||||||
{
|
|
||||||
hydro_x25519_limb_t carry;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
over = x[hydro_x25519_NLIMBS - 1] >> (hydro_x25519_WBITS - 1) | over << 1;
|
|
||||||
x[hydro_x25519_NLIMBS - 1] &= ~((hydro_x25519_limb_t) 1 << (hydro_x25519_WBITS - 1));
|
|
||||||
carry = over * 19;
|
|
||||||
for (i = 0; i < hydro_x25519_NLIMBS; i++) {
|
|
||||||
x[i] = hydro_x25519_adc0(&carry, x[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
hydro_x25519_add(hydro_x25519_fe out, const hydro_x25519_fe a, const hydro_x25519_fe b)
|
|
||||||
{
|
|
||||||
hydro_x25519_limb_t carry = 0;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < hydro_x25519_NLIMBS; i++) {
|
|
||||||
out[i] = hydro_x25519_adc(&carry, a[i], b[i]);
|
|
||||||
}
|
|
||||||
hydro_x25519_propagate(out, carry);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
hydro_x25519_sub(hydro_x25519_fe out, const hydro_x25519_fe a, const hydro_x25519_fe b)
|
|
||||||
{
|
|
||||||
hydro_x25519_sdlimb_t carry = -76;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < hydro_x25519_NLIMBS; i++) {
|
|
||||||
out[i] = (hydro_x25519_limb_t) (carry = carry + a[i] - b[i]);
|
|
||||||
carry >>= hydro_x25519_WBITS;
|
|
||||||
}
|
|
||||||
hydro_x25519_propagate(out, (hydro_x25519_limb_t) (2 + carry));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
hydro_x25519_swapin(hydro_x25519_limb_t *x, const uint8_t *in)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
memcpy(x, in, sizeof(hydro_x25519_fe));
|
|
||||||
for (i = 0; i < hydro_x25519_NLIMBS; i++) {
|
|
||||||
x[i] = hydro_x25519_eswap_limb(x[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
hydro_x25519_swapout(uint8_t *out, hydro_x25519_limb_t *x)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < hydro_x25519_NLIMBS; i++) {
|
|
||||||
x[i] = hydro_x25519_eswap_limb(x[i]);
|
|
||||||
}
|
|
||||||
memcpy(out, x, sizeof(hydro_x25519_fe));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
hydro_x25519_mul(hydro_x25519_fe out, const hydro_x25519_fe a, const hydro_x25519_limb_t b[],
|
|
||||||
const int nb)
|
|
||||||
{
|
|
||||||
hydro_x25519_limb_t accum[2 * hydro_x25519_NLIMBS] = { 0 };
|
|
||||||
hydro_x25519_limb_t carry2;
|
|
||||||
int i, j;
|
|
||||||
|
|
||||||
for (i = 0; i < nb; i++) {
|
|
||||||
hydro_x25519_limb_t mand = b[i];
|
|
||||||
carry2 = 0;
|
|
||||||
|
|
||||||
for (j = 0; j < hydro_x25519_NLIMBS; j++) {
|
|
||||||
accum[i + j] = hydro_x25519_umaal(&carry2, accum[i + j], mand, a[j]);
|
|
||||||
}
|
|
||||||
accum[i + j] = carry2;
|
|
||||||
}
|
|
||||||
carry2 = 0;
|
|
||||||
for (j = 0; j < hydro_x25519_NLIMBS; j++) {
|
|
||||||
const hydro_x25519_limb_t mand = 38;
|
|
||||||
|
|
||||||
out[j] = hydro_x25519_umaal(&carry2, accum[j], mand, accum[j + hydro_x25519_NLIMBS]);
|
|
||||||
}
|
|
||||||
hydro_x25519_propagate(out, carry2);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
hydro_x25519_sqr(hydro_x25519_fe out, const hydro_x25519_fe a)
|
|
||||||
{
|
|
||||||
hydro_x25519_mul(out, a, a, hydro_x25519_NLIMBS);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
hydro_x25519_mul1(hydro_x25519_fe out, const hydro_x25519_fe a)
|
|
||||||
{
|
|
||||||
hydro_x25519_mul(out, a, out, hydro_x25519_NLIMBS);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
hydro_x25519_sqr1(hydro_x25519_fe a)
|
|
||||||
{
|
|
||||||
hydro_x25519_mul1(a, a);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
hydro_x25519_condswap(hydro_x25519_limb_t a[2 * hydro_x25519_NLIMBS],
|
|
||||||
hydro_x25519_limb_t b[2 * hydro_x25519_NLIMBS], hydro_x25519_limb_t doswap)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < 2 * hydro_x25519_NLIMBS; i++) {
|
|
||||||
hydro_x25519_limb_t xorv = (a[i] ^ b[i]) & doswap;
|
|
||||||
a[i] ^= xorv;
|
|
||||||
b[i] ^= xorv;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
hydro_x25519_canon(hydro_x25519_fe x)
|
|
||||||
{
|
|
||||||
hydro_x25519_sdlimb_t carry;
|
|
||||||
hydro_x25519_limb_t carry0 = 19;
|
|
||||||
hydro_x25519_limb_t res;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < hydro_x25519_NLIMBS; i++) {
|
|
||||||
x[i] = hydro_x25519_adc0(&carry0, x[i]);
|
|
||||||
}
|
|
||||||
hydro_x25519_propagate(x, carry0);
|
|
||||||
carry = -19;
|
|
||||||
res = 0;
|
|
||||||
for (i = 0; i < hydro_x25519_NLIMBS; i++) {
|
|
||||||
res |= x[i] = (hydro_x25519_limb_t) (carry += x[i]);
|
|
||||||
carry >>= hydro_x25519_WBITS;
|
|
||||||
}
|
|
||||||
return ((hydro_x25519_dlimb_t) res - 1) >> hydro_x25519_WBITS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
hydro_x25519_ladder_part1(hydro_x25519_fe xs[5])
|
|
||||||
{
|
|
||||||
hydro_x25519_limb_t *x2 = xs[0], *z2 = xs[1], *x3 = xs[2], *z3 = xs[3], *t1 = xs[4];
|
|
||||||
|
|
||||||
hydro_x25519_add(t1, x2, z2); // t1 = A
|
|
||||||
hydro_x25519_sub(z2, x2, z2); // z2 = B
|
|
||||||
hydro_x25519_add(x2, x3, z3); // x2 = C
|
|
||||||
hydro_x25519_sub(z3, x3, z3); // z3 = D
|
|
||||||
hydro_x25519_mul1(z3, t1); // z3 = DA
|
|
||||||
hydro_x25519_mul1(x2, z2); // x3 = BC
|
|
||||||
hydro_x25519_add(x3, z3, x2); // x3 = DA+CB
|
|
||||||
hydro_x25519_sub(z3, z3, x2); // z3 = DA-CB
|
|
||||||
hydro_x25519_sqr1(t1); // t1 = AA
|
|
||||||
hydro_x25519_sqr1(z2); // z2 = BB
|
|
||||||
hydro_x25519_sub(x2, t1, z2); // x2 = E = AA-BB
|
|
||||||
hydro_x25519_mul(z2, x2, hydro_x25519_a24, // z2 = E*a24
|
|
||||||
sizeof(hydro_x25519_a24) / sizeof(hydro_x25519_a24[0]));
|
|
||||||
hydro_x25519_add(z2, z2, t1); // z2 = E*a24 + AA
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
hydro_x25519_ladder_part2(hydro_x25519_fe xs[5], const hydro_x25519_fe x1)
|
|
||||||
{
|
|
||||||
hydro_x25519_limb_t *x2 = xs[0], *z2 = xs[1], *x3 = xs[2], *z3 = xs[3], *t1 = xs[4];
|
|
||||||
|
|
||||||
hydro_x25519_sqr1(z3); // z3 = (DA-CB)^2
|
|
||||||
hydro_x25519_mul1(z3, x1); // z3 = x1 * (DA-CB)^2
|
|
||||||
hydro_x25519_sqr1(x3); // x3 = (DA+CB)^2
|
|
||||||
hydro_x25519_mul1(z2, x2); // z2 = AA*(E*a24+AA)
|
|
||||||
hydro_x25519_sub(x2, t1, x2); // x2 = BB again
|
|
||||||
hydro_x25519_mul1(x2, t1); // x2 = AA*BB
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
hydro_x25519_core(hydro_x25519_fe xs[5], const uint8_t scalar[hydro_x25519_BYTES],
|
|
||||||
const uint8_t *x1, bool clamp)
|
|
||||||
{
|
|
||||||
hydro_x25519_limb_t swap;
|
|
||||||
hydro_x25519_limb_t *x2 = xs[0], *x3 = xs[2], *z3 = xs[3];
|
|
||||||
hydro_x25519_fe x1i;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
hydro_x25519_swapin(x1i, x1);
|
|
||||||
x1 = (const uint8_t *) x1i;
|
|
||||||
swap = 0;
|
|
||||||
mem_zero(xs, 4 * sizeof(hydro_x25519_fe));
|
|
||||||
x2[0] = z3[0] = 1;
|
|
||||||
memcpy(x3, x1, sizeof(hydro_x25519_fe));
|
|
||||||
for (i = 255; i >= 0; i--) {
|
|
||||||
uint8_t bytei = scalar[i / 8];
|
|
||||||
hydro_x25519_limb_t doswap;
|
|
||||||
hydro_x25519_fe x1_dup;
|
|
||||||
|
|
||||||
if (clamp) {
|
|
||||||
if (i / 8 == 0) {
|
|
||||||
bytei &= ~7;
|
|
||||||
} else if (i / 8 == hydro_x25519_BYTES - 1) {
|
|
||||||
bytei &= 0x7F;
|
|
||||||
bytei |= 0x40;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
doswap = 1U + ~(hydro_x25519_limb_t) ((bytei >> (i % 8)) & 1);
|
|
||||||
hydro_x25519_condswap(x2, x3, swap ^ doswap);
|
|
||||||
swap = doswap;
|
|
||||||
hydro_x25519_ladder_part1(xs);
|
|
||||||
memcpy(x1_dup, x1, sizeof x1_dup);
|
|
||||||
hydro_x25519_ladder_part2(xs, x1_dup);
|
|
||||||
}
|
|
||||||
hydro_x25519_condswap(x2, x3, swap);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
hydro_x25519_scalarmult(uint8_t out[hydro_x25519_BYTES],
|
|
||||||
const uint8_t scalar[hydro_x25519_SECRETKEYBYTES],
|
|
||||||
const uint8_t x1[hydro_x25519_PUBLICKEYBYTES], bool clamp)
|
|
||||||
{
|
|
||||||
hydro_x25519_fe xs[5];
|
|
||||||
hydro_x25519_limb_t *x2, *z2, *z3;
|
|
||||||
hydro_x25519_limb_t *prev;
|
|
||||||
int i;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
hydro_x25519_core(xs, scalar, x1, clamp);
|
|
||||||
|
|
||||||
/* Precomputed inversion chain */
|
|
||||||
x2 = xs[0];
|
|
||||||
z2 = xs[1];
|
|
||||||
z3 = xs[3];
|
|
||||||
prev = z2;
|
|
||||||
|
|
||||||
/* Raise to the p-2 = 0x7f..ffeb */
|
|
||||||
for (i = 253; i >= 0; i--) {
|
|
||||||
hydro_x25519_sqr(z3, prev);
|
|
||||||
prev = z3;
|
|
||||||
if (i >= 8 || (0xeb >> i & 1)) {
|
|
||||||
hydro_x25519_mul1(z3, z2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Here prev = z3 */
|
|
||||||
/* x2 /= z2 */
|
|
||||||
hydro_x25519_mul1(x2, z3);
|
|
||||||
ret = hydro_x25519_canon(x2);
|
|
||||||
hydro_x25519_swapout(out, x2);
|
|
||||||
|
|
||||||
if (clamp == 0) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int
|
|
||||||
hydro_x25519_scalarmult_base(uint8_t pk[hydro_x25519_PUBLICKEYBYTES],
|
|
||||||
const uint8_t sk[hydro_x25519_SECRETKEYBYTES])
|
|
||||||
{
|
|
||||||
return hydro_x25519_scalarmult(pk, sk, hydro_x25519_BASE_POINT, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
hydro_x25519_scalarmult_base_uniform(uint8_t pk[hydro_x25519_PUBLICKEYBYTES],
|
|
||||||
const uint8_t sk[hydro_x25519_SECRETKEYBYTES])
|
|
||||||
{
|
|
||||||
if (hydro_x25519_scalarmult(pk, sk, hydro_x25519_BASE_POINT, 0) != 0) {
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
hydro_x25519_sc_montmul(hydro_x25519_scalar_t out, const hydro_x25519_scalar_t a,
|
|
||||||
const hydro_x25519_scalar_t b)
|
|
||||||
{
|
|
||||||
hydro_x25519_limb_t hic = 0;
|
|
||||||
int i, j;
|
|
||||||
|
|
||||||
for (i = 0; i < hydro_x25519_NLIMBS; i++) {
|
|
||||||
hydro_x25519_limb_t carry = 0, carry2 = 0, mand = a[i],
|
|
||||||
mand2 = hydro_x25519_MONTGOMERY_FACTOR;
|
|
||||||
|
|
||||||
for (j = 0; j < hydro_x25519_NLIMBS; j++) {
|
|
||||||
hydro_x25519_limb_t acc = out[j];
|
|
||||||
|
|
||||||
acc = hydro_x25519_umaal(&carry, acc, mand, b[j]);
|
|
||||||
if (j == 0) {
|
|
||||||
mand2 *= acc;
|
|
||||||
}
|
|
||||||
acc = hydro_x25519_umaal(&carry2, acc, mand2, hydro_x25519_sc_p[j]);
|
|
||||||
if (j > 0) {
|
|
||||||
out[j - 1] = acc;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Add two carry registers and high carry */
|
|
||||||
out[hydro_x25519_NLIMBS - 1] = hydro_x25519_adc(&hic, carry, carry2);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Reduce */
|
|
||||||
hydro_x25519_sdlimb_t scarry = 0;
|
|
||||||
for (i = 0; i < hydro_x25519_NLIMBS; i++) {
|
|
||||||
out[i] = (hydro_x25519_limb_t) (scarry = scarry + out[i] - hydro_x25519_sc_p[i]);
|
|
||||||
scarry >>= hydro_x25519_WBITS;
|
|
||||||
}
|
|
||||||
hydro_x25519_limb_t need_add = (hydro_x25519_limb_t) - (scarry + hic);
|
|
||||||
|
|
||||||
hydro_x25519_limb_t carry = 0;
|
|
||||||
for (i = 0; i < hydro_x25519_NLIMBS; i++) {
|
|
||||||
out[i] = hydro_x25519_umaal(&carry, out[i], need_add, hydro_x25519_sc_p[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,10 +0,0 @@
|
|||||||
architectures=avr,nrf52,particle-photon,particle-electron,particle-p1,esp32
|
|
||||||
author=Frank Denis <libhydrogen@pureftpd.org>
|
|
||||||
category=Other
|
|
||||||
includes=hydrogen.h
|
|
||||||
maintainer=Frank Denis <libhydrogen@pureftpd.org>
|
|
||||||
name=hydrogen-crypto
|
|
||||||
paragraph=Consistent high-level API, inspired by libsodium. Instead of low-level primitives, it exposes simple functions to solve common problems that cryptography can solve.
|
|
||||||
sentence=An easy-to-use, hard-to-misuse cryptographic library
|
|
||||||
url=https://github.com/jedisct1/libhydrogen
|
|
||||||
version=1.0.0
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 6.2 KiB |
@ -1,67 +0,0 @@
|
|||||||
project(
|
|
||||||
'libhydrogen',
|
|
||||||
'c',
|
|
||||||
license: 'ISC',
|
|
||||||
default_options: [
|
|
||||||
'buildtype=minsize',
|
|
||||||
'default_library=static',
|
|
||||||
'warning_level=2',
|
|
||||||
],
|
|
||||||
)
|
|
||||||
|
|
||||||
cc = meson.get_compiler('c')
|
|
||||||
|
|
||||||
cflags = cc.get_supported_arguments(
|
|
||||||
'-Wbad-function-cast',
|
|
||||||
'-Wcast-align',
|
|
||||||
'-Wcast-qual',
|
|
||||||
'-Wdiv-by-zero',
|
|
||||||
'-Wfloat-equal',
|
|
||||||
'-Wmissing-declarations',
|
|
||||||
'-Wmissing-prototypes',
|
|
||||||
'-Wnested-externs',
|
|
||||||
'-Wno-type-limits',
|
|
||||||
'-Wno-unknown-pragmas',
|
|
||||||
'-Wpointer-arith',
|
|
||||||
'-Wredundant-decls',
|
|
||||||
'-Wstrict-prototypes',
|
|
||||||
'-Wswitch-enum',
|
|
||||||
'-fno-exceptions',
|
|
||||||
'-mtune=native',
|
|
||||||
)
|
|
||||||
add_project_arguments(cflags, language: 'c')
|
|
||||||
|
|
||||||
include_dirs = include_directories('.')
|
|
||||||
|
|
||||||
sources = files(
|
|
||||||
'hydrogen.c',
|
|
||||||
)
|
|
||||||
|
|
||||||
libhydrogen = library(
|
|
||||||
'hydrogen',
|
|
||||||
sources,
|
|
||||||
include_directories: include_dirs,
|
|
||||||
install: true,
|
|
||||||
)
|
|
||||||
|
|
||||||
tests = executable(
|
|
||||||
'tests',
|
|
||||||
files('tests/tests.c'),
|
|
||||||
link_with: libhydrogen,
|
|
||||||
)
|
|
||||||
test('tests', tests)
|
|
||||||
|
|
||||||
install_headers(files('hydrogen.h'))
|
|
||||||
|
|
||||||
pkgconfig = import('pkgconfig')
|
|
||||||
pkgconfig.generate(
|
|
||||||
libhydrogen,
|
|
||||||
name: 'libhydrogen',
|
|
||||||
description: 'Lightweight, secure, easy-to-use crypto library suitable for constrained environments.',
|
|
||||||
url: 'https://libhydrogen.org/',
|
|
||||||
)
|
|
||||||
|
|
||||||
libhydrogen_dep = declare_dependency(
|
|
||||||
include_directories: include_dirs,
|
|
||||||
link_with: libhydrogen,
|
|
||||||
)
|
|
||||||
@ -1,493 +0,0 @@
|
|||||||
#ifdef NDEBUG
|
|
||||||
# undef NDEBUG
|
|
||||||
#endif
|
|
||||||
#include <assert.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "hydrogen.h"
|
|
||||||
|
|
||||||
static const char *ctx = "libtests";
|
|
||||||
|
|
||||||
static int
|
|
||||||
streq(const char *expected, const char *found)
|
|
||||||
{
|
|
||||||
if (strcmp(expected, found) != 0) {
|
|
||||||
fprintf(stderr, "Found: [%s]\n", found);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
#define assert_streq(EXPECTED, FOUND) assert(streq((EXPECTED), (FOUND)))
|
|
||||||
|
|
||||||
static void
|
|
||||||
test_randombytes(void)
|
|
||||||
{
|
|
||||||
uint8_t dk[hydro_random_SEEDBYTES];
|
|
||||||
uint8_t tmp[10000];
|
|
||||||
unsigned long b = 0U;
|
|
||||||
unsigned long bp;
|
|
||||||
uint32_t x;
|
|
||||||
size_t i, j;
|
|
||||||
|
|
||||||
for (i = 0; i < 10000; i++) {
|
|
||||||
x = hydro_random_u32();
|
|
||||||
for (j = 0; j < sizeof x; j++) {
|
|
||||||
b += (x >> j) & 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
assert(b > 18000 && b < 22000);
|
|
||||||
|
|
||||||
b = 0;
|
|
||||||
hydro_random_buf(tmp, sizeof tmp);
|
|
||||||
for (i = 0; i < 10000; i++) {
|
|
||||||
for (j = 0; j < sizeof tmp[0]; j++) {
|
|
||||||
b += (tmp[i] >> j) & 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
assert(b > 4500 && b < 5500);
|
|
||||||
|
|
||||||
memcpy(dk, tmp, sizeof dk);
|
|
||||||
b = 0;
|
|
||||||
hydro_random_buf_deterministic(tmp, 10000, dk);
|
|
||||||
for (i = 0; i < 10000; i++) {
|
|
||||||
for (j = 0; j < sizeof tmp[0]; j++) {
|
|
||||||
b += (tmp[i] >> j) & 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
assert(b > 4500 && b < 5500);
|
|
||||||
bp = b;
|
|
||||||
b = 0;
|
|
||||||
hydro_random_buf_deterministic(tmp, 10000, dk);
|
|
||||||
for (i = 0; i < 10000; i++) {
|
|
||||||
for (j = 0; j < sizeof tmp[0]; j++) {
|
|
||||||
b += (tmp[i] >> j) & 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
assert(b == bp);
|
|
||||||
|
|
||||||
for (i = 0; i < 1000; i++) {
|
|
||||||
for (j = 1; j < 100; j++) {
|
|
||||||
x = hydro_random_uniform((uint32_t) j);
|
|
||||||
assert(x < j);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
test_hash(void)
|
|
||||||
{
|
|
||||||
hydro_hash_state st;
|
|
||||||
uint8_t dk[hydro_random_SEEDBYTES];
|
|
||||||
uint8_t h[100];
|
|
||||||
uint8_t key[hydro_hash_KEYBYTES];
|
|
||||||
#ifdef __TRUSTINSOFT_ANALYZER__
|
|
||||||
uint8_t msg[32];
|
|
||||||
#else
|
|
||||||
uint8_t msg[1000];
|
|
||||||
#endif
|
|
||||||
char hex[100 * 2 + 1];
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
memset(dk, 0, sizeof dk);
|
|
||||||
hydro_random_buf_deterministic(key, sizeof key, dk);
|
|
||||||
hydro_increment(dk, sizeof dk);
|
|
||||||
hydro_hash_init(&st, ctx, key);
|
|
||||||
for (i = 0; i <= sizeof msg; i++) {
|
|
||||||
hydro_random_buf_deterministic(msg, i, dk);
|
|
||||||
hydro_increment(dk, sizeof dk);
|
|
||||||
hydro_hash_update(&st, msg, i);
|
|
||||||
}
|
|
||||||
hydro_hash_final(&st, h, sizeof h);
|
|
||||||
hydro_bin2hex(hex, sizeof hex, h, sizeof h);
|
|
||||||
#ifndef __TRUSTINSOFT_ANALYZER__
|
|
||||||
assert_streq(
|
|
||||||
"e5d2beb77a039965850ee76327e06b2fa6cb5121db8038b11bce4641a9c4bd843658104bdf07342570bb5fd1d7"
|
|
||||||
"2c0d31a8981b47c718fddaffbd4171605c873cbaf921bb57988dd814f3a3fbef9799ff7c762705c4bf37ab2981"
|
|
||||||
"5981bf0d8833d60afe14",
|
|
||||||
hex);
|
|
||||||
#endif
|
|
||||||
hydro_hash_hash(h, sizeof h, msg, sizeof msg, ctx, key);
|
|
||||||
hydro_bin2hex(hex, sizeof hex, h, sizeof h);
|
|
||||||
#ifndef __TRUSTINSOFT_ANALYZER__
|
|
||||||
assert_streq(
|
|
||||||
"724bd8883df73320ffd70923cb997f9a99bc670c4d78887be4975add0099fbf489b266a85d1f56743062d60a05"
|
|
||||||
"590cbce47e45108367879bf4641cbaefe584e8618cbeb8c230ae956da22c7c5c4f11a8804ca576ec20fa5da239"
|
|
||||||
"dde3d03a6018383c21f5",
|
|
||||||
hex);
|
|
||||||
#endif
|
|
||||||
hydro_hash_hash(h, hydro_hash_BYTES, msg, sizeof msg, ctx, key);
|
|
||||||
hydro_bin2hex(hex, sizeof hex, h, hydro_hash_BYTES);
|
|
||||||
#ifndef __TRUSTINSOFT_ANALYZER__
|
|
||||||
assert_streq("7dfa45ce18210e2422fd658bf7beccb6e534e44f99ae359f4af3ba41af8ca463", hex);
|
|
||||||
#endif
|
|
||||||
/* total input length is a multiple of the rate */
|
|
||||||
hydro_hash_hash(h, hydro_hash_BYTES, msg, 13, ctx, key);
|
|
||||||
hydro_bin2hex(hex, sizeof hex, h, hydro_hash_BYTES);
|
|
||||||
#ifndef __TRUSTINSOFT_ANALYZER__
|
|
||||||
assert_streq("d57a9800549bb4bab6a06fa6e16e08aad68d7d4313fb69a81b9f5d5af375dbe7", hex);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
test_core(void)
|
|
||||||
{
|
|
||||||
uint8_t x[100];
|
|
||||||
uint8_t y[100];
|
|
||||||
uint8_t a[5] = { 1, 2, 3, 4, 5 };
|
|
||||||
uint8_t b[5] = { 1, 2, 3, 4, 5 };
|
|
||||||
char hex[201];
|
|
||||||
const char *hexf;
|
|
||||||
|
|
||||||
memset(x, 0xd0, sizeof x);
|
|
||||||
hydro_memzero(x, sizeof x);
|
|
||||||
assert(x[0] == 0);
|
|
||||||
assert(x[sizeof x - 1] == 0);
|
|
||||||
hydro_increment(x, sizeof x);
|
|
||||||
assert(x[0] == 1);
|
|
||||||
assert(x[sizeof x - 1] == 0);
|
|
||||||
x[0] = 0xff;
|
|
||||||
hydro_increment(x, sizeof x);
|
|
||||||
assert(x[0] == 0);
|
|
||||||
assert(x[1] == 1);
|
|
||||||
assert(x[sizeof x - 1] == 0);
|
|
||||||
assert(hydro_equal(a, b, sizeof a));
|
|
||||||
assert(!hydro_equal(a, a, sizeof a));
|
|
||||||
assert(hydro_compare(a, b, sizeof a) == 0);
|
|
||||||
assert(hydro_compare(a, a, sizeof a) == 0);
|
|
||||||
a[0]++;
|
|
||||||
assert(hydro_compare(a, b, sizeof a) == 1);
|
|
||||||
assert(hydro_compare(b, a, sizeof a) == -1);
|
|
||||||
hydro_random_buf(x, sizeof x);
|
|
||||||
assert(hydro_bin2hex(hex, sizeof hex, x, sizeof x) != NULL);
|
|
||||||
assert(hydro_hex2bin(y, 1, hex, sizeof hex, NULL, NULL) == -1);
|
|
||||||
assert(hydro_hex2bin(y, sizeof y, hex, sizeof hex, NULL, NULL) == -1);
|
|
||||||
assert(hydro_hex2bin(y, sizeof y, hex, sizeof hex - 1, NULL, NULL) == sizeof x);
|
|
||||||
assert(hydro_equal(x, y, sizeof x));
|
|
||||||
assert(hydro_hex2bin(x, sizeof x, "452a", 4, NULL, NULL) == 2);
|
|
||||||
assert(hydro_hex2bin(y, sizeof y, "#452a#", 6, "#", NULL) == 2);
|
|
||||||
assert(hydro_equal(x, y, sizeof x));
|
|
||||||
memcpy(hex, "#452a", sizeof "#452a");
|
|
||||||
assert(hydro_hex2bin(x, sizeof x, hex, 0, NULL, &hexf) == 0);
|
|
||||||
assert(hexf == hex);
|
|
||||||
assert(hydro_hex2bin(x, sizeof x, hex, sizeof "#452a", NULL, &hexf) == 0);
|
|
||||||
assert(hexf == hex);
|
|
||||||
assert(hydro_hex2bin(x, sizeof x, hex, sizeof "#452a", "#", &hexf) == 2);
|
|
||||||
assert(hexf == hex + 6);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
test_secretbox(void)
|
|
||||||
{
|
|
||||||
uint8_t key[hydro_secretbox_KEYBYTES];
|
|
||||||
uint8_t m[25];
|
|
||||||
uint8_t m2[25];
|
|
||||||
uint8_t c[hydro_secretbox_HEADERBYTES + 25];
|
|
||||||
uint8_t dk[hydro_random_SEEDBYTES];
|
|
||||||
uint8_t probe[hydro_secretbox_PROBEBYTES];
|
|
||||||
|
|
||||||
memset(dk, 0, sizeof dk);
|
|
||||||
hydro_random_buf_deterministic(m, sizeof m, dk);
|
|
||||||
hydro_increment(dk, sizeof dk);
|
|
||||||
hydro_random_buf_deterministic(key, sizeof key, dk);
|
|
||||||
hydro_increment(dk, sizeof dk);
|
|
||||||
hydro_secretbox_encrypt(c, m, sizeof m, 0, ctx, key);
|
|
||||||
assert(hydro_secretbox_decrypt(m2, c, sizeof c, 0, ctx, key) == 0);
|
|
||||||
assert(hydro_equal(m, m2, sizeof m));
|
|
||||||
|
|
||||||
hydro_secretbox_probe_create(probe, c, sizeof c, ctx, key);
|
|
||||||
assert(hydro_secretbox_probe_verify(probe, c, sizeof c, ctx, key) == 0);
|
|
||||||
probe[0]++;
|
|
||||||
assert(hydro_secretbox_probe_verify(probe, c, sizeof c, ctx, key) == -1);
|
|
||||||
probe[0]--;
|
|
||||||
key[0]++;
|
|
||||||
assert(hydro_secretbox_probe_verify(probe, c, sizeof c, ctx, key) == -1);
|
|
||||||
key[0]--;
|
|
||||||
|
|
||||||
assert(hydro_secretbox_decrypt(m2, c, 0, 0, ctx, key) == -1);
|
|
||||||
assert(hydro_secretbox_decrypt(m2, c, 1, 0, ctx, key) == -1);
|
|
||||||
assert(hydro_secretbox_decrypt(m2, c, hydro_secretbox_HEADERBYTES, 0, ctx, key) == -1);
|
|
||||||
assert(hydro_secretbox_decrypt(m2, c, sizeof c, 1, ctx, key) == -1);
|
|
||||||
assert(!hydro_equal(m, m2, sizeof m));
|
|
||||||
key[0]++;
|
|
||||||
assert(hydro_secretbox_decrypt(m2, c, sizeof c, 0, ctx, key) == -1);
|
|
||||||
key[0]--;
|
|
||||||
c[hydro_random_uniform(sizeof c)]++;
|
|
||||||
assert(hydro_secretbox_decrypt(m2, c, sizeof c, 0, ctx, key) == -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
test_kdf(void)
|
|
||||||
{
|
|
||||||
uint8_t key[hydro_kdf_KEYBYTES];
|
|
||||||
uint8_t dk[hydro_random_SEEDBYTES];
|
|
||||||
uint8_t subkey1[16];
|
|
||||||
uint8_t subkey2[16];
|
|
||||||
uint8_t subkey3[32];
|
|
||||||
uint8_t subkey4[50];
|
|
||||||
char subkey1_hex[16 * 2 + 1];
|
|
||||||
char subkey2_hex[16 * 2 + 1];
|
|
||||||
char subkey3_hex[32 * 2 + 1];
|
|
||||||
char subkey4_hex[50 * 2 + 1];
|
|
||||||
|
|
||||||
memset(dk, 0, sizeof dk);
|
|
||||||
hydro_random_buf_deterministic(key, sizeof key, dk);
|
|
||||||
hydro_kdf_derive_from_key(subkey1, sizeof subkey1, 1, ctx, key);
|
|
||||||
hydro_kdf_derive_from_key(subkey2, sizeof subkey2, 2, ctx, key);
|
|
||||||
hydro_kdf_derive_from_key(subkey3, sizeof subkey3, 0, ctx, key);
|
|
||||||
hydro_kdf_derive_from_key(subkey4, sizeof subkey4, 0, ctx, key);
|
|
||||||
hydro_bin2hex(subkey1_hex, sizeof subkey1_hex, subkey1, sizeof subkey1);
|
|
||||||
hydro_bin2hex(subkey2_hex, sizeof subkey2_hex, subkey2, sizeof subkey2);
|
|
||||||
hydro_bin2hex(subkey3_hex, sizeof subkey3_hex, subkey3, sizeof subkey3);
|
|
||||||
hydro_bin2hex(subkey4_hex, sizeof subkey4_hex, subkey4, sizeof subkey4);
|
|
||||||
assert_streq("af8019d3516d4ba6c80a7ea5a87e4d77", subkey1_hex);
|
|
||||||
assert_streq("af8c4cba4e1f36c293631cc7001717dd", subkey2_hex);
|
|
||||||
assert_streq("ff9345489dea1e4fe59194cea8794c9b0af9380c2d18c3ab38eeef2af95c1e26", subkey3_hex);
|
|
||||||
assert_streq(
|
|
||||||
"a8dd79ca19d604d1487b82d76b8d4ad4138a29dfaeeb207b99b2e5904e7855555bb94a76070fa71871df6ed911"
|
|
||||||
"661d99efec",
|
|
||||||
subkey4_hex);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
test_sign(void)
|
|
||||||
{
|
|
||||||
#ifdef __TRUSTINSOFT_ANALYZER__
|
|
||||||
uint8_t msg[32];
|
|
||||||
#else
|
|
||||||
uint8_t msg[500];
|
|
||||||
#endif
|
|
||||||
uint8_t sig[hydro_sign_BYTES];
|
|
||||||
hydro_sign_state st;
|
|
||||||
hydro_sign_keypair kp;
|
|
||||||
|
|
||||||
hydro_random_buf(msg, sizeof msg);
|
|
||||||
hydro_sign_keygen(&kp);
|
|
||||||
hydro_sign_create(sig, msg, sizeof msg, ctx, kp.sk);
|
|
||||||
assert(hydro_sign_verify(sig, msg, sizeof msg, ctx, kp.pk) == 0);
|
|
||||||
sig[0]++;
|
|
||||||
assert(hydro_sign_verify(sig, msg, sizeof msg, ctx, kp.pk) == -1);
|
|
||||||
sig[0]--;
|
|
||||||
sig[hydro_sign_BYTES - 1]++;
|
|
||||||
assert(hydro_sign_verify(sig, msg, sizeof msg, ctx, kp.pk) == -1);
|
|
||||||
sig[hydro_sign_BYTES - 1]--;
|
|
||||||
msg[0]++;
|
|
||||||
assert(hydro_sign_verify(sig, msg, sizeof msg, ctx, kp.pk) == -1);
|
|
||||||
msg[0]++;
|
|
||||||
hydro_sign_create(sig, msg, sizeof msg, ctx, kp.sk);
|
|
||||||
|
|
||||||
hydro_sign_init(&st, ctx);
|
|
||||||
hydro_sign_update(&st, msg, (sizeof msg) / 3);
|
|
||||||
hydro_sign_update(&st, msg + (sizeof msg) / 3, (sizeof msg) - (sizeof msg) / 3);
|
|
||||||
assert(hydro_sign_final_verify(&st, sig, kp.pk) == 0);
|
|
||||||
|
|
||||||
hydro_sign_init(&st, ctx);
|
|
||||||
hydro_sign_update(&st, msg, (sizeof msg) / 3);
|
|
||||||
hydro_sign_update(&st, msg + (sizeof msg) / 3, (sizeof msg) - (sizeof msg) / 3);
|
|
||||||
hydro_sign_final_create(&st, sig, kp.sk);
|
|
||||||
|
|
||||||
hydro_sign_init(&st, ctx);
|
|
||||||
hydro_sign_update(&st, msg, (sizeof msg) / 3);
|
|
||||||
hydro_sign_update(&st, msg + (sizeof msg) / 3, (sizeof msg) - (sizeof msg) / 3);
|
|
||||||
assert(hydro_sign_final_verify(&st, sig, kp.pk) == 0);
|
|
||||||
|
|
||||||
hydro_sign_init(&st, ctx);
|
|
||||||
hydro_sign_update(&st, msg, (sizeof msg) / 3);
|
|
||||||
hydro_sign_update(&st, msg + (sizeof msg) / 3, (sizeof msg) - (sizeof msg) / 3);
|
|
||||||
sig[0]++;
|
|
||||||
assert(hydro_sign_final_verify(&st, sig, kp.pk) == -1);
|
|
||||||
|
|
||||||
hydro_sign_create(sig, msg, 0, ctx, kp.sk);
|
|
||||||
assert(hydro_sign_verify(sig, msg, sizeof msg, ctx, kp.pk) == -1);
|
|
||||||
assert(hydro_sign_verify(sig, msg, 0, ctx, kp.pk) == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
test_kx_n(void)
|
|
||||||
{
|
|
||||||
hydro_kx_keypair server_static_kp;
|
|
||||||
uint8_t psk[hydro_kx_PSKBYTES];
|
|
||||||
uint8_t packet1[hydro_kx_N_PACKET1BYTES];
|
|
||||||
hydro_kx_session_keypair kp_client;
|
|
||||||
hydro_kx_session_keypair kp_server;
|
|
||||||
|
|
||||||
hydro_kx_keygen(&server_static_kp);
|
|
||||||
hydro_random_buf(psk, sizeof psk);
|
|
||||||
|
|
||||||
hydro_kx_n_1(&kp_client, packet1, psk, server_static_kp.pk);
|
|
||||||
hydro_kx_n_2(&kp_server, packet1, psk, &server_static_kp);
|
|
||||||
|
|
||||||
assert(hydro_equal(kp_client.tx, kp_server.rx, hydro_kx_SESSIONKEYBYTES));
|
|
||||||
assert(hydro_equal(kp_client.rx, kp_server.tx, hydro_kx_SESSIONKEYBYTES));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
test_kx_kk(void)
|
|
||||||
{
|
|
||||||
hydro_kx_state st_client;
|
|
||||||
hydro_kx_keypair client_static_kp;
|
|
||||||
hydro_kx_keypair server_static_kp;
|
|
||||||
uint8_t packet1[hydro_kx_KK_PACKET1BYTES];
|
|
||||||
uint8_t packet2[hydro_kx_KK_PACKET2BYTES];
|
|
||||||
hydro_kx_session_keypair kp_client;
|
|
||||||
hydro_kx_session_keypair kp_server;
|
|
||||||
|
|
||||||
hydro_kx_keygen(&client_static_kp);
|
|
||||||
hydro_kx_keygen(&server_static_kp);
|
|
||||||
|
|
||||||
hydro_kx_kk_1(&st_client, packet1, server_static_kp.pk, &client_static_kp);
|
|
||||||
hydro_kx_kk_2(&kp_server, packet2, packet1, client_static_kp.pk, &server_static_kp);
|
|
||||||
hydro_kx_kk_3(&st_client, &kp_client, packet2, &client_static_kp);
|
|
||||||
|
|
||||||
assert(hydro_equal(kp_client.tx, kp_server.rx, hydro_kx_SESSIONKEYBYTES));
|
|
||||||
assert(hydro_equal(kp_client.rx, kp_server.tx, hydro_kx_SESSIONKEYBYTES));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
test_kx_xx(void)
|
|
||||||
{
|
|
||||||
hydro_kx_state st_client;
|
|
||||||
hydro_kx_state st_server;
|
|
||||||
hydro_kx_keypair client_static_kp;
|
|
||||||
hydro_kx_keypair server_static_kp;
|
|
||||||
uint8_t psk[hydro_kx_PSKBYTES];
|
|
||||||
uint8_t client_peer_pk[hydro_kx_PUBLICKEYBYTES];
|
|
||||||
uint8_t server_peer_pk[hydro_kx_PUBLICKEYBYTES];
|
|
||||||
uint8_t packet1[hydro_kx_XX_PACKET1BYTES];
|
|
||||||
uint8_t packet2[hydro_kx_XX_PACKET2BYTES];
|
|
||||||
uint8_t packet3[hydro_kx_XX_PACKET3BYTES];
|
|
||||||
hydro_kx_session_keypair kp_client;
|
|
||||||
hydro_kx_session_keypair kp_server;
|
|
||||||
|
|
||||||
hydro_kx_keygen(&client_static_kp);
|
|
||||||
hydro_kx_keygen(&server_static_kp);
|
|
||||||
|
|
||||||
hydro_kx_xx_1(&st_client, packet1, NULL);
|
|
||||||
hydro_kx_xx_2(&st_server, packet2, packet1, NULL, &server_static_kp);
|
|
||||||
hydro_kx_xx_3(&st_client, &kp_client, packet3, NULL, packet2, NULL, &client_static_kp);
|
|
||||||
hydro_kx_xx_4(&st_server, &kp_server, NULL, packet3, NULL);
|
|
||||||
|
|
||||||
assert(hydro_equal(kp_client.tx, kp_server.rx, hydro_kx_SESSIONKEYBYTES));
|
|
||||||
assert(hydro_equal(kp_client.rx, kp_server.tx, hydro_kx_SESSIONKEYBYTES));
|
|
||||||
|
|
||||||
hydro_random_buf(psk, sizeof psk);
|
|
||||||
hydro_kx_xx_1(&st_client, packet1, psk);
|
|
||||||
hydro_kx_xx_2(&st_server, packet2, packet1, psk, &server_static_kp);
|
|
||||||
hydro_kx_xx_3(&st_client, &kp_client, packet3, client_peer_pk, packet2, psk, &client_static_kp);
|
|
||||||
hydro_kx_xx_4(&st_server, &kp_server, server_peer_pk, packet3, psk);
|
|
||||||
|
|
||||||
assert(hydro_equal(kp_client.tx, kp_server.rx, hydro_kx_SESSIONKEYBYTES));
|
|
||||||
assert(hydro_equal(kp_client.rx, kp_server.tx, hydro_kx_SESSIONKEYBYTES));
|
|
||||||
assert(hydro_equal(client_peer_pk, server_static_kp.pk, hydro_kx_PUBLICKEYBYTES));
|
|
||||||
assert(hydro_equal(server_peer_pk, client_static_kp.pk, hydro_kx_PUBLICKEYBYTES));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
test_kx_nk(void)
|
|
||||||
{
|
|
||||||
hydro_kx_state st_client;
|
|
||||||
hydro_kx_keypair server_static_kp;
|
|
||||||
uint8_t psk[hydro_kx_PSKBYTES];
|
|
||||||
uint8_t packet1[hydro_kx_NK_PACKET1BYTES];
|
|
||||||
uint8_t packet2[hydro_kx_NK_PACKET2BYTES];
|
|
||||||
hydro_kx_session_keypair kp_client;
|
|
||||||
hydro_kx_session_keypair kp_server;
|
|
||||||
|
|
||||||
hydro_kx_keygen(&server_static_kp);
|
|
||||||
|
|
||||||
hydro_kx_nk_1(&st_client, packet1, NULL, server_static_kp.pk);
|
|
||||||
hydro_kx_nk_2(&kp_server, packet2, packet1, NULL, &server_static_kp);
|
|
||||||
hydro_kx_nk_3(&st_client, &kp_client, packet2);
|
|
||||||
|
|
||||||
assert(hydro_equal(kp_client.tx, kp_server.rx, hydro_kx_SESSIONKEYBYTES));
|
|
||||||
assert(hydro_equal(kp_client.rx, kp_server.tx, hydro_kx_SESSIONKEYBYTES));
|
|
||||||
|
|
||||||
hydro_random_buf(psk, sizeof psk);
|
|
||||||
|
|
||||||
hydro_kx_nk_1(&st_client, packet1, psk, server_static_kp.pk);
|
|
||||||
hydro_kx_nk_2(&kp_server, packet2, packet1, psk, &server_static_kp);
|
|
||||||
hydro_kx_nk_3(&st_client, &kp_client, packet2);
|
|
||||||
|
|
||||||
assert(hydro_equal(kp_client.tx, kp_server.rx, hydro_kx_SESSIONKEYBYTES));
|
|
||||||
assert(hydro_equal(kp_client.rx, kp_server.tx, hydro_kx_SESSIONKEYBYTES));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
test_pwhash(void)
|
|
||||||
{
|
|
||||||
uint8_t master_key[hydro_pwhash_MASTERKEYBYTES];
|
|
||||||
uint8_t new_master_key[hydro_pwhash_MASTERKEYBYTES];
|
|
||||||
uint8_t stored[hydro_pwhash_STOREDBYTES];
|
|
||||||
uint8_t h[64];
|
|
||||||
uint8_t static_key[64];
|
|
||||||
char h_hex[2 * 64 + 1];
|
|
||||||
unsigned long long ops = 1000;
|
|
||||||
|
|
||||||
memset(master_key, 'x', sizeof master_key);
|
|
||||||
hydro_pwhash_deterministic(h, sizeof h, "test", sizeof "test" - 1, ctx, master_key, ops, 0, 1);
|
|
||||||
hydro_bin2hex(h_hex, sizeof h_hex, h, sizeof h);
|
|
||||||
if (ops == 1000) {
|
|
||||||
assert_streq(
|
|
||||||
"2f1a804a02f25066fd0688bf8b8e03dff3a3866958a9cf5883c459e602e232d38e3e488723f0b4a2bc61d2"
|
|
||||||
"0cb36a04a4d2eb18be99bc61870d72d7de5d67f237",
|
|
||||||
h_hex);
|
|
||||||
}
|
|
||||||
|
|
||||||
hydro_pwhash_keygen(master_key);
|
|
||||||
assert(hydro_pwhash_create(stored, "test", sizeof "test" - 1, master_key, ops, 0, 1) == 0);
|
|
||||||
assert(hydro_pwhash_verify(stored, "test", sizeof "test" - 1, master_key, ops, 0, 1) == 0);
|
|
||||||
assert(hydro_pwhash_verify(stored, "test", sizeof "test" - 1, master_key, ops * 2, 10, 10) ==
|
|
||||||
0);
|
|
||||||
assert(hydro_pwhash_verify(stored, "test", sizeof "test" - 1, master_key, ops / 2, 10, 10) ==
|
|
||||||
-1);
|
|
||||||
assert(hydro_pwhash_verify(stored, "Test", sizeof "Test" - 1, master_key, ops, 0, 1) == -1);
|
|
||||||
assert(hydro_pwhash_verify(stored, "test", sizeof "tes" - 1, master_key, ops, 0, 1) == -1);
|
|
||||||
|
|
||||||
assert(hydro_pwhash_derive_static_key(static_key, sizeof static_key, stored, "test",
|
|
||||||
sizeof "test" - 1, ctx, master_key, ops, 0, 1) == 0);
|
|
||||||
assert(hydro_pwhash_derive_static_key(static_key, sizeof static_key, stored, "Test",
|
|
||||||
sizeof "Test" - 1, ctx, master_key, ops, 0, 1) == -1);
|
|
||||||
|
|
||||||
assert(hydro_pwhash_reencrypt(stored, master_key, master_key) == 0);
|
|
||||||
assert(hydro_pwhash_verify(stored, "test", sizeof "test" - 1, master_key, ops, 0, 1) == 0);
|
|
||||||
hydro_pwhash_keygen(new_master_key);
|
|
||||||
assert(hydro_pwhash_reencrypt(stored, master_key, new_master_key) == 0);
|
|
||||||
assert(hydro_pwhash_verify(stored, "test", sizeof "test" - 1, master_key, ops, 0, 1) == -1);
|
|
||||||
assert(hydro_pwhash_verify(stored, "test", sizeof "test" - 1, new_master_key, ops, 0, 1) == 0);
|
|
||||||
|
|
||||||
assert(hydro_pwhash_upgrade(stored, new_master_key, ops * 2, 0, 1) == 0);
|
|
||||||
assert(hydro_pwhash_verify(stored, "test", sizeof "test" - 1, new_master_key, ops, 0, 1) == -1);
|
|
||||||
assert(hydro_pwhash_verify(stored, "test", sizeof "test" - 1, new_master_key, ops * 2, 0, 1) ==
|
|
||||||
0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
main(void)
|
|
||||||
{
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
/*
|
|
||||||
* On Windows, disable the "Abort - Retry - Ignore" GUI dialog that otherwise pops up on
|
|
||||||
* assertion failure.
|
|
||||||
*/
|
|
||||||
_set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = hydro_init();
|
|
||||||
assert(ret == 0);
|
|
||||||
|
|
||||||
test_core();
|
|
||||||
test_hash();
|
|
||||||
test_kdf();
|
|
||||||
test_kx_n();
|
|
||||||
test_kx_kk();
|
|
||||||
test_kx_xx();
|
|
||||||
test_kx_nk();
|
|
||||||
test_pwhash();
|
|
||||||
test_randombytes();
|
|
||||||
test_secretbox();
|
|
||||||
test_sign();
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@ -1,8 +0,0 @@
|
|||||||
{
|
|
||||||
"files": [ "../tests/tests.c", "../hydrogen.c" ],
|
|
||||||
"filesystem": {
|
|
||||||
"files": [ { "name": "/dev/urandom", "from": "urandom_1" } ]
|
|
||||||
},
|
|
||||||
"val-timeout": 10800,
|
|
||||||
"no-results": "true"
|
|
||||||
}
|
|
||||||
@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"machdep": "gcc_ppc_32",
|
|
||||||
"compilation_cmd": "-I../. -U__SSE2__ -Dvolatile= -D__BYTE_ORDER__=__ORDER_BIG_ENDIAN__ -U__SIZEOF_INT128__"
|
|
||||||
}
|
|
||||||
@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"machdep": "gcc_ppc_64",
|
|
||||||
"compilation_cmd": "-I../. -U__SSE2__ -Dvolatile= -D__BYTE_ORDER__=__ORDER_BIG_ENDIAN__"
|
|
||||||
}
|
|
||||||
@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"machdep": "gcc_x86_32",
|
|
||||||
"compilation_cmd": "-I../. -U__SSE2__ -Dvolatile="
|
|
||||||
}
|
|
||||||
@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"machdep": "gcc_x86_64",
|
|
||||||
"compilation_cmd": "-I../. -U__SSE2__ -Dvolatile="
|
|
||||||
}
|
|
||||||
Binary file not shown.
@ -1,123 +0,0 @@
|
|||||||
[
|
|
||||||
{
|
|
||||||
"name": "hash - gcc_x86_32",
|
|
||||||
"main": "test_hash",
|
|
||||||
"include": "tis-ci/gcc_x86_32.config",
|
|
||||||
"include": "tis-ci/common.config"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "hash - gcc_x86_64",
|
|
||||||
"main": "test_hash",
|
|
||||||
"include": "tis-ci/gcc_x86_64.config",
|
|
||||||
"include": "tis-ci/common.config"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "hash - gcc_ppc_32",
|
|
||||||
"main": "test_hash",
|
|
||||||
"include": "tis-ci/gcc_ppc_32.config",
|
|
||||||
"include": "tis-ci/common.config"
|
|
||||||
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "hash - gcc_ppc_64",
|
|
||||||
"main": "test_hash",
|
|
||||||
"include": "tis-ci/gcc_ppc_64.config",
|
|
||||||
"include": "tis-ci/common.config"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "kdf - gcc_x86_32",
|
|
||||||
"main": "test_kdf",
|
|
||||||
"include": "tis-ci/gcc_x86_32.config",
|
|
||||||
"include": "tis-ci/common.config"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "kdf - gcc_x86_64",
|
|
||||||
"main": "test_kdf",
|
|
||||||
"include": "tis-ci/gcc_x86_64.config",
|
|
||||||
"include": "tis-ci/common.config"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "kdf - gcc_ppc_32",
|
|
||||||
"main": "test_kdf",
|
|
||||||
"include": "tis-ci/gcc_ppc_32.config",
|
|
||||||
"include": "tis-ci/common.config"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "kdf - gcc_ppc_64",
|
|
||||||
"main": "test_kdf",
|
|
||||||
"include": "tis-ci/gcc_ppc_64.config",
|
|
||||||
"include": "tis-ci/common.config"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "pwhash - gcc_x86_32",
|
|
||||||
"main": "test_pwhash",
|
|
||||||
"include": "tis-ci/gcc_x86_32.config",
|
|
||||||
"include": "tis-ci/common.config"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "pwhash - gcc_x86_64",
|
|
||||||
"main": "test_pwhash",
|
|
||||||
"include": "tis-ci/gcc_x86_64.config",
|
|
||||||
"include": "tis-ci/common.config"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "pwhash - gcc_ppc_32",
|
|
||||||
"main": "test_pwhash",
|
|
||||||
"include": "tis-ci/gcc_ppc_32.config",
|
|
||||||
"include": "tis-ci/common.config"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "pwhash - gcc_ppc_64",
|
|
||||||
"main": "test_pwhash",
|
|
||||||
"include": "tis-ci/gcc_ppc_64.config",
|
|
||||||
"include": "tis-ci/common.config"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "secretbox - gcc_x86_32",
|
|
||||||
"main": "test_secretbox",
|
|
||||||
"include": "tis-ci/gcc_x86_32.config",
|
|
||||||
"include": "tis-ci/common.config"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "secretbox - gcc_x86_64",
|
|
||||||
"main": "test_secretbox",
|
|
||||||
"include": "tis-ci/gcc_x86_64.config",
|
|
||||||
"include": "tis-ci/common.config"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "secretbox - gcc_ppc_32",
|
|
||||||
"main": "test_secretbox",
|
|
||||||
"include": "tis-ci/gcc_ppc_32.config",
|
|
||||||
"include": "tis-ci/common.config"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "secretbox - gcc_ppc_64",
|
|
||||||
"main": "test_secretbox",
|
|
||||||
"include": "tis-ci/gcc_ppc_64.config",
|
|
||||||
"include": "tis-ci/common.config"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "sign - gcc_x86_32",
|
|
||||||
"main": "test_sign",
|
|
||||||
"include": "tis-ci/gcc_x86_32.config",
|
|
||||||
"include": "tis-ci/common.config"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "sign - gcc_x86_64",
|
|
||||||
"main": "test_sign",
|
|
||||||
"include": "tis-ci/gcc_x86_64.config",
|
|
||||||
"include": "tis-ci/common.config"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "sign - gcc_ppc_32",
|
|
||||||
"main": "test_sign",
|
|
||||||
"include": "tis-ci/gcc_ppc_32.config",
|
|
||||||
"include": "tis-ci/common.config"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "sign - gcc_ppc_64",
|
|
||||||
"main": "test_sign",
|
|
||||||
"include": "tis-ci/gcc_ppc_64.config",
|
|
||||||
"include": "tis-ci/common.config"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
@ -3,7 +3,6 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <hydrogen.h>
|
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
|
||||||
#include "inter.h"
|
#include "inter.h"
|
||||||
@ -54,7 +53,7 @@ int weekday_from_day(int year, int month, int day) {
|
|||||||
int calendar_week_from_day(int year, int month, int day){
|
int calendar_week_from_day(int year, int month, int day){
|
||||||
int days_sum[] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
|
int days_sum[] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
|
||||||
int days = days_sum[month - 1];
|
int days = days_sum[month - 1];
|
||||||
if (is_leap_year(year) && month > 2)
|
if(is_leap_year(year) && month > 2)
|
||||||
days++;
|
days++;
|
||||||
|
|
||||||
return (10 + days + day - weekday_from_day(year, month, day)) / 7;
|
return (10 + days + day - weekday_from_day(year, month, day)) / 7;
|
||||||
@ -68,18 +67,7 @@ int days_per_month(int year, int month){
|
|||||||
return days_in_month[month - 1];
|
return days_in_month[month - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
#define HYDROGEN_CONTEXT "WorkCalS"
|
void init(){
|
||||||
#define HYDROGEN_OPSLIMIT 10000
|
|
||||||
#define HYDROGEN_MEMLIMIT 0
|
|
||||||
#define HYDROGEN_THREADS 1
|
|
||||||
static uint8_t master_key[hydro_pwhash_MASTERKEYBYTES] = { 0x6c, 0x2e, 0xed, 0x47, 0x36, 0x29, 0xda, 0x11, 0x6e, 0xf4, 0x41, 0x66, 0x3b, 0xd7, 0xfa, 0x72, 0xf7, 0x51, 0x48, 0x6d, 0x10, 0x7b, 0xa5, 0x04, 0x00, 0x11, 0x2e, 0xc4, 0xf2, 0xdb, 0x77, 0x51 };
|
|
||||||
static uint8_t derived_key[hydro_secretbox_KEYBYTES];
|
|
||||||
|
|
||||||
static char password_input_buffer[256];
|
|
||||||
static char password_confirmation_input_buffer[256];
|
|
||||||
|
|
||||||
void init() {
|
|
||||||
hydro_init();
|
|
||||||
ImGuiIO &io = ImGui::GetIO();
|
ImGuiIO &io = ImGui::GetIO();
|
||||||
inter_regular = io.Fonts->AddFontFromMemoryCompressedTTF(inter_compressed_data, inter_compressed_size);
|
inter_regular = io.Fonts->AddFontFromMemoryCompressedTTF(inter_compressed_data, inter_compressed_size);
|
||||||
inter_bold = io.Fonts->AddFontFromMemoryCompressedTTF(inter_bold_compressed_data, inter_bold_compressed_size);
|
inter_bold = io.Fonts->AddFontFromMemoryCompressedTTF(inter_bold_compressed_data, inter_bold_compressed_size);
|
||||||
@ -116,115 +104,68 @@ static uint32_t num_categorized_days = 0;
|
|||||||
static Categorized_Day categorized_days[365*50];
|
static Categorized_Day categorized_days[365*50];
|
||||||
|
|
||||||
//Colors
|
//Colors
|
||||||
static ImVec4 table_white_bg = ImVec4(1.0f, 1.0f, 1.0f, 1.0f);
|
ImVec4 table_white_bg = ImVec4(1.0f, 1.0f, 1.0f, 1.0f);
|
||||||
static ImVec4 table_saturday_bg = ImVec4(0.0f, 0.0f, 0.0f, 0.1f);
|
ImVec4 table_saturday_bg = ImVec4(0.0f, 0.0f, 0.0f, 0.1f);
|
||||||
static ImVec4 table_sunday_bg = ImVec4(0.0f, 0.0f, 0.0f, 0.2f);
|
ImVec4 table_sunday_bg = ImVec4(0.0f, 0.0f, 0.0f, 0.2f);
|
||||||
|
|
||||||
static ImVec4 table_hover_color = ImVec4(0.0f, 0.3f, 0.6f, 0.2f);
|
ImVec4 table_hover_color = ImVec4(0.0f, 0.3f, 0.6f, 0.2f);
|
||||||
|
|
||||||
static char plaintext_buffer[2 * 1024 * 1024] = {};
|
|
||||||
static char encrypted_buffer[hydro_secretbox_HEADERBYTES + sizeof(plaintext_buffer)];
|
|
||||||
|
|
||||||
void save(){
|
void save(){
|
||||||
if (!save_file_path) return;
|
if(!save_file_path) return;
|
||||||
|
|
||||||
uint32_t version = 1;
|
uint32_t version = 1;
|
||||||
#define write_to_buffer(x) memcpy(plaintext_buffer + offset, &(x), sizeof(x)); offset += sizeof(x);
|
FILE *save_file = fopen(save_file_path, "wb");
|
||||||
|
fwrite(&version, sizeof(version), 1, save_file);
|
||||||
size_t offset = 0;
|
fwrite(&num_categories, sizeof(num_categories), 1, save_file);
|
||||||
write_to_buffer(version);
|
fwrite(&num_categorized_days, sizeof(num_categorized_days), 1, save_file);
|
||||||
write_to_buffer(num_categories);
|
|
||||||
write_to_buffer(num_categorized_days);
|
|
||||||
|
|
||||||
for (int i = 0; i < num_categories; i++) {
|
for (int i = 0; i < num_categories; i++) {
|
||||||
write_to_buffer(categories[i].color);
|
fwrite(&categories[i].color, sizeof(categories[i].color), 1, save_file);
|
||||||
write_to_buffer(categories[i].name);
|
fwrite(&categories[i].name, sizeof(categories[i].name), 1, save_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < num_categorized_days; i++) {
|
for (int i = 0; i < num_categorized_days; i++) {
|
||||||
write_to_buffer(categorized_days[i].year);
|
fwrite(&categorized_days[i].year, sizeof(categorized_days[i].year), 1, save_file);
|
||||||
write_to_buffer(categorized_days[i].month);
|
fwrite(&categorized_days[i].month, sizeof(categorized_days[i].month), 1, save_file);
|
||||||
write_to_buffer(categorized_days[i].day);
|
fwrite(&categorized_days[i].day, sizeof(categorized_days[i].day), 1, save_file);
|
||||||
write_to_buffer(categorized_days[i].category);
|
fwrite(&categorized_days[i].category, sizeof(categorized_days[i].category), 1, save_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef write_to_buffer
|
|
||||||
|
|
||||||
if (hydro_secretbox_encrypt((uint8_t *)encrypted_buffer, plaintext_buffer, offset, 0, HYDROGEN_CONTEXT, derived_key) != 0) {
|
|
||||||
return; //TODO error message
|
|
||||||
}
|
|
||||||
hydro_memzero(plaintext_buffer, sizeof(plaintext_buffer));
|
|
||||||
|
|
||||||
FILE *save_file = fopen(save_file_path, "wb");
|
|
||||||
fwrite(encrypted_buffer, hydro_secretbox_HEADERBYTES + offset, 1, save_file);
|
|
||||||
fclose (save_file);
|
fclose (save_file);
|
||||||
hydro_memzero(encrypted_buffer, sizeof(encrypted_buffer));
|
|
||||||
|
|
||||||
char *title = (char *)calloc(1, strlen("Work Calendar - ") + strlen(save_file_path) + 1);
|
|
||||||
memcpy(title, "Work Calendar - ", strlen("Work Calendar - "));
|
|
||||||
memcpy(title + strlen("Work Calendar - "), save_file_path, strlen(save_file_path));
|
|
||||||
|
|
||||||
set_window_title(title);
|
|
||||||
free(title);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void load(){
|
void load(){
|
||||||
|
|
||||||
FILE *save_file = fopen(save_file_path, "rb");
|
FILE *save_file = fopen(save_file_path, "rb");
|
||||||
size_t num_bytes = fread(encrypted_buffer, 1, sizeof(encrypted_buffer), save_file);
|
|
||||||
fclose (save_file);
|
|
||||||
|
|
||||||
if ( num_bytes <= 0) {
|
|
||||||
return; //TODO Popup warning
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hydro_secretbox_decrypt(plaintext_buffer, (uint8_t *)encrypted_buffer, num_bytes, 0, HYDROGEN_CONTEXT, derived_key) != 0){
|
|
||||||
return; //TODO Popup warning
|
|
||||||
}
|
|
||||||
hydro_memzero(encrypted_buffer, sizeof(encrypted_buffer));
|
|
||||||
|
|
||||||
#define read_from_buffer(x) memcpy(&(x), plaintext_buffer + offset, sizeof(x)); offset += sizeof(x);
|
|
||||||
|
|
||||||
size_t offset = 0;
|
|
||||||
uint32_t version = 0;
|
uint32_t version = 0;
|
||||||
read_from_buffer(version);
|
fread(&version, sizeof(version), 1, save_file);
|
||||||
if (version != 1) {
|
if(version != 1) {
|
||||||
return; //TODO Popup warning
|
return; //TODO Popup warning
|
||||||
}
|
}
|
||||||
|
|
||||||
read_from_buffer(num_categories);
|
fread(&num_categories, sizeof(num_categories), 1, save_file);
|
||||||
read_from_buffer(num_categorized_days);
|
fread(&num_categorized_days, sizeof(num_categorized_days), 1, save_file);
|
||||||
|
|
||||||
if (num_categories > IM_ARRAYSIZE(categories) || num_categorized_days > IM_ARRAYSIZE(categorized_days)){
|
if(num_categories > IM_ARRAYSIZE(categories) || num_categorized_days > IM_ARRAYSIZE(categorized_days)){
|
||||||
return; //TODO Popup warning
|
return; //TODO Popup warning
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < num_categories; i++) {
|
for (int i = 0; i < num_categories; i++) {
|
||||||
read_from_buffer(categories[i].color);
|
fread(&categories[i].color, sizeof(categories[i].color), 1, save_file);
|
||||||
read_from_buffer(categories[i].name);
|
fread(&categories[i].name, sizeof(categories[i].name), 1, save_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < num_categorized_days; i++) {
|
for (int i = 0; i < num_categorized_days; i++) {
|
||||||
read_from_buffer(categorized_days[i].year);
|
fread(&categorized_days[i].year, sizeof(categorized_days[i].year), 1, save_file);
|
||||||
read_from_buffer(categorized_days[i].month);
|
fread(&categorized_days[i].month, sizeof(categorized_days[i].month), 1, save_file);
|
||||||
read_from_buffer(categorized_days[i].day);
|
fread(&categorized_days[i].day, sizeof(categorized_days[i].day), 1, save_file);
|
||||||
read_from_buffer(categorized_days[i].category);
|
fread(&categorized_days[i].category, sizeof(categorized_days[i].category), 1, save_file);
|
||||||
}
|
}
|
||||||
#undef read_from_buffer
|
|
||||||
|
|
||||||
hydro_memzero(plaintext_buffer, sizeof(plaintext_buffer));
|
fclose (save_file);
|
||||||
|
|
||||||
char *title = (char *)calloc(1, strlen("Work Calendar - ") + strlen(save_file_path) + 1);
|
|
||||||
memcpy(title, "Work Calendar - ", strlen("Work Calendar - "));
|
|
||||||
memcpy(title + strlen("Work Calendar - "), save_file_path, strlen(save_file_path));
|
|
||||||
|
|
||||||
set_window_title(title);
|
|
||||||
free(title);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void per_frame(){
|
void per_frame(){
|
||||||
ImGuiStyle &style = ImGui::GetStyle();
|
ImGuiStyle &style = ImGui::GetStyle();
|
||||||
ImVec2 center = ImGui::GetMainViewport()->GetCenter();
|
|
||||||
|
|
||||||
year_min_size = ImGui::CalcTextSize("8888").x + 5;
|
year_min_size = ImGui::CalcTextSize("8888").x + 5;
|
||||||
|
|
||||||
@ -243,17 +184,26 @@ void per_frame(){
|
|||||||
ImGui::DockSpaceOverViewport(main_viewport_dock, ImGui::GetMainViewport(), ImGuiDockNodeFlags_NoTabBar);
|
ImGui::DockSpaceOverViewport(main_viewport_dock, ImGui::GetMainViewport(), ImGuiDockNodeFlags_NoTabBar);
|
||||||
|
|
||||||
ImGuiID close_popup = ImGui::GetID("Close");
|
ImGuiID close_popup = ImGui::GetID("Close");
|
||||||
ImGuiID save_password_popup = ImGui::GetID("Passwort eingeben##Save");
|
ImGuiID open_popup = ImGui::GetID("Open");
|
||||||
ImGuiID open_password_popup = ImGui::GetID("Passwort eingeben##Open");
|
ImGuiID save_popup = ImGui::GetID("Save");
|
||||||
|
ImGuiID logout_popup = ImGui::GetID("Logout"); //TODO
|
||||||
|
ImGuiID about_popup = ImGui::GetID("About");
|
||||||
|
|
||||||
if (ImGui::BeginMainMenuBar()) {
|
if (ImGui::BeginMainMenuBar()) {
|
||||||
if (ImGui::BeginMenu("Datei")) {
|
if (ImGui::BeginMenu("Datei")) {
|
||||||
if (ImGui::MenuItem("Öffnen", "Ctrl + O")) {
|
if (ImGui::MenuItem("Öffnen", "Ctrl + O")) {
|
||||||
char *new_save_file_path = open_file_dialog();
|
char *new_save_file_path = open_file_dialog();
|
||||||
if (new_save_file_path) {
|
if(new_save_file_path) {
|
||||||
if (save_file_path) free(save_file_path);
|
if(save_file_path) free(save_file_path);
|
||||||
save_file_path = new_save_file_path;
|
save_file_path = new_save_file_path;
|
||||||
ImGui::OpenPopup(open_password_popup);
|
load();
|
||||||
|
|
||||||
|
char *title = (char *)calloc(1, strlen("Work Calendar - ") + strlen(save_file_path) + 1);
|
||||||
|
memcpy(title, "Work Calendar - ", strlen("Work Calendar - "));
|
||||||
|
memcpy(title + strlen("Work Calendar - "), save_file_path, strlen(save_file_path));
|
||||||
|
|
||||||
|
set_window_title(title);
|
||||||
|
free(title);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ImGui::MenuItem("Speichern", "Ctrl + S", false, !!save_file_path)) {
|
if (ImGui::MenuItem("Speichern", "Ctrl + S", false, !!save_file_path)) {
|
||||||
@ -262,27 +212,23 @@ void per_frame(){
|
|||||||
|
|
||||||
if (ImGui::MenuItem("Speichern unter", "Ctrl + Shift + S")) {
|
if (ImGui::MenuItem("Speichern unter", "Ctrl + Shift + S")) {
|
||||||
char *new_save_file_path = save_file_dialog();
|
char *new_save_file_path = save_file_dialog();
|
||||||
if (new_save_file_path) {
|
if(new_save_file_path) {
|
||||||
if (save_file_path) free(save_file_path);
|
if(save_file_path) free(save_file_path);
|
||||||
save_file_path = new_save_file_path;
|
save_file_path = new_save_file_path;
|
||||||
ImGui::OpenPopup(save_password_popup);
|
save();
|
||||||
|
|
||||||
|
char *title = (char *)calloc(1, strlen("Work Calendar - ") + strlen(save_file_path) + 1);
|
||||||
|
memcpy(title, "Work Calendar - ", strlen("Work Calendar - "));
|
||||||
|
memcpy(title + strlen("Work Calendar - "), save_file_path, strlen(save_file_path));
|
||||||
|
|
||||||
|
set_window_title(title);
|
||||||
|
free(title);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO
|
//TODO
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
if (ImGui::MenuItem("Kalender Schließen", "Ctrl + X")) {
|
ImGui::MenuItem("Kalender Schließen", "Ctrl + X");
|
||||||
//TODO if calendar is opened warning
|
|
||||||
|
|
||||||
if (save_file_path) free(save_file_path);
|
|
||||||
save_file_path = NULL;
|
|
||||||
num_categories = 0;
|
|
||||||
num_categorized_days = 0;
|
|
||||||
hydro_memzero(categories, sizeof(categories));
|
|
||||||
hydro_memzero(categorized_days, sizeof(categorized_days));
|
|
||||||
hydro_memzero(derived_key, sizeof(derived_key));
|
|
||||||
set_window_title("Work Calendar");
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
if (ImGui::MenuItem("Beenden", NULL)) {
|
if (ImGui::MenuItem("Beenden", NULL)) {
|
||||||
@ -309,78 +255,7 @@ void per_frame(){
|
|||||||
ImGui::EndMainMenuBar();
|
ImGui::EndMainMenuBar();
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::SetNextWindowPos(center, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
|
ImVec2 center = ImGui::GetMainViewport()->GetCenter();
|
||||||
if (ImGui::BeginPopupModal("Passwort eingeben##Save", NULL, ImGuiWindowFlags_AlwaysAutoResize)) {
|
|
||||||
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.0f);
|
|
||||||
|
|
||||||
ImGui::AlignTextToFramePadding();
|
|
||||||
ImGui::Text("Passwort");
|
|
||||||
ImGui::SameLine();
|
|
||||||
ImGui::SetNextItemWidth(-1);
|
|
||||||
ImGui::InputText("##Passwort", password_input_buffer, sizeof(password_input_buffer), ImGuiInputTextFlags_Password);
|
|
||||||
|
|
||||||
ImGui::AlignTextToFramePadding();
|
|
||||||
ImGui::Text("Passwort bestätigen");
|
|
||||||
ImGui::SameLine();
|
|
||||||
ImGui::SetNextItemWidth(-1);
|
|
||||||
ImGui::InputText("##Passwort bestätigen", password_confirmation_input_buffer, sizeof(password_confirmation_input_buffer), ImGuiInputTextFlags_Password);
|
|
||||||
|
|
||||||
ImGui::PopStyleVar();
|
|
||||||
|
|
||||||
if (ImGui::Button("OK", ImVec2(120, 0))) {
|
|
||||||
if (hydro_compare((uint8_t *)password_input_buffer, (uint8_t *) password_confirmation_input_buffer, sizeof(password_input_buffer)) == 0) {
|
|
||||||
hydro_pwhash_deterministic(derived_key, sizeof derived_key, password_input_buffer, strlen(password_input_buffer), HYDROGEN_CONTEXT,
|
|
||||||
master_key, HYDROGEN_OPSLIMIT, HYDROGEN_MEMLIMIT, HYDROGEN_THREADS);
|
|
||||||
save();
|
|
||||||
ImGui::CloseCurrentPopup();
|
|
||||||
hydro_memzero(password_input_buffer, sizeof(password_input_buffer));
|
|
||||||
hydro_memzero(password_confirmation_input_buffer, sizeof(password_confirmation_input_buffer));
|
|
||||||
}
|
|
||||||
//TODO color input red + message
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::SameLine();
|
|
||||||
if (ImGui::Button("Abbrechen", ImVec2(120, 0))) {
|
|
||||||
ImGui::CloseCurrentPopup();
|
|
||||||
hydro_memzero(password_input_buffer, sizeof(password_input_buffer));
|
|
||||||
hydro_memzero(password_confirmation_input_buffer, sizeof(password_confirmation_input_buffer));
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::EndPopup();
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::SetNextWindowPos(center, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
|
|
||||||
if (ImGui::BeginPopupModal("Passwort eingeben##Open", NULL, ImGuiWindowFlags_AlwaysAutoResize)) {
|
|
||||||
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.0f);
|
|
||||||
|
|
||||||
ImGui::AlignTextToFramePadding();
|
|
||||||
ImGui::Text("Passwort");
|
|
||||||
ImGui::SameLine();
|
|
||||||
ImGui::SetNextItemWidth(-1);
|
|
||||||
ImGui::InputText("##Passwort", password_input_buffer, sizeof(password_input_buffer), ImGuiInputTextFlags_Password);
|
|
||||||
|
|
||||||
ImGui::PopStyleVar();
|
|
||||||
|
|
||||||
if (ImGui::Button("OK", ImVec2(120, 0))) {
|
|
||||||
hydro_pwhash_deterministic(derived_key, sizeof derived_key, password_input_buffer, strlen(password_input_buffer), HYDROGEN_CONTEXT,
|
|
||||||
master_key, HYDROGEN_OPSLIMIT, HYDROGEN_MEMLIMIT, HYDROGEN_THREADS);
|
|
||||||
hydro_memzero(password_input_buffer, sizeof(password_input_buffer));
|
|
||||||
|
|
||||||
load();
|
|
||||||
ImGui::CloseCurrentPopup();
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::SameLine();
|
|
||||||
if (ImGui::Button("Abbrechen", ImVec2(120, 0))) {
|
|
||||||
if (save_file_path) free(save_file_path);
|
|
||||||
save_file_path = NULL;
|
|
||||||
ImGui::CloseCurrentPopup();
|
|
||||||
hydro_memzero(password_input_buffer, sizeof(password_input_buffer));
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::EndPopup();
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::SetNextWindowPos(center, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
|
ImGui::SetNextWindowPos(center, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
|
||||||
if (ImGui::BeginPopupModal("Close", NULL, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_AlwaysAutoResize)) {
|
if (ImGui::BeginPopupModal("Close", NULL, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_AlwaysAutoResize)) {
|
||||||
ImGui::Text("Möchten Sie wirklich beenden?");
|
ImGui::Text("Möchten Sie wirklich beenden?");
|
||||||
@ -404,7 +279,7 @@ void per_frame(){
|
|||||||
ImGui::PushStyleColor(ImGuiCol_HeaderHovered, {0,0,0,0});
|
ImGui::PushStyleColor(ImGuiCol_HeaderHovered, {0,0,0,0});
|
||||||
ImGui::PushStyleColor(ImGuiCol_HeaderActive, {0,0,0,0});
|
ImGui::PushStyleColor(ImGuiCol_HeaderActive, {0,0,0,0});
|
||||||
|
|
||||||
if (ImGui::BeginTable("CalendarHeader", 5)) {
|
if(ImGui::BeginTable("CalendarHeader", 5)) {
|
||||||
|
|
||||||
ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthStretch); // Left side
|
ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthStretch); // Left side
|
||||||
ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthFixed); // Prev year
|
ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthFixed); // Prev year
|
||||||
@ -435,7 +310,7 @@ void per_frame(){
|
|||||||
ImGui::PushStyleColor(ImGuiCol_TableBorderStrong, {0,0,0,0});
|
ImGui::PushStyleColor(ImGuiCol_TableBorderStrong, {0,0,0,0});
|
||||||
ImGui::PushStyleColor(ImGuiCol_TableBorderLight, {0,0,0,0});
|
ImGui::PushStyleColor(ImGuiCol_TableBorderLight, {0,0,0,0});
|
||||||
|
|
||||||
if (ImGui::BeginTable("Month", 1, ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_NoHostExtendX)) {
|
if(ImGui::BeginTable("Month", 1, ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_NoHostExtendX)) {
|
||||||
ImGui::TableNextRow();
|
ImGui::TableNextRow();
|
||||||
ImGui::TableSetColumnIndex(0);
|
ImGui::TableSetColumnIndex(0);
|
||||||
ImGui::TextAligned(0.5, -FLT_MIN, month_names[month - 1]);
|
ImGui::TextAligned(0.5, -FLT_MIN, month_names[month - 1]);
|
||||||
@ -444,7 +319,7 @@ void per_frame(){
|
|||||||
ImGui::TableSetColumnIndex(0);
|
ImGui::TableSetColumnIndex(0);
|
||||||
|
|
||||||
//calendar week table
|
//calendar week table
|
||||||
if (ImGui::BeginTable("CalendarWeek", 1, ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_NoHostExtendX | ImGuiTableFlags_Borders)){
|
if(ImGui::BeginTable("CalendarWeek", 1, ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_NoHostExtendX | ImGuiTableFlags_Borders)){
|
||||||
ImGui::TableNextRow();
|
ImGui::TableNextRow();
|
||||||
ImGui::TableSetColumnIndex(0);
|
ImGui::TableSetColumnIndex(0);
|
||||||
ImGui::TextAligned(0.5, -FLT_MIN, "KW");
|
ImGui::TextAligned(0.5, -FLT_MIN, "KW");
|
||||||
@ -452,13 +327,13 @@ void per_frame(){
|
|||||||
for (int day = 1; day <= days_per_month(year, month); day++) {
|
for (int day = 1; day <= days_per_month(year, month); day++) {
|
||||||
int weekday = weekday_from_day(year, month, day);
|
int weekday = weekday_from_day(year, month, day);
|
||||||
|
|
||||||
if (weekday == 0 || day == 1){
|
if(weekday == 0 || day == 1){
|
||||||
ImGui::TableNextRow();
|
ImGui::TableNextRow();
|
||||||
ImGui::TableSetColumnIndex(0);
|
ImGui::TableSetColumnIndex(0);
|
||||||
|
|
||||||
//if first week has 3 or less days, last week from previous year
|
//if first week has 3 or less days, last week from previous year
|
||||||
int calender_week = calendar_week_from_day(year, month, day);
|
int calender_week = calendar_week_from_day(year, month, day);
|
||||||
if (calender_week == 0) {
|
if(calender_week == 0) {
|
||||||
ImGui::TextAligned(0.5, -FLT_MIN, "%d", 53);
|
ImGui::TextAligned(0.5, -FLT_MIN, "%d", 53);
|
||||||
} else {
|
} else {
|
||||||
ImGui::TextAligned(0.5, -FLT_MIN, "%d", calender_week);
|
ImGui::TextAligned(0.5, -FLT_MIN, "%d", calender_week);
|
||||||
@ -473,7 +348,7 @@ void per_frame(){
|
|||||||
ImGui::BeginGroup();
|
ImGui::BeginGroup();
|
||||||
ImGui::PushStyleVarY(ImGuiStyleVar_ItemSpacing, 0);
|
ImGui::PushStyleVarY(ImGuiStyleVar_ItemSpacing, 0);
|
||||||
|
|
||||||
if (ImGui::BeginTable("Weekdays", 7, ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_NoHostExtendX | ImGuiTableFlags_Borders)){
|
if(ImGui::BeginTable("Weekdays", 7, ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_NoHostExtendX | ImGuiTableFlags_Borders)){
|
||||||
|
|
||||||
ImGui::TableSetupColumn("Mo");
|
ImGui::TableSetupColumn("Mo");
|
||||||
ImGui::TableSetupColumn("Di");
|
ImGui::TableSetupColumn("Di");
|
||||||
@ -492,13 +367,13 @@ void per_frame(){
|
|||||||
ImGui::PushStyleColor(ImGuiCol_TableBorderLight, {119/255.0f,119/255.0f,119/255.0f,83/255.0f});
|
ImGui::PushStyleColor(ImGuiCol_TableBorderLight, {119/255.0f,119/255.0f,119/255.0f,83/255.0f});
|
||||||
|
|
||||||
//days of month table
|
//days of month table
|
||||||
if (ImGui::BeginTable("Weekdays", 7, ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_NoHostExtendX | ImGuiTableFlags_Borders)) {
|
if(ImGui::BeginTable("Weekdays", 7, ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_NoHostExtendX | ImGuiTableFlags_Borders)) {
|
||||||
int offset = weekday_from_day(year, month, 1);
|
int offset = weekday_from_day(year, month, 1);
|
||||||
|
|
||||||
for (int day = 1; day <= days_per_month(2025, month); day++) {
|
for (int day = 1; day <= days_per_month(2025, month); day++) {
|
||||||
int weekday = weekday_from_day(year, month, day);
|
int weekday = weekday_from_day(year, month, day);
|
||||||
|
|
||||||
if (weekday == 0 || day == 1){
|
if(weekday == 0 || day == 1){
|
||||||
ImGui::TableNextRow();
|
ImGui::TableNextRow();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -507,12 +382,12 @@ void per_frame(){
|
|||||||
ImGui::TableSetBgColor(ImGuiTableBgTarget_CellBg, cell_bg_color_workweek);
|
ImGui::TableSetBgColor(ImGuiTableBgTarget_CellBg, cell_bg_color_workweek);
|
||||||
|
|
||||||
//weekend coloring
|
//weekend coloring
|
||||||
if (weekday == 5){
|
if(weekday == 5){
|
||||||
ImU32 cell_bg_color_sat = ImGui::GetColorU32(table_saturday_bg);
|
ImU32 cell_bg_color_sat = ImGui::GetColorU32(table_saturday_bg);
|
||||||
ImGui::TableSetBgColor(ImGuiTableBgTarget_CellBg, cell_bg_color_sat);
|
ImGui::TableSetBgColor(ImGuiTableBgTarget_CellBg, cell_bg_color_sat);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (weekday == 6){
|
if(weekday == 6){
|
||||||
ImU32 cell_bg_color_sun = ImGui::GetColorU32(table_sunday_bg);
|
ImU32 cell_bg_color_sun = ImGui::GetColorU32(table_sunday_bg);
|
||||||
ImGui::TableSetBgColor(ImGuiTableBgTarget_CellBg, cell_bg_color_sun);
|
ImGui::TableSetBgColor(ImGuiTableBgTarget_CellBg, cell_bg_color_sun);
|
||||||
}
|
}
|
||||||
@ -527,15 +402,15 @@ void per_frame(){
|
|||||||
color.Value.w = 0.5;
|
color.Value.w = 0.5;
|
||||||
|
|
||||||
//sat + sun: add alpha value
|
//sat + sun: add alpha value
|
||||||
if (weekday == 5)
|
if(weekday == 5)
|
||||||
color.Value.w = color.Value.w + table_saturday_bg.w;
|
color.Value.w = color.Value.w + table_saturday_bg.w;
|
||||||
if (weekday == 6)
|
if(weekday == 6)
|
||||||
color.Value.w = color.Value.w + table_sunday_bg.w;
|
color.Value.w = color.Value.w + table_sunday_bg.w;
|
||||||
|
|
||||||
ImGui::TableSetBgColor(ImGuiTableBgTarget_CellBg, ImU32(color));
|
ImGui::TableSetBgColor(ImGuiTableBgTarget_CellBg, ImU32(color));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (current_year == year && current_month == month && current_day == day ) {
|
if(current_year == year && current_month == month && current_day == day ) {
|
||||||
ImGui::PushFont(inter_bold);
|
ImGui::PushFont(inter_bold);
|
||||||
ImGui::TextAligned(0.5, -FLT_MIN, "%d", day);
|
ImGui::TextAligned(0.5, -FLT_MIN, "%d", day);
|
||||||
ImGui::PopFont();
|
ImGui::PopFont();
|
||||||
@ -543,8 +418,8 @@ void per_frame(){
|
|||||||
ImGui::TextAligned(0.5, -FLT_MIN, "%d", day);
|
ImGui::TextAligned(0.5, -FLT_MIN, "%d", day);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ImGui::IsItemHovered()){
|
if(ImGui::IsItemHovered()){
|
||||||
if (selected_category != -1) {
|
if(selected_category != -1) {
|
||||||
ImColor hover_color = categories[selected_category].color;
|
ImColor hover_color = categories[selected_category].color;
|
||||||
hover_color.Value.w = 0.2;
|
hover_color.Value.w = 0.2;
|
||||||
ImGui::TableSetBgColor(ImGuiTableBgTarget_CellBg, ImGui::GetColorU32(ImU32(hover_color)));
|
ImGui::TableSetBgColor(ImGuiTableBgTarget_CellBg, ImGui::GetColorU32(ImU32(hover_color)));
|
||||||
@ -611,7 +486,7 @@ void per_frame(){
|
|||||||
|
|
||||||
// Legende
|
// Legende
|
||||||
if (legend_visible && ImGui::Begin("Legende", 0)) {
|
if (legend_visible && ImGui::Begin("Legende", 0)) {
|
||||||
if (ImGui::BeginTable("Legend", 4, ImGuiTableFlags_SizingStretchProp)) {
|
if(ImGui::BeginTable("Legend", 4, ImGuiTableFlags_SizingStretchProp)) {
|
||||||
ImGui::TableSetupColumn("Color", ImGuiTableColumnFlags_WidthFixed);
|
ImGui::TableSetupColumn("Color", ImGuiTableColumnFlags_WidthFixed);
|
||||||
ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_WidthStretch);
|
ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_WidthStretch);
|
||||||
ImGui::TableSetupColumn("Edit", ImGuiTableColumnFlags_WidthFixed);
|
ImGui::TableSetupColumn("Edit", ImGuiTableColumnFlags_WidthFixed);
|
||||||
@ -632,7 +507,7 @@ void per_frame(){
|
|||||||
ImGui::TableSetColumnIndex(1);
|
ImGui::TableSetColumnIndex(1);
|
||||||
if (category.editing) {
|
if (category.editing) {
|
||||||
ImGui::SetNextItemWidth(-1);
|
ImGui::SetNextItemWidth(-1);
|
||||||
if (ImGui::InputText("##name", category.name, IM_ARRAYSIZE(category.name), ImGuiInputTextFlags_EnterReturnsTrue)) {
|
if(ImGui::InputText("##name", category.name, IM_ARRAYSIZE(category.name), ImGuiInputTextFlags_EnterReturnsTrue)) {
|
||||||
category.editing = false;
|
category.editing = false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user