Merge pull request #1 from ionspin/sample-continued
Migrate to own repo
This commit is contained in:
commit
548305644c
@ -54,7 +54,6 @@ macPublishToSnapshot:
|
||||
script:
|
||||
- ./macBuild.sh
|
||||
- ./macBuildAndPublishSnapshot-bindings.sh
|
||||
- ./macBuildAndPublishSnapshot-delegated.sh
|
||||
only:
|
||||
- master
|
||||
tags:
|
||||
@ -69,7 +68,6 @@ buildWindows:
|
||||
script:
|
||||
- $env:CHERE_INVOKING = 'yes'
|
||||
- C:\msys64\usr\bin\bash -lc "./windowsBuild-delegated.sh"
|
||||
- C:\msys64\usr\bin\bash -lc "./windowsBuild-pure.sh"
|
||||
tags:
|
||||
- windowsX64
|
||||
|
||||
@ -78,7 +76,6 @@ windowsPublishToSnapshot:
|
||||
script:
|
||||
- $env:CHERE_INVOKING = 'yes'
|
||||
- C:\msys64\usr\bin\bash -lc "./windowsBuildAndPublish-delegated.sh"
|
||||
- C:\msys64\usr\bin\bash -lc "./windowsBuildAndPublish-pure.sh"
|
||||
only:
|
||||
- master
|
||||
tags:
|
||||
|
197
.travis.yml
197
.travis.yml
@ -1,197 +0,0 @@
|
||||
matrix:
|
||||
include:
|
||||
- os: linux
|
||||
name: linux
|
||||
language: java
|
||||
jdk: openjdk12
|
||||
|
||||
env:
|
||||
KBUILD=linux
|
||||
JAVA_OPTS=-Xmx2g
|
||||
#skip ./gradlew assemble that is normally invoked in installation step
|
||||
install:
|
||||
- sudo apt-get update
|
||||
- sudo apt-get -y install automake
|
||||
script:
|
||||
- 'if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then bash ./linuxBuild.sh; fi'
|
||||
- 'if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then bash ./linuxBuildAndPublish.sh; fi'
|
||||
# OSX macos
|
||||
- os: osx
|
||||
name: osx-mac
|
||||
osx_image: xcode11.4
|
||||
language: java
|
||||
jdk: openjdk12
|
||||
install: true
|
||||
env:
|
||||
KBUILD=linux
|
||||
JAVA_OPTS=-Xmx2g
|
||||
script:
|
||||
- 'if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then bash ./macBuild-mac.sh; fi'
|
||||
- 'if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then bash ./macBuildAndPublish-mac.sh; fi'
|
||||
# OSX ios
|
||||
- os: osx
|
||||
name: osx-ios
|
||||
osx_image: xcode11.4
|
||||
language: java
|
||||
jdk: openjdk12
|
||||
install: true
|
||||
env:
|
||||
KBUILD=linux
|
||||
JAVA_OPTS=-Xmx2g
|
||||
script:
|
||||
- 'if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then bash ./macBuild-ios.sh; fi'
|
||||
- 'if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then bash ./macBuildAndPublish-ios.sh; fi'
|
||||
# OSX watchos
|
||||
- os: osx
|
||||
name: osx-watchos
|
||||
osx_image: xcode11.4
|
||||
language: java
|
||||
jdk: openjdk12
|
||||
install: true
|
||||
env:
|
||||
KBUILD=linux
|
||||
JAVA_OPTS=-Xmx2g
|
||||
script:
|
||||
- 'if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then bash ./macBuild-watchos.sh; fi'
|
||||
- 'if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then bash ./macBuildAndPublish-watchos.sh; fi'
|
||||
# OSX tvos
|
||||
- os: osx
|
||||
name: osx-tvos
|
||||
osx_image: xcode11.4
|
||||
language: java
|
||||
jdk: openjdk12
|
||||
install: true
|
||||
env:
|
||||
KBUILD=linux
|
||||
JAVA_OPTS=-Xmx2g
|
||||
script:
|
||||
- 'if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then bash ./macBuild-tvos.sh; fi'
|
||||
- 'if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then bash ./macBuildAndPublish-tvos.sh; fi'
|
||||
|
||||
# OSX macos PURE
|
||||
- os: osx
|
||||
name: osx-mac-pure
|
||||
osx_image: xcode11.4
|
||||
language: java
|
||||
jdk: openjdk12
|
||||
install: true
|
||||
env:
|
||||
KBUILD=linux
|
||||
JAVA_OPTS=-Xmx2g
|
||||
script:
|
||||
- 'if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then bash ./macBuild-pure-mac.sh; fi'
|
||||
- 'if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then bash ./macBuildAndPublish-pure-mac.sh; fi'
|
||||
# OSX ios PURE
|
||||
- os: osx
|
||||
name: osx-ios-pure
|
||||
osx_image: xcode11.4
|
||||
language: java
|
||||
jdk: openjdk12
|
||||
install: true
|
||||
env:
|
||||
KBUILD=linux
|
||||
JAVA_OPTS=-Xmx2g
|
||||
script:
|
||||
- 'if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then bash ./macBuild-pure-ios.sh; fi'
|
||||
- 'if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then bash ./macBuildAndPublish-pure-ios.sh; fi'
|
||||
# OSX watchos PURE
|
||||
- os: osx
|
||||
name: osx-watchos-pure
|
||||
osx_image: xcode11.4
|
||||
language: java
|
||||
jdk: openjdk12
|
||||
install: true
|
||||
env:
|
||||
KBUILD=linux
|
||||
JAVA_OPTS=-Xmx2g
|
||||
script:
|
||||
- 'if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then bash ./macBuild-pure-watchos.sh; fi'
|
||||
- 'if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then bash ./macBuildAndPublish-pure-watchos.sh; fi'
|
||||
# OSX tvos PURE
|
||||
- os: osx
|
||||
name: osx-tvos-pure
|
||||
osx_image: xcode11.4
|
||||
language: java
|
||||
jdk: openjdk12
|
||||
install: true
|
||||
env:
|
||||
KBUILD=linux
|
||||
JAVA_OPTS=-Xmx2g
|
||||
script:
|
||||
- 'if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then bash ./macBuild-pure-tvos.sh; fi'
|
||||
- 'if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then bash ./macBuildAndPublish-pure-tvos.sh; fi'
|
||||
|
||||
- os: windows
|
||||
name: windows-pure
|
||||
language: shell
|
||||
jdk: openjdk12
|
||||
env:
|
||||
- GRAVIS="https://raw.githubusercontent.com/DanySK/Gravis-CI/master/"
|
||||
- JAVA_OPTS=-Xmx2g
|
||||
- JDK="adopt-openj9@1.11"
|
||||
before_install:
|
||||
- curl "${GRAVIS}.install-jdk-travis.sh" --output ~/.install-jdk-travis.sh
|
||||
- source ~/.install-jdk-travis.sh
|
||||
install: true
|
||||
script:
|
||||
- 'if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then $shell ./windowsBuild-pure.sh; fi'
|
||||
- 'if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then ./windowsBuildAndPublish-pure.sh; fi'
|
||||
- os: windows
|
||||
name: windows-delegated
|
||||
language: shell
|
||||
jdk: openjdk12
|
||||
env:
|
||||
- GRAVIS="https://raw.githubusercontent.com/DanySK/Gravis-CI/master/"
|
||||
- JAVA_OPTS=-Xmx2g
|
||||
- JDK="adopt-openj9@1.11"
|
||||
before_install:
|
||||
- curl "${GRAVIS}.install-jdk-travis.sh" --output ~/.install-jdk-travis.sh
|
||||
- source ~/.install-jdk-travis.sh
|
||||
- |-
|
||||
case $TRAVIS_OS_NAME in
|
||||
windows)
|
||||
[[ ! -f C:/tools/msys64/msys2_shell.cmd ]] && rm -rf C:/tools/msys64
|
||||
choco uninstall -y mingw
|
||||
choco upgrade --no-progress -y msys2 bazel
|
||||
export msys2='cmd //C RefreshEnv.cmd '
|
||||
export msys2+='& set MSYS=winsymlinks:nativestrict '
|
||||
export msys2+='& C:\\tools\\msys64\\msys2_shell.cmd -defterm -no-start'
|
||||
export shell="$msys2 -mingw64 -full-path -here -c \$\* --"
|
||||
export msys2+=" -msys2 -c \$\* --"
|
||||
$msys2 pacman --sync --noconfirm --needed \
|
||||
autoconf \
|
||||
automake \
|
||||
mingw-w64-x86_64-libtool \
|
||||
mingw-w64-x86_64-toolchain \
|
||||
perl \
|
||||
unzip
|
||||
taskkill //IM gpg-agent.exe //F
|
||||
export CPPFLAGS=-D__USE_MINGW_ANSI_STDIO=1
|
||||
export PATH=/C/tools/msys64/mingw64/bin:$PATH
|
||||
export GNU_MAKE=mingw32-make
|
||||
export MAKE=mingw32-make
|
||||
export AR=gcc-ar
|
||||
export RANLIB=gcc-ranlib
|
||||
export COVERITY_SCAN_BRANCH_PATTERN=disable_coverity_scan
|
||||
;;
|
||||
esac
|
||||
- export GIT=git
|
||||
- g++ --version
|
||||
- $GNU_MAKE --version
|
||||
- $GIT --version
|
||||
install: true
|
||||
before_cache:
|
||||
- $msys2 pacman --sync --clean --noconfirm
|
||||
script:
|
||||
- 'if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then $shell ./windowsBuild-delegated.sh; fi'
|
||||
- 'if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then $shell ./windowsBuildAndPublish-delegated.sh; fi'
|
||||
cache:
|
||||
directories:
|
||||
- $HOME/.m2/
|
||||
- $HOME/.gradle
|
||||
- $HOME/.konan
|
||||
- $HOME/AppData/Local/Temp/chocolatey
|
||||
- /C/tools/msys64
|
||||
branches:
|
||||
only:
|
||||
- master
|
@ -1,5 +1,5 @@
|
||||
|
||||
[](https://gitlab.com/ionspin-github-ci/kotlin-multiplatform-crypto-ci/-/commits/master)
|
||||
[](https://gitlab.com/ionspin-github-ci/kotlin-multiplatform-libsodium/-/commits/master)
|
||||
|
||||

|
||||
|
||||
@ -108,6 +108,7 @@ And here is the usage sample
|
||||
|
||||
The functions are mapped from libsodium to kotiln objects, so `crypto_secretstream_xchacha20poly1305_init_push` becomes
|
||||
`SecretStream.xChaCha20Poly1305InitPush`
|
||||

|
||||
|
||||
At the moment you should refer to original libsodium documentation for instructions on how to use the library
|
||||
|
||||
@ -139,6 +140,7 @@ Currently supported native platforms:
|
||||
- Android testing
|
||||
- Fix browser testing, both locally and in CI/CD
|
||||
- LobsodiumUtil `unpad` and `fromBase64` native implementations use a nasty hack to support shared native sourceset. The hack either needs to be removed and replaced with another solution or additional safeguards need to be added.
|
||||
- Complete exposing libsodium constants
|
||||
|
||||
|
||||
|
||||
|
@ -15,13 +15,13 @@
|
||||
*/
|
||||
|
||||
object Versions {
|
||||
val kotlinCoroutines = "1.3.9"
|
||||
val kotlin = "1.4.10"
|
||||
val kotlinSerialization = "1.0.0"
|
||||
val kotlinCoroutines = "1.4.1"
|
||||
val kotlin = "1.4.20"
|
||||
val kotlinSerialization = "1.0.1"
|
||||
val kotlinSerializationPlugin = "1.4.10"
|
||||
val atomicfu = "0.14.3-M2-2-SNAPSHOT" //NOTE: my linux arm32 and arm64 build
|
||||
val nodePlugin = "1.3.0"
|
||||
val dokkaPlugin = "1.4.0-rc"
|
||||
val dokkaPlugin = "1.4.0"
|
||||
val taskTreePlugin = "1.5"
|
||||
val kotlinBigNumVersion = "0.2.2"
|
||||
val lazySodium = "4.3.1-SNAPSHOT"
|
||||
|
91
doc/res/libsodium_api_mapping.svg
Normal file
91
doc/res/libsodium_api_mapping.svg
Normal file
@ -0,0 +1,91 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="297mm"
|
||||
height="210mm"
|
||||
viewBox="0 0 297 210"
|
||||
version="1.1"
|
||||
id="svg8"
|
||||
inkscape:version="1.0.1 (3bc2e813f5, 2020-09-07)"
|
||||
sodipodi:docname="libsodium_api_mapping.svg">
|
||||
<defs
|
||||
id="defs2" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="0.7"
|
||||
inkscape:cx="554.56493"
|
||||
inkscape:cy="538.66625"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="layer1"
|
||||
inkscape:document-rotation="0"
|
||||
showgrid="false"
|
||||
inkscape:window-width="1276"
|
||||
inkscape:window-height="1396"
|
||||
inkscape:window-x="3840"
|
||||
inkscape:window-y="20"
|
||||
inkscape:window-maximized="0" />
|
||||
<metadata
|
||||
id="metadata5">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:10.5833px;line-height:1.25;font-family:sans-serif;word-spacing:0px;stroke-width:0.264583"
|
||||
x="9.5235968"
|
||||
y="64.991554"
|
||||
id="text12"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan10"
|
||||
x="9.5235968"
|
||||
y="64.991554"
|
||||
style="stroke-width:0.264583"><tspan
|
||||
style="fill:#ff0000"
|
||||
id="tspan18">crypto</tspan>_<tspan
|
||||
style="fill:#008000"
|
||||
id="tspan20">secretstream</tspan>_<tspan
|
||||
style="fill:#0000ff"
|
||||
id="tspan22">xchacha20poly1305</tspan>_<tspan
|
||||
style="fill:#0000ff"
|
||||
id="tspan28">init</tspan>_<tspan
|
||||
style="fill:#0000ff"
|
||||
id="tspan30">push</tspan></tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:10.5833px;line-height:1.25;font-family:sans-serif;word-spacing:0px;stroke-width:0.264583"
|
||||
x="47.202728"
|
||||
y="94.062126"
|
||||
id="text16"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan14"
|
||||
x="47.202728"
|
||||
y="94.062126"
|
||||
style="stroke-width:0.264583"><tspan
|
||||
style="fill:#008000"
|
||||
id="tspan34">SecretStream</tspan>.<tspan
|
||||
style="fill:#0000ff"
|
||||
id="tspan32">xChaCha20Poly1305InitPush</tspan></tspan></text>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.7 KiB |
@ -15,10 +15,8 @@ fi
|
||||
./makeLinuxArm64.sh
|
||||
#now we can do the delegated build
|
||||
cd ..
|
||||
./gradlew multiplatform-crypto-delegated:build
|
||||
|
||||
#build libsodium bindings
|
||||
./gradlew multiplatform-crypto-libsodium-bindings:build
|
||||
#and finally pure build
|
||||
./gradlew multiplatform-crypto:build
|
||||
set +e
|
||||
|
||||
|
@ -15,11 +15,9 @@ fi
|
||||
./makeLinuxArm64.sh
|
||||
#now we can do the delegated build
|
||||
cd ..
|
||||
./gradlew multiplatform-crypto-delegated:build
|
||||
#build libsodium bindings
|
||||
./gradlew multiplatform-crypto-libsodium-bindings:build
|
||||
#and finally pure build
|
||||
./gradlew multiplatform-crypto:build
|
||||
|
||||
./gradlew publishJvmPublicationToSnapshotRepository publishJsPublicationToSnapshotRepository \
|
||||
publishKotlinMultiplatformPublicationToSnapshotRepository publishLinuxX64PublicationToSnapshotRepository \
|
||||
publishLinuxArm64PublicationToSnapshotRepository publishMetadataPublicationToSnapshotRepository
|
||||
|
@ -8,10 +8,6 @@ cd sodiumWrapper
|
||||
./makeIos.sh
|
||||
#now we can do the delegated build of ios and macos libraries
|
||||
cd ..
|
||||
./gradlew multiplatform-crypto-delegated:iosArm32MainKlibrary multiplatform-crypto-delegated:iosArm32TestKlibrary \
|
||||
multiplatform-crypto-delegated:iosArm64MainKlibrary multiplatform-crypto-delegated:iosArm64TestKlibrary \
|
||||
multiplatform-crypto-delegated:iosX64MainKlibrary multiplatform-crypto-delegated:iosX64TestKlibrary
|
||||
./gradlew multiplatform-crypto-delegated:iosX64Test
|
||||
|
||||
./gradlew multiplatform-crypto-libsodium-bindings:iosArm32MainKlibrary multiplatform-crypto-libsodium-bindings:iosArm32TestKlibrary \
|
||||
multiplatform-crypto-libsodium-bindings:iosArm64MainKlibrary multiplatform-crypto-libsodium-bindings:iosArm64TestKlibrary \
|
||||
|
@ -8,9 +8,6 @@ cd sodiumWrapper
|
||||
./makeIos.sh
|
||||
#now we can do the delegated build of ios and macos libraries
|
||||
cd ..
|
||||
./gradlew multiplatform-crypto-delegated:macosX64MainKlibrary multiplatform-crypto-delegated:macosX64TestKlibrary
|
||||
./gradlew multiplatform-crypto-delegated:macosX64Test
|
||||
|
||||
./gradlew multiplatform-crypto-libsodium-bindings:macosX64MainKlibrary multiplatform-crypto-libsodium-bindings:macosX64TestKlibrary
|
||||
./gradlew multiplatform-crypto-libsodium-bindings:macosX64Test
|
||||
set +e
|
||||
|
@ -1,9 +0,0 @@
|
||||
set -e
|
||||
#!/bin/sh
|
||||
./gradlew multiplatform-crypto-api:build
|
||||
./gradlew multiplatform-crypto:iosArm32MainKlibrary multiplatform-crypto:iosArm32TestKlibrary \
|
||||
multiplatform-crypto:iosArm64MainKlibrary multiplatform-crypto:iosArm64TestKlibrary \
|
||||
multiplatform-crypto:iosX64MainKlibrary multiplatform-crypto:iosX64TestKlibrary
|
||||
./gradlew multiplatform-crypto:iosX64Test
|
||||
|
||||
set +e
|
@ -1,7 +0,0 @@
|
||||
set -e
|
||||
#!/bin/sh
|
||||
./gradlew multiplatform-crypto-api:build
|
||||
./gradlew multiplatform-crypto:macosX64MainKlibrary multiplatform-crypto:macosX64TestKlibrary
|
||||
./gradlew multiplatform-crypto:macosX64Test
|
||||
|
||||
set +e
|
@ -1,7 +0,0 @@
|
||||
set -e
|
||||
#!/bin/sh
|
||||
./gradlew multiplatform-crypto-api:build
|
||||
./gradlew multiplatform-crypto:tvosArm64MainKlibrary multiplatform-crypto:tvosArm64TestKlibrary \
|
||||
multiplatform-crypto:tvosX64MainKlibrary multiplatform-crypto:tvosX64TestKlibrary
|
||||
./gradlew multiplatform-crypto:tvosX64Test
|
||||
set +e
|
@ -1,8 +0,0 @@
|
||||
set -e
|
||||
#!/bin/sh
|
||||
./gradlew multiplatform-crypto-api:build
|
||||
./gradlew multiplatform-crypto:watchosArm32MainKlibrary multiplatform-crypto:watchosArm32TestKlibrary \
|
||||
multiplatform-crypto:watchosArm64MainKlibrary multiplatform-crypto:watchosArm64TestKlibrary \
|
||||
multiplatform-crypto:watchosX86MainKlibrary multiplatform-crypto:watchosX86TestKlibrary
|
||||
./gradlew multiplatform-crypto:watchosX86Test
|
||||
set +e
|
@ -7,9 +7,6 @@ cd sodiumWrapper
|
||||
./makeTvos.sh
|
||||
#now we can do the delegated build of ios and macos libraries
|
||||
cd ..
|
||||
./gradlew multiplatform-crypto-delegated:tvosArm64MainKlibrary multiplatform-crypto-delegated:tvosArm64TestKlibrary \
|
||||
multiplatform-crypto-delegated:tvosX64MainKlibrary multiplatform-crypto-delegated:tvosX64TestKlibrary
|
||||
./gradlew multiplatform-crypto-delegated:tvosX64Test
|
||||
|
||||
./gradlew multiplatform-crypto-libsodium-bindings:tvosArm64MainKlibrary multiplatform-crypto-libsodium-bindings:tvosArm64TestKlibrary \
|
||||
multiplatform-crypto-libsodium-bindings:tvosX64MainKlibrary multiplatform-crypto-libsodium-bindings:tvosX64TestKlibrary
|
||||
|
@ -7,10 +7,6 @@ cd sodiumWrapper
|
||||
./makeWatchos.sh
|
||||
#now we can do the delegated build of ios and macos libraries
|
||||
cd ..
|
||||
./gradlew multiplatform-crypto-delegated:watchosArm32MainKlibrary multiplatform-crypto-delegated:watchosArm32TestKlibrary \
|
||||
multiplatform-crypto-delegated:watchosArm64MainKlibrary multiplatform-crypto-delegated:watchosArm64TestKlibrary \
|
||||
multiplatform-crypto-delegated:watchosX86MainKlibrary multiplatform-crypto-delegated:watchosX86TestKlibrary
|
||||
./gradlew multiplatform-crypto-delegated:watchosX86Test
|
||||
|
||||
./gradlew multiplatform-crypto-libsodium-bindings:watchosArm32MainKlibrary multiplatform-crypto-libsodium-bindings:watchosArm32TestKlibrary \
|
||||
multiplatform-crypto-libsodium-bindings:watchosArm64MainKlibrary multiplatform-crypto-libsodium-bindings:watchosArm64TestKlibrary \
|
||||
|
@ -8,9 +8,6 @@ cd sodiumWrapper
|
||||
./makeIosWatchosTvos.sh
|
||||
#now we can do the delegated build
|
||||
cd ..
|
||||
./gradlew multiplatform-crypto-delegated:build
|
||||
#pure build
|
||||
./gradlew multiplatform-crypto:build
|
||||
#libsodium bindings
|
||||
./gradlew multiplatform-crypto-libsodium-bindings:build
|
||||
set +e
|
||||
|
@ -8,9 +8,6 @@ cd sodiumWrapper
|
||||
./makeIos.sh
|
||||
#now we can do the delegated build of ios and macos libraries
|
||||
cd ..
|
||||
./gradlew multiplatform-crypto-delegated:publishIosArm32PublicationToSnapshotRepository \
|
||||
multiplatform-crypto-delegated:publishIosArm64PublicationToSnapshotRepository \
|
||||
multiplatform-crypto-delegated:publishIosX64PublicationToSnapshotRepository
|
||||
|
||||
./gradlew multiplatform-crypto-libsodium-bindings:publishIosArm32PublicationToSnapshotRepository \
|
||||
multiplatform-crypto-libsodium-bindings:publishIosArm64PublicationToSnapshotRepository \
|
||||
|
@ -7,7 +7,6 @@ cd sodiumWrapper
|
||||
./makeMacosX86-64.sh
|
||||
#now we can do the delegated build of ios and macos libraries
|
||||
cd ..
|
||||
./gradlew multiplatform-crypto-delegated:publishMacosX64PublicationToSnapshotRepository
|
||||
|
||||
./gradlew multiplatform-crypto-libsodium-bindings:publishMacosX64PublicationToSnapshotRepository
|
||||
set +e
|
||||
|
@ -1,8 +0,0 @@
|
||||
set -e
|
||||
#!/bin/sh
|
||||
#this will hopefully download all konan dependancies that we use in the build scripts
|
||||
./gradlew multiplatform-crypto-api:build
|
||||
./gradlew multiplatform-crypto:publishIosArm32PublicationToSnapshotRepository \
|
||||
multiplatform-crypto:publishIosArm64PublicationToSnapshotRepository \
|
||||
multiplatform-crypto:publishIosX64PublicationToSnapshotRepository
|
||||
set +e
|
@ -1,6 +0,0 @@
|
||||
set -e
|
||||
#!/bin/sh
|
||||
#this will hopefully download all konan dependancies that we use in the build scripts
|
||||
./gradlew multiplatform-crypto-api:build
|
||||
./gradlew multiplatform-crypto:publishMacosX64PublicationToSnapshotRepository
|
||||
set +e
|
@ -1,8 +0,0 @@
|
||||
set -e
|
||||
#!/bin/sh
|
||||
#this will hopefully download all konan dependancies that we use in the build scripts
|
||||
./gradlew multiplatform-crypto-api:build
|
||||
./gradlew multiplatform-crypto:publishTvosArm64PublicationToSnapshotRepository \
|
||||
multiplatform-crypto:publishTvosX64PublicationToSnapshotRepository
|
||||
|
||||
set +e
|
@ -1,8 +0,0 @@
|
||||
set -e
|
||||
#!/bin/sh
|
||||
#this will hopefully download all konan dependancies that we use in the build scripts
|
||||
./gradlew multiplatform-crypto-api:build
|
||||
./gradlew multiplatform-crypto:publishWatchosArm32PublicationToSnapshotRepository \
|
||||
multiplatform-crypto:publishWatchosArm64PublicationToSnapshotRepository \
|
||||
multiplatform-crypto:publishWatchosX86PublicationToSnapshotRepository
|
||||
set +e
|
@ -1,8 +0,0 @@
|
||||
set -e
|
||||
#!/bin/sh
|
||||
#this will hopefully download all konan dependancies that we use in the build scripts
|
||||
./gradlew multiplatform-crypto-api:build
|
||||
./gradlew multiplatform-crypto:publishTvosArm64PublicationToSnapshotRepository \
|
||||
multiplatform-crypto:publishTvosX64PublicationToSnapshotRepository
|
||||
|
||||
set +e
|
@ -7,9 +7,6 @@ cd sodiumWrapper
|
||||
./makeWatchos.sh
|
||||
#now we can do the delegated build of ios and macos libraries
|
||||
cd ..
|
||||
./gradlew multiplatform-crypto-delegated:publishWatchosArm32PublicationToSnapshotRepository \
|
||||
multiplatform-crypto-delegated:publishWatchosArm64PublicationToSnapshotRepository \
|
||||
multiplatform-crypto-delegated:publishWatchosX86PublicationToSnapshotRepository
|
||||
|
||||
./gradlew multiplatform-crypto-libsodium-bindings:publishWatchosArm32PublicationToSnapshotRepository \
|
||||
multiplatform-crypto-libsodium-bindings:publishWatchosArm64PublicationToSnapshotRepository \
|
||||
|
@ -1,15 +0,0 @@
|
||||
set -e
|
||||
#!/bin/sh
|
||||
./gradlew multiplatform-crypto-delegated:publishMacosX64PublicationToSnapshotRepository
|
||||
|
||||
./gradlew multiplatform-crypto-delegated:publishIosArm32PublicationToSnapshotRepository \
|
||||
multiplatform-crypto-delegated:publishIosArm64PublicationToSnapshotRepository \
|
||||
multiplatform-crypto-delegated:publishIosX64PublicationToSnapshotRepository
|
||||
|
||||
./gradlew multiplatform-crypto-delegated:publishWatchosArm32PublicationToSnapshotRepository \
|
||||
multiplatform-crypto-delegated:publishWatchosArm64PublicationToSnapshotRepository \
|
||||
multiplatform-crypto-delegated:publishWatchosX86PublicationToSnapshotRepository
|
||||
|
||||
./gradlew multiplatform-crypto-delegated:publishTvosArm64PublicationToSnapshotRepository \
|
||||
multiplatform-crypto-delegated:publishTvosX64PublicationToSnapshotRepository
|
||||
set +e
|
@ -19,6 +19,7 @@
|
||||
|
||||
import org.jetbrains.kotlin.gradle.targets.js.testing.KotlinJsTest
|
||||
import org.jetbrains.kotlin.gradle.targets.native.tasks.KotlinNativeTest
|
||||
import org.jetbrains.dokka.Platform
|
||||
|
||||
plugins {
|
||||
kotlin(PluginsDeps.multiplatform)
|
||||
@ -275,9 +276,9 @@ tasks {
|
||||
dokkaJavadoc {
|
||||
println("Dokka !")
|
||||
dokkaSourceSets {
|
||||
create("commonMain") {
|
||||
displayName = "common"
|
||||
platform = "common"
|
||||
named("commonMain") {
|
||||
displayName.set("common")
|
||||
platform.set(Platform.common)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,697 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019 Ugljesa Jovanovic
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
@file:Suppress("UnstableApiUsage")
|
||||
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
|
||||
import org.jetbrains.kotlin.gradle.targets.js.testing.KotlinJsTest
|
||||
import org.jetbrains.kotlin.gradle.targets.native.tasks.KotlinNativeTest
|
||||
|
||||
plugins {
|
||||
kotlin(PluginsDeps.multiplatform)
|
||||
id(PluginsDeps.mavenPublish)
|
||||
id(PluginsDeps.signing)
|
||||
id(PluginsDeps.node) version Versions.nodePlugin
|
||||
id(PluginsDeps.dokka)
|
||||
id(PluginsDeps.taskTree) version Versions.taskTreePlugin
|
||||
}
|
||||
|
||||
val sonatypeStaging = "https://oss.sonatype.org/service/local/staging/deploy/maven2/"
|
||||
val sonatypeSnapshots = "https://oss.sonatype.org/content/repositories/snapshots/"
|
||||
|
||||
val sonatypePassword: String? by project
|
||||
|
||||
val sonatypeUsername: String? by project
|
||||
|
||||
val sonatypePasswordEnv: String? = System.getenv()["SONATYPE_PASSWORD"]
|
||||
val sonatypeUsernameEnv: String? = System.getenv()["SONATYPE_USERNAME"]
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
jcenter()
|
||||
|
||||
}
|
||||
group = ReleaseInfo.group
|
||||
version = ReleaseInfo.version
|
||||
|
||||
val ideaActive = isInIdea()
|
||||
println("Idea active: $ideaActive")
|
||||
|
||||
|
||||
|
||||
kotlin {
|
||||
val hostOsName = getHostOsName()
|
||||
runningOnLinuxx86_64 {
|
||||
println("Configuring Linux X86-64 targets")
|
||||
jvm()
|
||||
js {
|
||||
browser {
|
||||
testTask {
|
||||
isRunningInGitlabCi {
|
||||
enabled = false //Until I sort out testing on travis
|
||||
}
|
||||
useKarma {
|
||||
useChrome()
|
||||
}
|
||||
}
|
||||
}
|
||||
nodejs {
|
||||
testTask {
|
||||
useMocha() {
|
||||
timeout = "10s"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
linuxX64() {
|
||||
compilations.getByName("main") {
|
||||
val libsodiumCinterop by cinterops.creating {
|
||||
defFile(project.file("src/nativeInterop/cinterop/libsodium.def"))
|
||||
compilerOpts.add("-I${project.rootDir}/sodiumWrapper/static-linux-x86-64/include/")
|
||||
}
|
||||
kotlinOptions.freeCompilerArgs = listOf(
|
||||
"-include-binary", "${project.rootDir}/sodiumWrapper/static-linux-x86-64/lib/libsodium.a"
|
||||
)
|
||||
}
|
||||
binaries {
|
||||
staticLib {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
linuxArm64() {
|
||||
binaries {
|
||||
staticLib {
|
||||
}
|
||||
}
|
||||
}
|
||||
// Linux 32 is using target-sysroot-2-raspberrypi which is missing getrandom and explicit_bzero in stdlib
|
||||
// so konanc can't build klib because getrandom missing will cause sodium_misuse()
|
||||
// ld.lld: error: undefined symbol: explicit_bzero
|
||||
// >>> referenced by utils.c
|
||||
// >>> libsodium_la-utils.o:(sodium_memzero) in archive /tmp/included11051337748775083797/libsodium.a
|
||||
//
|
||||
// ld.lld: error: undefined symbol: getrandom
|
||||
// >>> referenced by randombytes_sysrandom.c
|
||||
// >>> libsodium_la-randombytes_sysrandom.o:(_randombytes_linux_getrandom) in archive /tmp/included11051337748775083797/libsodium.a
|
||||
|
||||
// linuxArm32Hfp() {
|
||||
// binaries {
|
||||
// staticLib {
|
||||
// }
|
||||
// }
|
||||
// compilations.getByName("main") {
|
||||
// val libsodiumCinterop by cinterops.creating {
|
||||
// defFile(project.file("src/nativeInterop/cinterop/libsodium.def"))
|
||||
// compilerOpts.add("-I${project.rootDir}/sodiumWrapper/static-arm32/include/")
|
||||
// }
|
||||
// kotlinOptions.freeCompilerArgs = listOf(
|
||||
// "-include-binary", "${project.rootDir}/sodiumWrapper/static-arm32/lib/libsodium.a"
|
||||
// )
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
runningOnLinuxArm64 {
|
||||
println("Configuring Linux Arm 64 targets")
|
||||
|
||||
}
|
||||
|
||||
runningOnLinuxArm32 {
|
||||
println("Configuring Linux Arm 32 targets")
|
||||
|
||||
}
|
||||
|
||||
runningOnMacos {
|
||||
println("Configuring macos targets")
|
||||
iosX64() {
|
||||
binaries {
|
||||
framework {
|
||||
optimized = true
|
||||
}
|
||||
}
|
||||
}
|
||||
iosArm64() {
|
||||
binaries {
|
||||
framework {
|
||||
optimized = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
iosArm32() {
|
||||
binaries {
|
||||
framework {
|
||||
optimized = true
|
||||
}
|
||||
}
|
||||
}
|
||||
macosX64() {
|
||||
binaries {
|
||||
framework {
|
||||
optimized = true
|
||||
}
|
||||
}
|
||||
compilations.getByName("main") {
|
||||
val libsodiumCinterop by cinterops.creating {
|
||||
defFile(project.file("src/nativeInterop/cinterop/libsodium.def"))
|
||||
compilerOpts.add("-I${project.rootDir}/sodiumWrapper/static-macos-x86-64/include")
|
||||
}
|
||||
kotlinOptions.freeCompilerArgs = listOf(
|
||||
"-include-binary", "${project.rootDir}/sodiumWrapper/static-macos-x86-64/lib/libsodium.a"
|
||||
)
|
||||
}
|
||||
}
|
||||
tvosX64() {
|
||||
binaries {
|
||||
framework {
|
||||
optimized = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tvosArm64() {
|
||||
binaries {
|
||||
framework {
|
||||
optimized = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
watchosArm64() {
|
||||
binaries {
|
||||
framework {
|
||||
optimized = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
watchosArm32() {
|
||||
binaries {
|
||||
framework {
|
||||
optimized = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
watchosX86() {
|
||||
binaries {
|
||||
framework {
|
||||
optimized = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
runningOnWindows {
|
||||
println("Configuring Mingw targets")
|
||||
mingwX64() {
|
||||
binaries {
|
||||
staticLib {
|
||||
optimized = true
|
||||
}
|
||||
}
|
||||
compilations.getByName("main") {
|
||||
val libsodiumCinterop by cinterops.creating {
|
||||
defFile(project.file("src/nativeInterop/cinterop/libsodium.def"))
|
||||
compilerOpts.add("-I${project.rootDir}/sodiumWrapper/static-mingw-x86-64/include")
|
||||
}
|
||||
kotlinOptions.freeCompilerArgs = listOf(
|
||||
"-include-binary", "${project.rootDir}/sodiumWrapper/static-mingw-x86-64/lib/libsodium.a"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
println(targets.names)
|
||||
|
||||
sourceSets {
|
||||
val commonMain by getting {
|
||||
dependencies {
|
||||
implementation(kotlin(Deps.Common.stdLib))
|
||||
implementation(kotlin(Deps.Common.test))
|
||||
implementation(Deps.Common.kotlinBigNum)
|
||||
api(project(Deps.Common.apiProject))
|
||||
}
|
||||
}
|
||||
val commonTest by getting {
|
||||
dependencies {
|
||||
implementation(kotlin(Deps.Common.test))
|
||||
implementation(kotlin(Deps.Common.testAnnotation))
|
||||
}
|
||||
}
|
||||
|
||||
val nativeDependencies = independentDependencyBlock {
|
||||
}
|
||||
|
||||
val nativeMain by creating {
|
||||
dependsOn(commonMain)
|
||||
isRunningInIdea {
|
||||
kotlin.setSrcDirs(emptySet<String>())
|
||||
}
|
||||
dependencies {
|
||||
nativeDependencies(this)
|
||||
}
|
||||
}
|
||||
|
||||
val nativeTest by creating {
|
||||
dependsOn(commonTest)
|
||||
isRunningInIdea {
|
||||
kotlin.setSrcDirs(emptySet<String>())
|
||||
}
|
||||
dependencies {
|
||||
}
|
||||
}
|
||||
|
||||
//Set up shared source sets
|
||||
//linux, linuxArm32Hfp, linuxArm64
|
||||
val linux64Bit = setOf(
|
||||
"linuxX64"
|
||||
)
|
||||
val linuxArm64Bit = setOf(
|
||||
"linuxArm64"
|
||||
)
|
||||
val linux32Bit = setOf(
|
||||
"" // "linuxArm32Hfp"
|
||||
)
|
||||
|
||||
//iosArm32, iosArm64, iosX64, macosX64, metadata, tvosArm64, tvosX64, watchosArm32, watchosArm64, watchosX86
|
||||
val macos64Bit = setOf(
|
||||
"macosX64"
|
||||
)
|
||||
val iosArm = setOf(
|
||||
"iosArm64", "iosArm32"
|
||||
)
|
||||
val iosSimulator = setOf(
|
||||
"iosX64"
|
||||
)
|
||||
val mingw64Bit = setOf(
|
||||
"mingwX64"
|
||||
)
|
||||
|
||||
val tvosArm = setOf(
|
||||
"tvosArm64"
|
||||
)
|
||||
val tvosSimulator = setOf(
|
||||
"tvosX64"
|
||||
)
|
||||
|
||||
val watchosArm = setOf(
|
||||
"watchosArm32", "watchosArm64"
|
||||
)
|
||||
val watchosSimulator = setOf(
|
||||
"watchosX86"
|
||||
)
|
||||
|
||||
targets.withType<KotlinNativeTarget> {
|
||||
println("Target $name")
|
||||
|
||||
compilations.getByName("main") {
|
||||
if (linux64Bit.contains(this@withType.name)) {
|
||||
defaultSourceSet.dependsOn(nativeMain)
|
||||
}
|
||||
if (linuxArm64Bit.contains(this@withType.name)) {
|
||||
defaultSourceSet.dependsOn(
|
||||
createWorkaroundNativeMainSourceSet(
|
||||
this@withType.name,
|
||||
nativeDependencies
|
||||
)
|
||||
)
|
||||
|
||||
compilations.getByName("main") {
|
||||
val libsodiumCinterop by cinterops.creating {
|
||||
defFile(project.file("src/nativeInterop/cinterop/libsodium.def"))
|
||||
compilerOpts.add("-I${project.rootDir}/sodiumWrapper/static-arm64/include/")
|
||||
}
|
||||
kotlinOptions.freeCompilerArgs = listOf(
|
||||
"-include-binary", "${project.rootDir}/sodiumWrapper/static-arm64/lib/libsodium.a"
|
||||
)
|
||||
}
|
||||
}
|
||||
if (linux32Bit.contains(this@withType.name)) {
|
||||
defaultSourceSet.dependsOn(createWorkaroundNativeMainSourceSet(this@withType.name, nativeDependencies))
|
||||
}
|
||||
if (macos64Bit.contains(this@withType.name)) {
|
||||
defaultSourceSet.dependsOn(createWorkaroundNativeMainSourceSet(this@withType.name, nativeDependencies))
|
||||
}
|
||||
//All ioses share the same static library
|
||||
if (iosArm.contains(this@withType.name)) {
|
||||
defaultSourceSet.dependsOn(createWorkaroundNativeMainSourceSet(this@withType.name, nativeDependencies))
|
||||
println("Setting ios cinterop for $this")
|
||||
val libsodiumCinterop by cinterops.creating {
|
||||
defFile(project.file("src/nativeInterop/cinterop/libsodium.def"))
|
||||
compilerOpts.add("-I${project.rootDir}/sodiumWrapper/static-ios/include")
|
||||
}
|
||||
kotlinOptions.freeCompilerArgs = listOf(
|
||||
"-include-binary", "${project.rootDir}/sodiumWrapper/static-ios/lib/libsodium.a"
|
||||
)
|
||||
}
|
||||
|
||||
if (iosSimulator.contains(this@withType.name)) {
|
||||
defaultSourceSet.dependsOn(createWorkaroundNativeMainSourceSet(this@withType.name, nativeDependencies))
|
||||
println("Setting ios cinterop for $this")
|
||||
val libsodiumCinterop by cinterops.creating {
|
||||
defFile(project.file("src/nativeInterop/cinterop/libsodium.def"))
|
||||
compilerOpts.add("-I${project.rootDir}/sodiumWrapper/static-ios-simulators/include")
|
||||
}
|
||||
kotlinOptions.freeCompilerArgs = listOf(
|
||||
"-include-binary", "${project.rootDir}/sodiumWrapper/static-ios-simulators/lib/libsodium.a"
|
||||
)
|
||||
}
|
||||
|
||||
if (tvosArm.contains(this@withType.name)) {
|
||||
defaultSourceSet.dependsOn(createWorkaroundNativeMainSourceSet(this@withType.name, nativeDependencies))
|
||||
println("Setting ios cinterop for $this")
|
||||
val libsodiumCinterop by cinterops.creating {
|
||||
defFile(project.file("src/nativeInterop/cinterop/libsodium.def"))
|
||||
compilerOpts.add("-I${project.rootDir}/sodiumWrapper/static-tvos/include")
|
||||
}
|
||||
kotlinOptions.freeCompilerArgs = listOf(
|
||||
"-include-binary", "${project.rootDir}/sodiumWrapper/static-tvos/lib/libsodium.a"
|
||||
)
|
||||
}
|
||||
|
||||
if (tvosSimulator.contains(this@withType.name)) {
|
||||
defaultSourceSet.dependsOn(createWorkaroundNativeMainSourceSet(this@withType.name, nativeDependencies))
|
||||
println("Setting ios cinterop for $this")
|
||||
val libsodiumCinterop by cinterops.creating {
|
||||
defFile(project.file("src/nativeInterop/cinterop/libsodium.def"))
|
||||
compilerOpts.add("-I${project.rootDir}/sodiumWrapper/static-tvos-simulators/include")
|
||||
}
|
||||
kotlinOptions.freeCompilerArgs = listOf(
|
||||
"-include-binary", "${project.rootDir}/sodiumWrapper/static-tvos-simulators/lib/libsodium.a"
|
||||
)
|
||||
}
|
||||
|
||||
if (watchosArm.contains(this@withType.name)) {
|
||||
defaultSourceSet.dependsOn(createWorkaroundNativeMainSourceSet(this@withType.name, nativeDependencies))
|
||||
println("Setting ios cinterop for $this")
|
||||
val libsodiumCinterop by cinterops.creating {
|
||||
defFile(project.file("src/nativeInterop/cinterop/libsodium.def"))
|
||||
compilerOpts.add("-I${project.rootDir}/sodiumWrapper/static-watchos/include")
|
||||
}
|
||||
kotlinOptions.freeCompilerArgs = listOf(
|
||||
"-include-binary", "${project.rootDir}/sodiumWrapper/static-watchos/lib/libsodium.a"
|
||||
)
|
||||
}
|
||||
|
||||
if (watchosSimulator.contains(this@withType.name)) {
|
||||
defaultSourceSet.dependsOn(createWorkaroundNativeMainSourceSet(this@withType.name, nativeDependencies))
|
||||
println("Setting ios cinterop for $this")
|
||||
val libsodiumCinterop by cinterops.creating {
|
||||
defFile(project.file("src/nativeInterop/cinterop/libsodium.def"))
|
||||
compilerOpts.add("-I${project.rootDir}/sodiumWrapper/static-watchos-simulators/include")
|
||||
}
|
||||
kotlinOptions.freeCompilerArgs = listOf(
|
||||
"-include-binary", "${project.rootDir}/sodiumWrapper/static-watchos-simulators/lib/libsodium.a"
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
compilations.getByName("test") {
|
||||
println("Setting native test dep for $this@withType.name")
|
||||
defaultSourceSet.dependsOn(nativeTest)
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
runningOnLinuxx86_64 {
|
||||
println("Configuring Linux 64 Bit source sets")
|
||||
val jvmMain by getting {
|
||||
dependencies {
|
||||
implementation(kotlin(Deps.Jvm.stdLib))
|
||||
implementation(kotlin(Deps.Jvm.test))
|
||||
implementation(kotlin(Deps.Jvm.testJUnit))
|
||||
|
||||
//lazysodium
|
||||
implementation(Deps.Jvm.Delegated.lazysodium)
|
||||
implementation(Deps.Jvm.Delegated.jna)
|
||||
}
|
||||
}
|
||||
val jvmTest by getting {
|
||||
dependencies {
|
||||
implementation(kotlin(Deps.Jvm.test))
|
||||
implementation(kotlin(Deps.Jvm.testJUnit))
|
||||
implementation(kotlin(Deps.Jvm.reflection))
|
||||
}
|
||||
}
|
||||
val jsMain by getting {
|
||||
dependencies {
|
||||
implementation(kotlin(Deps.Js.stdLib))
|
||||
implementation(npm(Deps.Js.Npm.libsodiumWrappers.first, Deps.Js.Npm.libsodiumWrappers.second))
|
||||
}
|
||||
}
|
||||
val jsTest by getting {
|
||||
dependencies {
|
||||
implementation(kotlin(Deps.Js.test))
|
||||
implementation(npm(Deps.Js.Npm.libsodiumWrappers.first, Deps.Js.Npm.libsodiumWrappers.second))
|
||||
}
|
||||
}
|
||||
val linuxX64Main by getting {
|
||||
isRunningInIdea {
|
||||
kotlin.srcDir("src/nativeMain/kotlin")
|
||||
}
|
||||
}
|
||||
val linuxX64Test by getting {
|
||||
dependsOn(nativeTest)
|
||||
isRunningInIdea {
|
||||
kotlin.srcDir("src/nativeTest/kotlin")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
runningOnMacos {
|
||||
println("Configuring Macos source sets")
|
||||
val macosX64Main by getting {
|
||||
dependsOn(nativeMain)
|
||||
if (ideaActive) {
|
||||
kotlin.srcDir("src/nativeMain/kotlin")
|
||||
}
|
||||
|
||||
}
|
||||
val macosX64Test by getting {
|
||||
dependsOn(nativeTest)
|
||||
if (ideaActive) {
|
||||
kotlin.srcDir("src/nativeTest/kotlin")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
val tvosX64Main by getting {
|
||||
dependsOn(commonMain)
|
||||
}
|
||||
|
||||
val tvosArm64Main by getting {
|
||||
dependsOn(commonMain)
|
||||
}
|
||||
|
||||
val watchosX86Main by getting {
|
||||
dependsOn(commonMain)
|
||||
}
|
||||
|
||||
val watchosArm64Main by getting {
|
||||
dependsOn(commonMain)
|
||||
}
|
||||
|
||||
val watchosArm32Main by getting {
|
||||
dependsOn(commonMain)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (hostOsName == "windows") {
|
||||
val mingwX64Main by getting {
|
||||
dependsOn(nativeMain)
|
||||
if (ideaActive) {
|
||||
kotlin.srcDir("src/nativeMain/kotlin")
|
||||
}
|
||||
}
|
||||
|
||||
val mingwX64Test by getting {
|
||||
dependsOn(nativeTest)
|
||||
if (ideaActive) {
|
||||
kotlin.srcDir("src/nativeTest/kotlin")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
all {
|
||||
languageSettings.enableLanguageFeature("InlineClasses")
|
||||
languageSettings.useExperimentalAnnotation("kotlin.ExperimentalUnsignedTypes")
|
||||
languageSettings.useExperimentalAnnotation("kotlin.ExperimentalStdlibApi")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
tasks {
|
||||
|
||||
|
||||
create<Jar>("javadocJar") {
|
||||
dependsOn(dokkaJavadoc)
|
||||
archiveClassifier.set("javadoc")
|
||||
from(dokkaJavadoc.get().outputDirectory)
|
||||
}
|
||||
|
||||
dokkaJavadoc {
|
||||
println("Dokka !")
|
||||
dokkaSourceSets {
|
||||
create("commonMain") {
|
||||
displayName = "common"
|
||||
platform = "common"
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if (getHostOsName() == "linux" && getHostArchitecture() == "x86-64") {
|
||||
val jvmTest by getting(Test::class) {
|
||||
testLogging {
|
||||
events("PASSED", "FAILED", "SKIPPED")
|
||||
}
|
||||
}
|
||||
|
||||
val linuxX64Test by getting(KotlinNativeTest::class) {
|
||||
|
||||
testLogging {
|
||||
events("PASSED", "FAILED", "SKIPPED")
|
||||
showStandardStreams = true
|
||||
}
|
||||
}
|
||||
|
||||
val jsNodeTest by getting(KotlinJsTest::class) {
|
||||
testLogging {
|
||||
events("PASSED", "FAILED", "SKIPPED")
|
||||
// showStandardStreams = true
|
||||
}
|
||||
}
|
||||
|
||||
// val legacyjsNodeTest by getting(KotlinJsTest::class) {
|
||||
//
|
||||
// testLogging {
|
||||
// events("PASSED", "FAILED", "SKIPPED")
|
||||
// showStandardStreams = true
|
||||
// }
|
||||
// }
|
||||
|
||||
// val jsIrBrowserTest by getting(KotlinJsTest::class) {
|
||||
// testLogging {
|
||||
// events("PASSED", "FAILED", "SKIPPED")
|
||||
// showStandardStreams = true
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
if (getHostOsName() == "windows") {
|
||||
val mingwX64Test by getting(KotlinNativeTest::class) {
|
||||
|
||||
testLogging {
|
||||
events("PASSED", "FAILED", "SKIPPED")
|
||||
showStandardStreams = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
signing {
|
||||
isRequired = false
|
||||
sign(publishing.publications)
|
||||
}
|
||||
|
||||
publishing {
|
||||
publications.withType(MavenPublication::class) {
|
||||
artifact(tasks["javadocJar"])
|
||||
pom {
|
||||
name.set("Kotlin Multiplatform Crypto")
|
||||
description.set("Kotlin Multiplatform Crypto library")
|
||||
url.set("https://github.com/ionspin/kotlin-multiplatform-crypto")
|
||||
licenses {
|
||||
license {
|
||||
name.set("The Apache License, Version 2.0")
|
||||
url.set("http://www.apache.org/licenses/LICENSE-2.0.txt")
|
||||
}
|
||||
}
|
||||
developers {
|
||||
developer {
|
||||
id.set("ionspin")
|
||||
name.set("Ugljesa Jovanovic")
|
||||
email.set("opensource@ionspin.com")
|
||||
}
|
||||
}
|
||||
scm {
|
||||
url.set("https://github.com/ionspin/kotlin-multiplatform-crypto")
|
||||
connection.set("scm:git:git://git@github.com:ionspin/kotlin-multiplatform-crypto.git")
|
||||
developerConnection.set("scm:git:ssh://git@github.com:ionspin/kotlin-multiplatform-crypto.git")
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
repositories {
|
||||
maven {
|
||||
|
||||
url = uri(sonatypeStaging)
|
||||
credentials {
|
||||
username = sonatypeUsername ?: sonatypeUsernameEnv ?: ""
|
||||
password = sonatypePassword ?: sonatypePasswordEnv ?: ""
|
||||
}
|
||||
}
|
||||
|
||||
maven {
|
||||
name = "snapshot"
|
||||
url = uri(sonatypeSnapshots)
|
||||
credentials {
|
||||
username = sonatypeUsername ?: sonatypeUsernameEnv ?: ""
|
||||
password = sonatypePassword ?: sonatypePasswordEnv ?: ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//configurations.forEach {
|
||||
//
|
||||
// if (it.name == "linuxCompileKlibraries") {
|
||||
// println("Configuration name: ${it.name}")
|
||||
// it.attributes {
|
||||
// this.keySet().forEach { key ->
|
||||
// val attribute = getAttribute(key)
|
||||
// println(" |-- Attribute $key ${attribute}")
|
||||
// attribute(org.jetbrains.kotlin.gradle.plugin.ProjectLocalConfigurations.ATTRIBUTE, "publicZ")
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
|
Binary file not shown.
@ -1,26 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019 Ugljesa Jovanovic
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.ionspin.kotlin.crypto
|
||||
|
||||
/**
|
||||
* Created by Ugljesa Jovanovic
|
||||
* ugljesa.jovanovic@ionspin.com
|
||||
* on 20-Jul-2019
|
||||
*/
|
||||
object Config {
|
||||
const val DEBUG = false
|
||||
}
|
@ -1,216 +0,0 @@
|
||||
package com.ionspin.kotlin.crypto
|
||||
|
||||
import com.ionspin.kotlin.crypto.authenticated.XChaCha20Poly1305Delegated
|
||||
import com.ionspin.kotlin.crypto.hash.blake2b.Blake2bProperties
|
||||
import com.ionspin.kotlin.crypto.hash.blake2b.Blake2bDelegated
|
||||
import com.ionspin.kotlin.crypto.hash.blake2b.Blake2bDelegatedStateless
|
||||
import com.ionspin.kotlin.crypto.hash.blake2b.Blake2bMultipart
|
||||
import com.ionspin.kotlin.crypto.hash.sha.*
|
||||
import com.ionspin.kotlin.crypto.keyderivation.ArgonResult
|
||||
|
||||
/**
|
||||
* Created by Ugljesa Jovanovic
|
||||
* ugljesa.jovanovic@ionspin.com
|
||||
* on 24-May-2020
|
||||
*/
|
||||
|
||||
object CryptoInitializerDelegated : CryptoInitializer {
|
||||
override suspend fun initialize() {
|
||||
Initializer.initialize()
|
||||
}
|
||||
|
||||
fun initializeWithCallback(done: () -> Unit) {
|
||||
Initializer.initializeWithCallback(done)
|
||||
}
|
||||
|
||||
override fun isInitialized(): Boolean {
|
||||
return Initializer.isInitialized()
|
||||
}
|
||||
}
|
||||
|
||||
object CryptoPrimitives : PrimitivesApi {
|
||||
|
||||
object Blake2b {
|
||||
fun updateable(key: UByteArray? = null, hashLength: Int = Blake2bProperties.MAX_HASH_BYTES): com.ionspin.kotlin.crypto.hash.blake2b.Blake2bMultipart {
|
||||
checkInitialization()
|
||||
return Blake2bDelegated(key, hashLength)
|
||||
}
|
||||
|
||||
fun stateless(message: UByteArray, key: UByteArray = ubyteArrayOf(), hashLength: Int = Blake2bProperties.MAX_HASH_BYTES): UByteArray {
|
||||
checkInitialization()
|
||||
return Blake2bDelegatedStateless.digest(message, key, hashLength)
|
||||
}
|
||||
}
|
||||
|
||||
object Sha256 {
|
||||
fun updateable(): com.ionspin.kotlin.crypto.hash.sha.Sha256 {
|
||||
checkInitialization()
|
||||
return Sha256Delegated()
|
||||
}
|
||||
|
||||
fun stateless(message: UByteArray) : UByteArray{
|
||||
checkInitialization()
|
||||
return Sha256StatelessDelegated.digest(inputMessage = message)
|
||||
}
|
||||
}
|
||||
|
||||
object Sha512 {
|
||||
fun updateable(): Sha512Multipart {
|
||||
checkInitialization()
|
||||
return Sha512Delegated()
|
||||
}
|
||||
|
||||
fun stateless(message: UByteArray) : UByteArray {
|
||||
checkInitialization()
|
||||
return Sha512StatelessDelegated.digest(inputMessage = message)
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkInitialization() {
|
||||
if (!Initializer.isInitialized()) {
|
||||
throw RuntimeException("Platform library not initialized, check if you called Initializer.initialize()")
|
||||
}
|
||||
}
|
||||
|
||||
override fun hashBlake2bMultipart(key: UByteArray?, hashLength: Int): Blake2bMultipart {
|
||||
checkInitialization()
|
||||
return Blake2bDelegated(key, hashLength)
|
||||
}
|
||||
|
||||
override fun hashBlake2b(message: UByteArray, key: UByteArray, hashLength: Int): UByteArray {
|
||||
checkInitialization()
|
||||
return Blake2bDelegatedStateless.digest(message, key, hashLength)
|
||||
}
|
||||
|
||||
override fun hashSha256Multipart(): com.ionspin.kotlin.crypto.hash.sha.Sha256 {
|
||||
checkInitialization()
|
||||
return Sha256Delegated()
|
||||
}
|
||||
|
||||
override fun hashSha256(message: UByteArray): UByteArray {
|
||||
checkInitialization()
|
||||
return Sha256StatelessDelegated.digest(inputMessage = message)
|
||||
}
|
||||
|
||||
override fun hashSha512Multipart(): com.ionspin.kotlin.crypto.hash.sha.Sha512Multipart {
|
||||
checkInitialization()
|
||||
return Sha512Delegated()
|
||||
}
|
||||
|
||||
override fun hashSha512(message: UByteArray): UByteArray {
|
||||
checkInitialization()
|
||||
return Sha512StatelessDelegated.digest(inputMessage = message)
|
||||
}
|
||||
|
||||
override fun deriveKey(
|
||||
password: String,
|
||||
salt: String?,
|
||||
key: String,
|
||||
associatedData: String,
|
||||
parallelism: Int,
|
||||
tagLength: Int,
|
||||
memory: Int,
|
||||
numberOfIterations: Int
|
||||
): ArgonResult {
|
||||
// return Argon2Delegated.derive(
|
||||
// password,
|
||||
// salt,
|
||||
// key,
|
||||
// associatedData,
|
||||
// parallelism
|
||||
// tagLength,
|
||||
// memory,
|
||||
// numberOfIterations
|
||||
// )
|
||||
TODO()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
fun SymmetricKey.Companion.randomKey() : SymmetricKey {
|
||||
return SymmetricKey(SRNG.getRandomBytes(32))
|
||||
}
|
||||
|
||||
object Crypto {
|
||||
|
||||
object Hash : HashApi {
|
||||
override fun hash(data: UByteArray, key : UByteArray) : HashedData {
|
||||
return HashedData(Blake2bDelegatedStateless.digest(data, key))
|
||||
}
|
||||
|
||||
override fun multipartHash(key: UByteArray?) : com.ionspin.kotlin.crypto.hash.MultipartHash {
|
||||
return Blake2bDelegated(key)
|
||||
}
|
||||
}
|
||||
|
||||
object Encryption : EncryptionApi {
|
||||
override fun encrypt(key: SymmetricKey, data : Encryptable<*>, associatedData : UByteArray) : EncryptedData {
|
||||
if (key.value.size != 32) {
|
||||
throw RuntimeException("Invalid key size! Required 32, supplied ${key.value.size}")
|
||||
}
|
||||
val nonce = SRNG.getRandomBytes(24)
|
||||
return EncryptedData(XChaCha20Poly1305Delegated.encrypt(key.value, nonce, data.toEncryptableForm(), associatedData), nonce)
|
||||
|
||||
}
|
||||
|
||||
override fun <T: Encryptable<T>> decrypt(key: SymmetricKey, encryptedData : EncryptedData, associatedData: UByteArray, byteArrayDeserializer : (UByteArray) -> T) : T {
|
||||
return byteArrayDeserializer(XChaCha20Poly1305Delegated.decrypt(key.value, encryptedData.nonce, encryptedData.ciphertext, associatedData))
|
||||
|
||||
}
|
||||
|
||||
override fun createMultipartEncryptor(key: SymmetricKey): MultipartAuthenticatedEncryption {
|
||||
return MultipartAuthenticatedEncryptor(key)
|
||||
}
|
||||
|
||||
override fun createMultipartDecryptor(key: SymmetricKey, header: MultipartEncryptionHeader) : MultipartAuthenticatedDecryption {
|
||||
val decryptor = XChaCha20Poly1305Delegated()
|
||||
decryptor.initializeForDecryption(key.value, header.nonce)
|
||||
return MultipartAuthenticatedDecryptor(decryptor)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
class MultipartAuthenticatedEncryptor internal constructor(val key : SymmetricKey) : MultipartAuthenticatedEncryption {
|
||||
|
||||
val header : MultipartEncryptionHeader
|
||||
val primitive = XChaCha20Poly1305Delegated()
|
||||
init {
|
||||
header = MultipartEncryptionHeader(primitive.initializeForEncryption(key.value))
|
||||
}
|
||||
|
||||
override fun startEncryption(): MultipartEncryptionHeader {
|
||||
return header
|
||||
}
|
||||
|
||||
override fun encryptPartialData(data: UByteArray, associatedData: UByteArray): EncryptedDataPart {
|
||||
return EncryptedDataPart(primitive.encrypt(data, associatedData))
|
||||
}
|
||||
|
||||
override fun cleanup() {
|
||||
primitive.cleanup()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class MultipartAuthenticatedDecryptor internal constructor(val decryptor: XChaCha20Poly1305Delegated) : MultipartAuthenticatedDecryption {
|
||||
override fun decryptPartialData(data: EncryptedDataPart, associatedData: UByteArray): DecryptedDataPart {
|
||||
return DecryptedDataPart(decryptor.decrypt(data.data, associatedData))
|
||||
}
|
||||
|
||||
override fun cleanup() {
|
||||
decryptor.cleanup()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
expect object Initializer {
|
||||
fun isInitialized() : Boolean
|
||||
|
||||
suspend fun initialize()
|
||||
|
||||
fun initializeWithCallback(done: () -> (Unit))
|
||||
}
|
||||
|
@ -1,12 +0,0 @@
|
||||
package _multiplatform_crypto_delegated
|
||||
|
||||
/**
|
||||
* Created by Ugljesa Jovanovic
|
||||
* ugljesa.jovanovic@ionspin.com
|
||||
* on 24-May-2020
|
||||
*/
|
||||
//Workaround for https://youtrack.jetbrains.com/issue/KT-36878
|
||||
val byteArray = byteArrayOf(0)
|
||||
val byte = 0.toByte()
|
||||
val longArray = longArrayOf(0)
|
||||
val long = 0L
|
@ -1,26 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019 Ugljesa Jovanovic
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.ionspin.kotlin.crypto
|
||||
|
||||
/**
|
||||
* Created by Ugljesa Jovanovic
|
||||
* ugljesa.jovanovic@ionspin.com
|
||||
* on 21-Sep-2019
|
||||
*/
|
||||
expect object SRNG {
|
||||
fun getRandomBytes(amount : Int) : UByteArray
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
package com.ionspin.kotlin.crypto.authenticated
|
||||
|
||||
|
||||
/**
|
||||
* Created by Ugljesa Jovanovic
|
||||
* ugljesa.jovanovic@ionspin.com
|
||||
* on 14-Jun-2020
|
||||
*/
|
||||
expect class XChaCha20Poly1305Delegated internal constructor() {
|
||||
internal constructor(key: UByteArray, testState : UByteArray, testHeader: UByteArray, isDecryptor: Boolean)
|
||||
companion object {
|
||||
fun encrypt(key: UByteArray, nonce: UByteArray, message: UByteArray, associatedData: UByteArray) : UByteArray
|
||||
fun decrypt(key: UByteArray, nonce: UByteArray, ciphertext: UByteArray, associatedData: UByteArray) : UByteArray
|
||||
}
|
||||
fun initializeForEncryption(key: UByteArray) : UByteArray
|
||||
fun initializeForDecryption(key: UByteArray, header: UByteArray)
|
||||
fun encrypt(data: UByteArray, associatedData: UByteArray = ubyteArrayOf()) : UByteArray
|
||||
fun decrypt(data: UByteArray, associatedData: UByteArray = ubyteArrayOf()) : UByteArray
|
||||
fun cleanup()
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
@ -1,31 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019 Ugljesa Jovanovic
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.ionspin.kotlin.crypto.hash.blake2b
|
||||
|
||||
/**
|
||||
* Created by Ugljesa Jovanovic
|
||||
* ugljesa.jovanovic@ionspin.com
|
||||
* on 14-Jul-2019
|
||||
*/
|
||||
|
||||
|
||||
expect class Blake2bDelegated(key: UByteArray? = null, hashLength: Int = Blake2bProperties.MAX_HASH_BYTES) : Blake2bMultipart
|
||||
|
||||
|
||||
expect object Blake2bDelegatedStateless : Blake2b
|
||||
|
||||
|
@ -1,29 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019 Ugljesa Jovanovic
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.ionspin.kotlin.crypto.hash.sha
|
||||
|
||||
|
||||
/**
|
||||
* Created by Ugljesa Jovanovic
|
||||
* ugljesa.jovanovic@ionspin.com
|
||||
* on 17-Jul-2019
|
||||
*/
|
||||
|
||||
|
||||
expect class Sha256Delegated() : Sha256
|
||||
|
||||
expect object Sha256StatelessDelegated : StatelessSha256
|
@ -1,29 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019 Ugljesa Jovanovic
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.ionspin.kotlin.crypto.hash.sha
|
||||
|
||||
|
||||
/**
|
||||
* Created by Ugljesa Jovanovic
|
||||
* ugljesa.jovanovic@ionspin.com
|
||||
* on 17-Jul-2019
|
||||
*/
|
||||
|
||||
|
||||
expect class Sha512Delegated() : Sha512Multipart
|
||||
|
||||
expect object Sha512StatelessDelegated : Sha512
|
@ -1,10 +0,0 @@
|
||||
package com.ionspin.kotlin.crypto.keyderivation.argon2
|
||||
|
||||
import com.ionspin.kotlin.crypto.keyderivation.KeyDerivationFunction
|
||||
|
||||
/**
|
||||
* Created by Ugljesa Jovanovic
|
||||
* ugljesa.jovanovic@ionspin.com
|
||||
* on 24-May-2020
|
||||
*/
|
||||
interface Argon2 : KeyDerivationFunction
|
@ -1,34 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019 Ugljesa Jovanovic
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.ionspin.kotlin.crypto.parallelization
|
||||
|
||||
import kotlin.time.ExperimentalTime
|
||||
|
||||
/**
|
||||
* Created by Ugljesa Jovanovic
|
||||
* ugljesa.jovanovic@ionspin.com
|
||||
* on 17-May-2020
|
||||
*/
|
||||
@ExperimentalTime
|
||||
object Coroutines14 {
|
||||
fun argonParallel() : Array<UByte> {
|
||||
// val argon = Argon2()
|
||||
// argon
|
||||
println("Placeholder")
|
||||
return emptyArray()
|
||||
}
|
||||
}
|
@ -1,216 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019 Ugljesa Jovanovic
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
@file:Suppress("EXPERIMENTAL_API_USAGE")
|
||||
|
||||
package com.ionspin.kotlin.crypto.util
|
||||
|
||||
/**
|
||||
* Created by Ugljesa Jovanovic
|
||||
* ugljesa.jovanovic@ionspin.com
|
||||
* on 15-Jul-2019
|
||||
*/
|
||||
|
||||
|
||||
inline fun <reified T> Array<T>.chunked(sliceSize: Int): Array<Array<T>> {
|
||||
val last = this.size % sliceSize
|
||||
val hasLast = last != 0
|
||||
val numberOfSlices = this.size / sliceSize
|
||||
|
||||
|
||||
val result : MutableList<List<T>> = MutableList<List<T>>(0) { emptyList() }
|
||||
|
||||
for (i in 0 until numberOfSlices) {
|
||||
result.add(this.slice(i * sliceSize until (i + 1) * sliceSize))
|
||||
}
|
||||
if (hasLast) {
|
||||
result.add(this.slice(numberOfSlices * sliceSize until this.size))
|
||||
}
|
||||
|
||||
return result.map { it.toTypedArray() }.toTypedArray()
|
||||
|
||||
}
|
||||
|
||||
|
||||
infix fun UInt.rotateRight(places: Int): UInt {
|
||||
return (this shr places) xor (this shl (32 - places))
|
||||
}
|
||||
|
||||
|
||||
infix fun ULong.rotateRight(places: Int): ULong {
|
||||
return (this shr places) xor (this shl (64 - places))
|
||||
}
|
||||
|
||||
|
||||
infix fun Array<UByte>.xor(other : Array<UByte>) : Array<UByte> {
|
||||
if (this.size != other.size) {
|
||||
throw RuntimeException("Operands of different sizes are not supported yet")
|
||||
}
|
||||
return Array(this.size) { this[it] xor other[it] }
|
||||
}
|
||||
|
||||
|
||||
infix fun UByteArray.xor(other : UByteArray) : UByteArray {
|
||||
if (this.size != other.size) {
|
||||
throw RuntimeException("Operands of different sizes are not supported yet")
|
||||
}
|
||||
return UByteArray(this.size) { this[it] xor other[it] }
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// UInt / Array utils
|
||||
|
||||
fun UInt.toBigEndianUByteArray() : Array<UByte> {
|
||||
return Array<UByte> (4) {
|
||||
((this shr (24 - (it * 8))) and 0xFFU).toUByte()
|
||||
}
|
||||
}
|
||||
|
||||
fun UInt.toLittleEndianTypedUByteArray() : Array<UByte> {
|
||||
return Array<UByte> (4) {
|
||||
((this shr (it * 8)) and 0xFFU).toUByte()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun UInt.toLittleEndianUByteArray() : UByteArray {
|
||||
return UByteArray (4) {
|
||||
((this shr (it * 8)) and 0xFFU).toUByte()
|
||||
}
|
||||
}
|
||||
|
||||
// UInt / Array utils
|
||||
|
||||
fun ULong.toBigEndianUByteArray() : Array<UByte> {
|
||||
return Array<UByte> (8) {
|
||||
((this shr (56 - (it * 8))) and 0xFFU).toUByte()
|
||||
}
|
||||
}
|
||||
|
||||
fun ULong.toLittleEndianTypedUByteArray() : Array<UByte> {
|
||||
return Array<UByte> (8) {
|
||||
((this shr (it * 8)) and 0xFFU).toUByte()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun ULong.toLittleEndianUByteArray() :UByteArray {
|
||||
return UByteArray (8) {
|
||||
((this shr (it * 8)) and 0xFFU).toUByte()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun Array<UByte>.fromLittleEndianArrayToULong() : ULong {
|
||||
if (this.size > 8) {
|
||||
throw RuntimeException("ore than 8 bytes in input, potential overflow")
|
||||
}
|
||||
var ulong = this.foldIndexed(0UL) { index, acc, uByte -> acc or (uByte.toULong() shl (index * 8))}
|
||||
return ulong
|
||||
}
|
||||
|
||||
|
||||
fun UByteArray.fromLittleEndianArrayToULong() : ULong {
|
||||
if (this.size > 8) {
|
||||
throw RuntimeException("ore than 8 bytes in input, potential overflow")
|
||||
}
|
||||
var ulong = this.foldIndexed(0UL) { index, acc, uByte -> acc or (uByte.toULong() shl (index * 8))}
|
||||
return ulong
|
||||
}
|
||||
|
||||
fun UByteArray.arrayChunked(sliceSize: Int): List<UByteArray> {
|
||||
val last = this.size % sliceSize
|
||||
val hasLast = last != 0
|
||||
val numberOfSlices = this.size / sliceSize
|
||||
|
||||
|
||||
val result : MutableList<UByteArray> = MutableList<UByteArray>(0) { ubyteArrayOf() }
|
||||
|
||||
for (i in 0 until numberOfSlices) {
|
||||
result.add(this.sliceArray(i * sliceSize until (i + 1) * sliceSize))
|
||||
}
|
||||
if (hasLast) {
|
||||
result.add(this.sliceArray(numberOfSlices * sliceSize until this.size))
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
|
||||
|
||||
fun Array<UByte>.fromBigEndianArrayToULong() : ULong {
|
||||
if (this.size > 8) {
|
||||
throw RuntimeException("ore than 8 bytes in input, potential overflow")
|
||||
}
|
||||
var ulong = this.foldIndexed(0UL) {
|
||||
index, acc, uByte ->
|
||||
val res = acc or (uByte.toULong() shl (56 - (index * 8)))
|
||||
res
|
||||
|
||||
}
|
||||
return ulong
|
||||
}
|
||||
|
||||
|
||||
fun Array<UByte>.fromLittleEndianArrayToUInt() : UInt {
|
||||
if (this.size > 4) {
|
||||
throw RuntimeException("ore than 8 bytes in input, potential overflow")
|
||||
}
|
||||
var uint = this.foldIndexed(0U) { index, acc, uByte -> acc or (uByte.toUInt() shl (index * 8))}
|
||||
return uint
|
||||
}
|
||||
|
||||
|
||||
fun UByteArray.fromLittleEndianArrayToUInt() : UInt {
|
||||
if (this.size > 4) {
|
||||
throw RuntimeException("ore than 8 bytes in input, potential overflow")
|
||||
}
|
||||
var uint = this.foldIndexed(0U) { index, acc, uByte -> acc or (uByte.toUInt() shl (index * 8))}
|
||||
return uint
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
fun Array<UByte>.fromBigEndianArrayToUInt() : UInt {
|
||||
if (this.size > 4) {
|
||||
throw RuntimeException("ore than 8 bytes in input, potential overflow")
|
||||
}
|
||||
var uint = this.foldIndexed(0U) { index, acc, uByte -> acc or (uByte.toUInt() shl (24 - (index * 8))) }
|
||||
return uint
|
||||
}
|
||||
|
||||
|
||||
operator fun UInt.plus(other : UByteArray) : UByteArray {
|
||||
return this.toLittleEndianUByteArray() + other
|
||||
}
|
||||
|
||||
//AES Flatten
|
||||
fun Collection<UByteArray>.flattenToUByteArray(): UByteArray {
|
||||
val result = UByteArray(sumBy { it.size })
|
||||
var position = 0
|
||||
for (element in this) {
|
||||
element.forEach { uByte ->
|
||||
result[position] = uByte
|
||||
position++
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
package com.ionspin.kotlin.crypto
|
||||
|
||||
import kotlin.test.Test
|
||||
|
||||
/**
|
||||
* Created by Ugljesa Jovanovic
|
||||
* ugljesa.jovanovic@ionspin.com
|
||||
* on 17-Jul-2020
|
||||
*/
|
||||
class DebugTest {
|
||||
|
||||
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019 Ugljesa Jovanovic
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.ionspin.kotlin.crypto
|
||||
|
||||
import com.ionspin.kotlin.crypto.util.testBlocking
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
/**
|
||||
* Created by Ugljesa Jovanovic
|
||||
* ugljesa.jovanovic@ionspin.com
|
||||
* on 21-Sep-2019
|
||||
*/
|
||||
class SRNGTest {
|
||||
@Test
|
||||
fun testSrng() = testBlocking {
|
||||
CryptoInitializerDelegated.initialize()
|
||||
//Just a sanity test, need to add better srng tests.
|
||||
val randomBytes1 = SRNG.getRandomBytes(10)
|
||||
val randomBytes2 = SRNG.getRandomBytes(10)
|
||||
assertTrue { !randomBytes1.contentEquals(randomBytes2) }
|
||||
}
|
||||
}
|
@ -1,240 +0,0 @@
|
||||
package com.ionspin.kotlin.crypto.authenticated
|
||||
|
||||
import com.ionspin.kotlin.crypto.CryptoInitializerDelegated
|
||||
import com.ionspin.kotlin.crypto.Initializer
|
||||
import com.ionspin.kotlin.crypto.hash.encodeToUByteArray
|
||||
import com.ionspin.kotlin.crypto.util.hexColumsPrint
|
||||
import com.ionspin.kotlin.crypto.util.testBlocking
|
||||
import kotlin.test.Ignore
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertFails
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
/**
|
||||
* Created by Ugljesa Jovanovic
|
||||
* ugljesa.jovanovic@ionspin.com
|
||||
* on 17-Jun-2020
|
||||
*/
|
||||
class XChaCha20Poly1305Test {
|
||||
|
||||
|
||||
@Test
|
||||
fun xChaCha20Poly1305() = testBlocking {
|
||||
CryptoInitializerDelegated.initialize()
|
||||
|
||||
assertTrue {
|
||||
val message = ("Ladies and Gentlemen of the class of '99: If I could offer you " +
|
||||
"only one tip for the future, sunscreen would be it.").encodeToUByteArray()
|
||||
|
||||
val associatedData = ubyteArrayOf(
|
||||
0x50U, 0x51U, 0x52U, 0x53U, 0xc0U, 0xc1U, 0xc2U, 0xc3U, 0xc4U, 0xc5U, 0xc6U, 0xc7U
|
||||
)
|
||||
val key = ubyteArrayOf(
|
||||
0x80U, 0x81U, 0x82U, 0x83U, 0x84U, 0x85U, 0x86U, 0x87U,
|
||||
0x88U, 0x89U, 0x8aU, 0x8bU, 0x8cU, 0x8dU, 0x8eU, 0x8fU,
|
||||
0x90U, 0x91U, 0x92U, 0x93U, 0x94U, 0x95U, 0x96U, 0x97U,
|
||||
0x98U, 0x99U, 0x9aU, 0x9bU, 0x9cU, 0x9dU, 0x9eU, 0x9fU,
|
||||
)
|
||||
|
||||
val nonce = ubyteArrayOf(
|
||||
0x40U, 0x41U, 0x42U, 0x43U, 0x44U, 0x45U, 0x46U, 0x47U,
|
||||
0x48U, 0x49U, 0x4aU, 0x4bU, 0x4cU, 0x4dU, 0x4eU, 0x4fU,
|
||||
0x50U, 0x51U, 0x52U, 0x53U, 0x54U, 0x55U, 0x56U, 0x57U,
|
||||
)
|
||||
|
||||
val expected = ubyteArrayOf(
|
||||
0xbdU, 0x6dU, 0x17U, 0x9dU, 0x3eU, 0x83U, 0xd4U, 0x3bU,
|
||||
0x95U, 0x76U, 0x57U, 0x94U, 0x93U, 0xc0U, 0xe9U, 0x39U,
|
||||
0x57U, 0x2aU, 0x17U, 0x00U, 0x25U, 0x2bU, 0xfaU, 0xccU,
|
||||
0xbeU, 0xd2U, 0x90U, 0x2cU, 0x21U, 0x39U, 0x6cU, 0xbbU,
|
||||
0x73U, 0x1cU, 0x7fU, 0x1bU, 0x0bU, 0x4aU, 0xa6U, 0x44U,
|
||||
0x0bU, 0xf3U, 0xa8U, 0x2fU, 0x4eU, 0xdaU, 0x7eU, 0x39U,
|
||||
0xaeU, 0x64U, 0xc6U, 0x70U, 0x8cU, 0x54U, 0xc2U, 0x16U,
|
||||
0xcbU, 0x96U, 0xb7U, 0x2eU, 0x12U, 0x13U, 0xb4U, 0x52U,
|
||||
0x2fU, 0x8cU, 0x9bU, 0xa4U, 0x0dU, 0xb5U, 0xd9U, 0x45U,
|
||||
0xb1U, 0x1bU, 0x69U, 0xb9U, 0x82U, 0xc1U, 0xbbU, 0x9eU,
|
||||
0x3fU, 0x3fU, 0xacU, 0x2bU, 0xc3U, 0x69U, 0x48U, 0x8fU,
|
||||
0x76U, 0xb2U, 0x38U, 0x35U, 0x65U, 0xd3U, 0xffU, 0xf9U,
|
||||
0x21U, 0xf9U, 0x66U, 0x4cU, 0x97U, 0x63U, 0x7dU, 0xa9U,
|
||||
0x76U, 0x88U, 0x12U, 0xf6U, 0x15U, 0xc6U, 0x8bU, 0x13U,
|
||||
0xb5U, 0x2eU, 0xc0U, 0x87U, 0x59U, 0x24U, 0xc1U, 0xc7U,
|
||||
0x98U, 0x79U, 0x47U, 0xdeU, 0xafU, 0xd8U, 0x78U, 0x0aU,
|
||||
0xcfU, 0x49U
|
||||
)
|
||||
val encrypted = XChaCha20Poly1305Delegated.encrypt(key, nonce, message, associatedData)
|
||||
encrypted.hexColumsPrint()
|
||||
val decrypted = XChaCha20Poly1305Delegated.decrypt(key, nonce, encrypted, associatedData)
|
||||
println("Decrypted")
|
||||
decrypted.hexColumsPrint()
|
||||
println("----------")
|
||||
encrypted.contentEquals(expected) && decrypted.contentEquals(message)
|
||||
}
|
||||
|
||||
assertTrue {
|
||||
val message = ubyteArrayOf(
|
||||
0x00U
|
||||
)
|
||||
val associatedData = ubyteArrayOf(
|
||||
0x00U
|
||||
)
|
||||
val key = ubyteArrayOf(
|
||||
0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U,
|
||||
0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U,
|
||||
0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U,
|
||||
0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U,
|
||||
)
|
||||
|
||||
val nonce = ubyteArrayOf(
|
||||
0x00U, 0x01U, 0x02U, 0x03U, 0x04U, 0x05U, 0x06U, 0x07U, 0x08U, 0x09U, 0x0aU, 0x0bU,
|
||||
0x0cU, 0x0dU, 0x0eU, 0x0fU, 0x10U, 0x11U, 0x12U, 0x13U, 0x14U, 0x15U, 0x16U, 0x17U,
|
||||
)
|
||||
|
||||
val expected = ubyteArrayOf(
|
||||
0xbdU, 0x3bU, 0x8aU, 0xd7U, 0xa1U, 0x9dU, 0xe8U, 0xc4U, 0x55U,
|
||||
0x84U, 0x6fU, 0xfcU, 0x75U, 0x31U, 0xbfU, 0x0cU, 0x2dU
|
||||
)
|
||||
val encrypted = XChaCha20Poly1305Delegated.encrypt(key, nonce, message, associatedData)
|
||||
val decrypted = XChaCha20Poly1305Delegated.decrypt(key, nonce, encrypted, associatedData)
|
||||
|
||||
encrypted.contentEquals(expected) && decrypted.contentEquals(message)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Ignore() //"Will fail because nonce is not a parameter any more"
|
||||
@Test
|
||||
fun updateableXChaCha20Poly1305() {
|
||||
assertTrue {
|
||||
val message = ("Ladies and Gentlemen of the class of '99: If I could offer you " +
|
||||
"only one tip for the future, sunscreen would be it.").encodeToUByteArray()
|
||||
|
||||
val associatedData = ubyteArrayOf(
|
||||
0x50U, 0x51U, 0x52U, 0x53U, 0xc0U, 0xc1U, 0xc2U, 0xc3U, 0xc4U, 0xc5U, 0xc6U, 0xc7U
|
||||
)
|
||||
val key = ubyteArrayOf(
|
||||
0x80U, 0x81U, 0x82U, 0x83U, 0x84U, 0x85U, 0x86U, 0x87U,
|
||||
0x88U, 0x89U, 0x8aU, 0x8bU, 0x8cU, 0x8dU, 0x8eU, 0x8fU,
|
||||
0x90U, 0x91U, 0x92U, 0x93U, 0x94U, 0x95U, 0x96U, 0x97U,
|
||||
0x98U, 0x99U, 0x9aU, 0x9bU, 0x9cU, 0x9dU, 0x9eU, 0x9fU,
|
||||
)
|
||||
|
||||
val nonce = ubyteArrayOf(
|
||||
0x40U, 0x41U, 0x42U, 0x43U, 0x44U, 0x45U, 0x46U, 0x47U,
|
||||
0x48U, 0x49U, 0x4aU, 0x4bU, 0x4cU, 0x4dU, 0x4eU, 0x4fU,
|
||||
0x50U, 0x51U, 0x52U, 0x53U, 0x54U, 0x55U, 0x56U, 0x57U,
|
||||
)
|
||||
|
||||
val expected = ubyteArrayOf(
|
||||
0xbdU, 0x6dU, 0x17U, 0x9dU, 0x3eU, 0x83U, 0xd4U, 0x3bU,
|
||||
0x95U, 0x76U, 0x57U, 0x94U, 0x93U, 0xc0U, 0xe9U, 0x39U,
|
||||
0x57U, 0x2aU, 0x17U, 0x00U, 0x25U, 0x2bU, 0xfaU, 0xccU,
|
||||
0xbeU, 0xd2U, 0x90U, 0x2cU, 0x21U, 0x39U, 0x6cU, 0xbbU,
|
||||
0x73U, 0x1cU, 0x7fU, 0x1bU, 0x0bU, 0x4aU, 0xa6U, 0x44U,
|
||||
0x0bU, 0xf3U, 0xa8U, 0x2fU, 0x4eU, 0xdaU, 0x7eU, 0x39U,
|
||||
0xaeU, 0x64U, 0xc6U, 0x70U, 0x8cU, 0x54U, 0xc2U, 0x16U,
|
||||
0xcbU, 0x96U, 0xb7U, 0x2eU, 0x12U, 0x13U, 0xb4U, 0x52U,
|
||||
0x2fU, 0x8cU, 0x9bU, 0xa4U, 0x0dU, 0xb5U, 0xd9U, 0x45U,
|
||||
0xb1U, 0x1bU, 0x69U, 0xb9U, 0x82U, 0xc1U, 0xbbU, 0x9eU,
|
||||
0x3fU, 0x3fU, 0xacU, 0x2bU, 0xc3U, 0x69U, 0x48U, 0x8fU,
|
||||
0x76U, 0xb2U, 0x38U, 0x35U, 0x65U, 0xd3U, 0xffU, 0xf9U,
|
||||
0x21U, 0xf9U, 0x66U, 0x4cU, 0x97U, 0x63U, 0x7dU, 0xa9U,
|
||||
0x76U, 0x88U, 0x12U, 0xf6U, 0x15U, 0xc6U, 0x8bU, 0x13U,
|
||||
0xb5U, 0x2eU, 0xc0U, 0x87U, 0x59U, 0x24U, 0xc1U, 0xc7U,
|
||||
0x98U, 0x79U, 0x47U, 0xdeU, 0xafU, 0xd8U, 0x78U, 0x0aU,
|
||||
0xcfU, 0x49U
|
||||
)
|
||||
// val xChaChaPoly = XChaCha20Poly1305Delegated(key, associatedData)
|
||||
// val firstChunk = xChaChaPoly.encrypt(message)
|
||||
// val finalChunk = xChaChaPoly.finishEncryption().first
|
||||
// val result = firstChunk + finalChunk
|
||||
|
||||
// result.contentEquals(expected)
|
||||
1 == 1
|
||||
}
|
||||
|
||||
assertTrue {
|
||||
val message = ubyteArrayOf(
|
||||
0x00U
|
||||
)
|
||||
val associatedData = ubyteArrayOf(
|
||||
0x00U
|
||||
)
|
||||
val key = ubyteArrayOf(
|
||||
0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U,
|
||||
0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U,
|
||||
0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U,
|
||||
0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U,
|
||||
)
|
||||
|
||||
val nonce = ubyteArrayOf(
|
||||
0x00U, 0x01U, 0x02U, 0x03U, 0x04U, 0x05U, 0x06U, 0x07U, 0x08U, 0x09U, 0x0aU, 0x0bU,
|
||||
0x0cU, 0x0dU, 0x0eU, 0x0fU, 0x10U, 0x11U, 0x12U, 0x13U, 0x14U, 0x15U, 0x16U, 0x17U,
|
||||
)
|
||||
|
||||
val expected = ubyteArrayOf(
|
||||
0xbdU, 0x3bU, 0x8aU, 0xd7U, 0xa1U, 0x9dU, 0xe8U, 0xc4U, 0x55U,
|
||||
0x84U, 0x6fU, 0xfcU, 0x75U, 0x31U, 0xbfU, 0x0cU, 0x2dU
|
||||
)
|
||||
// val xChaChaPoly = XChaCha20Poly1305Delegated(key, associatedData)
|
||||
// val firstChunk = xChaChaPoly.encrypt(message)
|
||||
// val finalChunk = xChaChaPoly.finishEncryption().first
|
||||
// val result = firstChunk + finalChunk
|
||||
// result.contentEquals(expected)
|
||||
1 == 1
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testStreamingImpl() = testBlocking {
|
||||
Initializer.initialize()
|
||||
val key = UByteArray(32) { 0U }
|
||||
val state = ubyteArrayOf(
|
||||
0x2DU, 0xDBU, 0xC7U, 0xB2U, 0x03U, 0xBCU, 0xC3U, 0x22U, 0xBDU, 0x0CU, 0xBAU, 0x82U, 0xADU, 0x77U, 0x79U, 0x44U,
|
||||
0xE6U, 0x8FU, 0xA9U, 0x94U, 0x89U, 0xB1U, 0xDFU, 0xBEU, 0x00U, 0x9FU, 0x69U, 0xECU, 0x21U, 0x88U, 0x47U, 0x55U,
|
||||
0x01U, 0x00U, 0x00U, 0x00U, 0xC5U, 0x55U, 0x06U, 0x38U, 0xEBU, 0xA3U, 0x12U, 0x7BU, 0x00U, 0x00U, 0x00U, 0x00U,
|
||||
0x00U, 0x00U, 0x00U, 0x00U,
|
||||
)
|
||||
val header = ubyteArrayOf(
|
||||
0x49U, 0x62U, 0x22U, 0x03U, 0xB7U, 0x46U, 0x11U, 0x97U, 0x8FU, 0x46U, 0x4AU, 0x3BU, 0x2FU, 0x2AU, 0x81U, 0x03U,
|
||||
0xC5U, 0x55U, 0x06U, 0x38U, 0xEBU, 0xA3U, 0x12U, 0x7BU,
|
||||
)
|
||||
val expected = ubyteArrayOf(
|
||||
0xAFU, 0xD3U, 0x2DU, 0x59U, 0xB8U, 0xC4U, 0x66U, 0x2EU, 0x47U, 0x29U, 0xC6U, 0xF9U, 0x93U, 0x4BU, 0x09U, 0x27U,
|
||||
0x24U, 0xDDU, 0xF3U, 0x05U, 0x48U, 0x94U, 0x67U, 0x10U, 0x00U, 0x21U, 0x85U, 0x22U, 0x96U, 0x3CU, 0xCEU, 0x8EU,
|
||||
0xB7U, 0x53U, 0x9DU, 0x46U, 0xF5U, 0x3CU, 0x5EU, 0x48U, 0x9BU, 0x8CU, 0x13U, 0xB7U, 0x28U, 0x6BU, 0xB3U, 0x6CU,
|
||||
0x3AU, 0x04U, 0xB7U, 0x25U, 0xB9U, 0x50U, 0x45U, 0x08U, 0x0BU, 0x89U, 0xA2U, 0x0FU, 0x70U, 0xCCU, 0x60U, 0x1BU,
|
||||
0xC3U, 0x17U, 0x35U, 0x9FU, 0xAEU, 0x82U, 0x51U, 0x43U, 0x1BU, 0x9DU, 0x53U, 0x9EU, 0xE2U, 0xAFU, 0x20U, 0x1FU,
|
||||
0xFDU, 0x03U, 0x59U, 0x11U, 0x51U, 0x9EU, 0xACU, 0x83U, 0xCDU, 0x78U, 0xD1U, 0xD0U, 0xE5U, 0xD7U, 0x0EU, 0x41U,
|
||||
0xDEU, 0xFBU, 0x5CU, 0x7FU, 0x1CU, 0x26U, 0x32U, 0x2CU, 0x51U, 0xF6U, 0xEFU, 0xC6U, 0x34U, 0xC4U, 0xACU, 0x6CU,
|
||||
0xE8U, 0xF9U, 0x4BU, 0xABU, 0xA3U,
|
||||
)
|
||||
val encryptor = XChaCha20Poly1305Delegated(key, state, header, false)
|
||||
val decryptor = XChaCha20Poly1305Delegated(key, state, header, true)
|
||||
val data = UByteArray(100) { 0U }
|
||||
val result = encryptor.encrypt(data)
|
||||
val decrypted = decryptor.decrypt(result)
|
||||
println("Encrypted -----------")
|
||||
result.hexColumsPrint()
|
||||
println("Encrypted end -----------")
|
||||
println("Decrypted -----------")
|
||||
decrypted.hexColumsPrint()
|
||||
println("Decrypted end -----------")
|
||||
assertTrue {
|
||||
expected.contentEquals(result) && decrypted.contentEquals(data)
|
||||
}
|
||||
val messedUpTag = result.copyOf()
|
||||
messedUpTag[messedUpTag.size - 3] = 0U
|
||||
messedUpTag[messedUpTag.size - 2] = 0U
|
||||
messedUpTag[messedUpTag.size - 1] = 0U
|
||||
assertFails {
|
||||
val decryptorForWrongTag = XChaCha20Poly1305Delegated(key, state, header, true)
|
||||
val plaintext = decryptorForWrongTag.decrypt(messedUpTag)
|
||||
println("Decrypted with wrong tag -----------")
|
||||
plaintext.hexColumsPrint()
|
||||
println("Decrypted with wrong tag end -----------")
|
||||
}
|
||||
}
|
||||
}
|
@ -1,46 +0,0 @@
|
||||
package com.ionspin.kotlin.crypto.hash.blake2b
|
||||
|
||||
import com.ionspin.kotlin.crypto.Crypto
|
||||
import com.ionspin.kotlin.crypto.CryptoPrimitives
|
||||
import com.ionspin.kotlin.crypto.Initializer
|
||||
import com.ionspin.kotlin.crypto.hash.encodeToUByteArray
|
||||
import com.ionspin.kotlin.crypto.util.testBlocking
|
||||
import com.ionspin.kotlin.crypto.util.toHexString
|
||||
import kotlin.test.BeforeTest
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
/**
|
||||
* Created by Ugljesa Jovanovic
|
||||
* ugljesa.jovanovic@ionspin.com
|
||||
* on 09-Jun-2020
|
||||
*/
|
||||
class Blake2bTest {
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
fun statelessSimpleTest() = testBlocking {
|
||||
Initializer.initialize()
|
||||
val expected = "a71079d42853dea26e453004338670a53814b78137ffbed07603a41d76a483aa9bc33b582f77d30a65e6f29a89" +
|
||||
"6c0411f38312e1d66e0bf16386c86a89bea572"
|
||||
val result = CryptoPrimitives.Blake2b.stateless("test".encodeToUByteArray()).toHexString()
|
||||
// println("Result: $result")
|
||||
assertTrue { result == expected }
|
||||
}
|
||||
|
||||
//This is a bad test since it's not larger than one block
|
||||
//but for now I'm testing that the platform library is being correctly called
|
||||
@Test
|
||||
fun updateableSimpleTest() = testBlocking {
|
||||
Initializer.initialize()
|
||||
val expected = "a71079d42853dea26e453004338670a53814b78137ffbed07603a41d76a483aa9bc33b582f77d30a65e6f29a89" +
|
||||
"6c0411f38312e1d66e0bf16386c86a89bea572"
|
||||
val blake2b = CryptoPrimitives.Blake2b.updateable()
|
||||
blake2b.update("t".encodeToUByteArray())
|
||||
blake2b.update(("est".encodeToUByteArray()))
|
||||
val result = blake2b.digest().toHexString()
|
||||
// println("Result: $result")
|
||||
assertTrue { result == expected }
|
||||
}
|
||||
}
|
@ -1,46 +0,0 @@
|
||||
package com.ionspin.kotlin.crypto.hash.sha
|
||||
|
||||
import com.ionspin.kotlin.crypto.Crypto
|
||||
import com.ionspin.kotlin.crypto.CryptoPrimitives
|
||||
import com.ionspin.kotlin.crypto.Initializer
|
||||
import com.ionspin.kotlin.crypto.hash.encodeToUByteArray
|
||||
import com.ionspin.kotlin.crypto.util.testBlocking
|
||||
import com.ionspin.kotlin.crypto.util.toHexString
|
||||
import kotlin.test.BeforeTest
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
/**
|
||||
* Created by Ugljesa Jovanovic
|
||||
* ugljesa.jovanovic@ionspin.com
|
||||
* on 07-Jun-2020
|
||||
*/
|
||||
class Sha256Test {
|
||||
@BeforeTest
|
||||
fun beforeTest() = testBlocking {
|
||||
Initializer.initialize()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun statelessSimpleTest() = testBlocking {
|
||||
Initializer.initialize()
|
||||
val expected = "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08"
|
||||
val result = CryptoPrimitives.Sha256.stateless("test".encodeToUByteArray()).toHexString()
|
||||
// println("Result: $result")
|
||||
assertTrue { result == expected }
|
||||
}
|
||||
|
||||
//This is a bad test since it's not larger than one block
|
||||
//but for now I'm testing that the platform library is being correctly called
|
||||
@Test
|
||||
fun updateableSimpleTest() = testBlocking {
|
||||
Initializer.initialize()
|
||||
val expected = "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08"
|
||||
val sha256 = CryptoPrimitives.Sha256.updateable()
|
||||
sha256.update("t".encodeToUByteArray())
|
||||
sha256.update(("est".encodeToUByteArray()))
|
||||
val result = sha256.digest().toHexString()
|
||||
// println("Result: $result")
|
||||
assertTrue { result == expected }
|
||||
}
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
package com.ionspin.kotlin.crypto.hash.sha
|
||||
|
||||
import com.ionspin.kotlin.crypto.Crypto
|
||||
import com.ionspin.kotlin.crypto.CryptoPrimitives
|
||||
import com.ionspin.kotlin.crypto.Initializer
|
||||
import com.ionspin.kotlin.crypto.hash.encodeToUByteArray
|
||||
import com.ionspin.kotlin.crypto.util.testBlocking
|
||||
import com.ionspin.kotlin.crypto.util.toHexString
|
||||
import kotlin.test.BeforeTest
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
/**
|
||||
* Created by Ugljesa Jovanovic
|
||||
* ugljesa.jovanovic@ionspin.com
|
||||
* on 07-Jun-2020
|
||||
*/
|
||||
class Sha512Test {
|
||||
@BeforeTest
|
||||
fun beforeTest() = testBlocking {
|
||||
Initializer.initialize()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun statelessSimpleTest() = testBlocking {
|
||||
Initializer.initialize()
|
||||
val expected = "ee26b0dd4af7e749aa1a8ee3c10ae9923f618980772e473f8819a5d4940e0db27ac185f8a0e1d5f84f88bc887fd67" +
|
||||
"b143732c304cc5fa9ad8e6f57f50028a8ff"
|
||||
val result = CryptoPrimitives.Sha512.stateless("test".encodeToUByteArray()).toHexString()
|
||||
// println("Result: $result")
|
||||
assertTrue { result == expected }
|
||||
}
|
||||
|
||||
//This is a bad test since it's not larger than one block
|
||||
//but for now I'm testing that the platform library is being correctly called
|
||||
@Test
|
||||
fun updateableSimpleTest() = testBlocking {
|
||||
Initializer.initialize()
|
||||
val expected = "ee26b0dd4af7e749aa1a8ee3c10ae9923f618980772e473f8819a5d4940e0db27ac185f8a0e1d5f84f88bc887fd67" +
|
||||
"b143732c304cc5fa9ad8e6f57f50028a8ff"
|
||||
val sha512 = CryptoPrimitives.Sha512.updateable()
|
||||
sha512.update("t".encodeToUByteArray())
|
||||
sha512.update(("est".encodeToUByteArray()))
|
||||
val result = sha512.digest().toHexString()
|
||||
// println("Result: $result")
|
||||
assertTrue { result == expected }
|
||||
}
|
||||
}
|
@ -1,50 +0,0 @@
|
||||
package com.ionspin.kotlin.crypto.highlevel
|
||||
|
||||
import com.ionspin.kotlin.crypto.Crypto
|
||||
import com.ionspin.kotlin.crypto.Initializer
|
||||
import com.ionspin.kotlin.crypto.SymmetricKey
|
||||
import com.ionspin.kotlin.crypto.hash.decodeToString
|
||||
import com.ionspin.kotlin.crypto.hash.encodeToUByteArray
|
||||
import com.ionspin.kotlin.crypto.util.hexColumsPrint
|
||||
import com.ionspin.kotlin.crypto.util.testBlocking
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
/**
|
||||
* Created by Ugljesa Jovanovic
|
||||
* ugljesa.jovanovic@ionspin.com
|
||||
* on 09-Jul-2020
|
||||
*/
|
||||
class EncryptionTest {
|
||||
@Test
|
||||
fun testMultipartEncryption() = testBlocking {
|
||||
Initializer.initialize()
|
||||
val plaintext = ("pUoR4JVXJUeMKNkt6ZGGzEdTo33ajNGXwXpivBKA0XKs8toGRYI9Eul4bELRDkaQDNhd4vZseEFU" +
|
||||
"ojsAn3c9zIifIrMnydSivHVZ2pBtpAQwYoJhYmEsfE0tROGnOwFWyB9K6LRSv1gB3YqKR9VyM8mpRoUM3UCRRjyiX7bnKdCE1" +
|
||||
"EiX0myiwcY1nUKTgB3keERWtMU07hX7bCtao5nRvDofSj3o3IInHRQh6opltr5asQwn4m1qn029QF").encodeToUByteArray()
|
||||
val associatedData = "Additional data 1".encodeToUByteArray()
|
||||
val keyValue = UByteArray(32) { it.toUByte() }
|
||||
val key = SymmetricKey(keyValue)
|
||||
val encryptor = Crypto.Encryption.createMultipartEncryptor(key)
|
||||
val header = encryptor.startEncryption()
|
||||
val ciphertext1 = encryptor.encryptPartialData(plaintext.sliceArray(0 until 100), associatedData)
|
||||
val ciphertext2 = encryptor.encryptPartialData(plaintext.sliceArray(100 until 200))
|
||||
val ciphertext3 = encryptor.encryptPartialData(plaintext.sliceArray(200 until 250))
|
||||
//decrypt
|
||||
val decryptor = Crypto.Encryption.createMultipartDecryptor(key, header)
|
||||
val plaintext1 = decryptor.decryptPartialData(ciphertext1, associatedData)
|
||||
val plaintext2 = decryptor.decryptPartialData(ciphertext2)
|
||||
val plaintext3 = decryptor.decryptPartialData(ciphertext3)
|
||||
|
||||
val combinedPlaintext = plaintext1.data + plaintext2.data + plaintext3.data
|
||||
assertTrue {
|
||||
plaintext.contentEquals(combinedPlaintext)
|
||||
}
|
||||
encryptor.cleanup()
|
||||
decryptor.cleanup()
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019 Ugljesa Jovanovic
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.ionspin.kotlin.crypto.util
|
||||
|
||||
import kotlin.coroutines.Continuation
|
||||
import kotlin.coroutines.EmptyCoroutineContext
|
||||
import kotlin.coroutines.startCoroutine
|
||||
|
||||
|
||||
/**
|
||||
* Created by Ugljesa Jovanovic
|
||||
* ugljesa.jovanovic@ionspin.com
|
||||
* on 20-Jul-2019
|
||||
*/
|
||||
fun testBlocking(block : suspend () -> Unit) {
|
||||
val continuation = Continuation<Unit>(EmptyCoroutineContext) {
|
||||
//Do nothing
|
||||
if (it.isFailure) {
|
||||
throw it.exceptionOrNull()!!
|
||||
}
|
||||
}
|
||||
block.startCoroutine(continuation)
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
package com.ionspin.kotlin.crypto
|
||||
|
||||
import ext.libsodium.com.ionspin.kotlin.crypto.JsSodiumInterface
|
||||
import ext.libsodium.com.ionspin.kotlin.crypto.JsSodiumLoader
|
||||
/* 1.4-M1 has some weirdness with static/objects, or I'm misusing something, not sure */
|
||||
lateinit var sodiumPointer : JsSodiumInterface
|
||||
var sodiumLoaded: Boolean = false
|
||||
|
||||
fun getSodium() : JsSodiumInterface = sodiumPointer
|
||||
|
||||
//fun getSodiumAdvanced() : JsSodiumAdvancedInterface = js("sodiumPointer.libsodium")
|
||||
|
||||
fun setSodiumPointer(jsSodiumInterface: JsSodiumInterface) {
|
||||
js("sodiumPointer = jsSodiumInterface")
|
||||
}
|
||||
|
||||
fun getSodiumLoaded() : Boolean = sodiumLoaded
|
||||
|
||||
fun setSodiumLoaded(loaded: Boolean) {
|
||||
js("sodiumLoaded = loaded")
|
||||
}
|
||||
|
||||
actual object Initializer {
|
||||
private var isPlatformInitialized = false
|
||||
|
||||
actual suspend fun initialize() {
|
||||
JsSodiumLoader.load()
|
||||
isPlatformInitialized = true
|
||||
}
|
||||
|
||||
actual fun initializeWithCallback(done: () -> Unit) {
|
||||
JsSodiumLoader.loadWithCallback {
|
||||
isPlatformInitialized = true
|
||||
done()
|
||||
}
|
||||
}
|
||||
|
||||
actual fun isInitialized(): Boolean {
|
||||
return isPlatformInitialized
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -1,60 +0,0 @@
|
||||
package ext.libsodium.com.ionspin.kotlin.crypto
|
||||
|
||||
|
||||
import org.khronos.webgl.Uint8Array
|
||||
|
||||
/**
|
||||
* Created by Ugljesa Jovanovic
|
||||
* ugljesa.jovanovic@ionspin.com
|
||||
* on 27-May-2020
|
||||
*/
|
||||
interface JsSodiumInterface {
|
||||
|
||||
fun randombytes_buf(numberOfBytes: Int): Uint8Array
|
||||
|
||||
fun crypto_generichash(hashLength: Int, inputMessage: Uint8Array, key: Uint8Array,): Uint8Array
|
||||
|
||||
fun crypto_hash_sha256(message: Uint8Array): Uint8Array
|
||||
|
||||
fun crypto_hash_sha512(message: Uint8Array): Uint8Array
|
||||
|
||||
//Updateable
|
||||
|
||||
fun crypto_generichash_init(key : Uint8Array, hashLength: Int) : dynamic
|
||||
|
||||
fun crypto_generichash_update(state: dynamic, inputMessage: Uint8Array)
|
||||
|
||||
fun crypto_generichash_final(state: dynamic, hashLength: Int) : Uint8Array
|
||||
|
||||
|
||||
fun crypto_hash_sha256_init() : dynamic
|
||||
|
||||
fun crypto_hash_sha256_update(state: dynamic, message: Uint8Array)
|
||||
|
||||
fun crypto_hash_sha256_final(state: dynamic): Uint8Array
|
||||
|
||||
fun crypto_hash_sha512_init() : dynamic
|
||||
|
||||
fun crypto_hash_sha512_update(state: dynamic, message: Uint8Array)
|
||||
|
||||
fun crypto_hash_sha512_final(state: dynamic): Uint8Array
|
||||
|
||||
//XChaCha20Poly1305
|
||||
fun crypto_aead_xchacha20poly1305_ietf_encrypt(message: Uint8Array, associatedData: Uint8Array, secretNonce: Uint8Array, nonce: Uint8Array, key: Uint8Array) : Uint8Array
|
||||
fun crypto_aead_xchacha20poly1305_ietf_decrypt(secretNonce: Uint8Array, ciphertext: Uint8Array, associatedData: Uint8Array, nonce: Uint8Array, key: Uint8Array) : Uint8Array
|
||||
|
||||
//XChaCha20Poly1305
|
||||
//encrypt
|
||||
fun crypto_secretstream_xchacha20poly1305_init_push(header: Uint8Array) : dynamic
|
||||
fun crypto_secretstream_xchacha20poly1305_push(state: dynamic, message: Uint8Array, associatedData: Uint8Array, tag: UByte) : Uint8Array
|
||||
|
||||
//decrypt
|
||||
fun crypto_secretstream_xchacha20poly1305_init_pull(header: Uint8Array, key: Uint8Array) : dynamic
|
||||
fun crypto_secretstream_xchacha20poly1305_pull(state: dynamic, ciphertext: Uint8Array, associatedData: Uint8Array) : dynamic
|
||||
|
||||
//util
|
||||
fun memzero(array: Uint8Array)
|
||||
|
||||
|
||||
|
||||
}
|
@ -1,56 +0,0 @@
|
||||
package ext.libsodium.com.ionspin.kotlin.crypto
|
||||
|
||||
import com.ionspin.kotlin.crypto.getSodiumLoaded
|
||||
import com.ionspin.kotlin.crypto.setSodiumPointer
|
||||
import com.ionspin.kotlin.crypto.sodiumLoaded
|
||||
import ext.libsodium.*
|
||||
import kotlin.coroutines.Continuation
|
||||
import kotlin.coroutines.suspendCoroutine
|
||||
|
||||
/**
|
||||
* Created by Ugljesa Jovanovic
|
||||
* ugljesa.jovanovic@ionspin.com
|
||||
* on 27-May-2020
|
||||
*/
|
||||
object JsSodiumLoader {
|
||||
|
||||
class _EmitJsSodiumFunction {
|
||||
init {
|
||||
println(::crypto_generichash)
|
||||
println(::crypto_hash_sha256)
|
||||
println(::crypto_hash_sha512)
|
||||
println(::crypto_hash_sha256_init)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun storeSodium(promisedSodium: dynamic, continuation: Continuation<Unit>) {
|
||||
setSodiumPointer(promisedSodium)
|
||||
sodiumLoaded = true
|
||||
continuation.resumeWith(Result.success(Unit))
|
||||
}
|
||||
|
||||
suspend fun load() = suspendCoroutine<Unit> { continuation ->
|
||||
console.log(getSodiumLoaded())
|
||||
if (!getSodiumLoaded()) {
|
||||
val libsodiumModule = js("\$module\$libsodium_wrappers_sumo")
|
||||
_libsodiumPromise.then<dynamic> { storeSodium(libsodiumModule, continuation) }
|
||||
} else {
|
||||
continuation.resumeWith(Result.success(Unit))
|
||||
}
|
||||
}
|
||||
|
||||
fun loadWithCallback(doneCallback: () -> (Unit)) {
|
||||
console.log(getSodiumLoaded())
|
||||
if (!getSodiumLoaded()) {
|
||||
val libsodiumModule = js("\$module\$libsodium_wrappers_sumo")
|
||||
_libsodiumPromise.then<dynamic> {
|
||||
setSodiumPointer(libsodiumModule)
|
||||
sodiumLoaded = true
|
||||
doneCallback.invoke()
|
||||
}
|
||||
} else {
|
||||
doneCallback.invoke()
|
||||
}
|
||||
}
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
package ext.libsodium.com.ionspin.kotlin.crypto
|
||||
|
||||
import org.khronos.webgl.Uint8Array
|
||||
import org.khronos.webgl.get
|
||||
import org.khronos.webgl.set
|
||||
|
||||
/**
|
||||
* Created by Ugljesa Jovanovic
|
||||
* ugljesa.jovanovic@ionspin.com
|
||||
* on 25-Jun-2020
|
||||
*
|
||||
* TODO investigate using unsafe cast
|
||||
*/
|
||||
fun UByteArray.toUInt8Array() : Uint8Array {
|
||||
val uint8Result = Uint8Array(toByteArray().toTypedArray())
|
||||
return uint8Result
|
||||
}
|
||||
|
||||
|
||||
fun Uint8Array.toUByteArray() : UByteArray {
|
||||
val result = UByteArray(length)
|
||||
for (i in 0 until length) {
|
||||
result[i] = get(i).toUByte()
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019 Ugljesa Jovanovic
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.ionspin.kotlin.crypto
|
||||
|
||||
import org.khronos.webgl.get
|
||||
|
||||
/**
|
||||
* Created by Ugljesa Jovanovic
|
||||
* ugljesa.jovanovic@ionspin.com
|
||||
* on 21-Sep-2019
|
||||
*/
|
||||
actual object SRNG {
|
||||
var counter = 0
|
||||
|
||||
actual fun getRandomBytes(amount: Int): UByteArray {
|
||||
val randomBytes = getSodium().randombytes_buf(amount)
|
||||
val randomBytesUByteArray = UByteArray(amount) {
|
||||
0U
|
||||
}
|
||||
for (i in 0 until amount) {
|
||||
js("""
|
||||
randomBytesUByteArray[i] = randomBytes[i]
|
||||
""")
|
||||
}
|
||||
return randomBytesUByteArray
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -1,130 +0,0 @@
|
||||
package com.ionspin.kotlin.crypto.authenticated
|
||||
|
||||
import com.ionspin.kotlin.crypto.InvalidTagException
|
||||
import com.ionspin.kotlin.crypto.getSodium
|
||||
import com.ionspin.kotlin.crypto.util.hexColumsPrint
|
||||
import ext.libsodium.com.ionspin.kotlin.crypto.toUByteArray
|
||||
import ext.libsodium.com.ionspin.kotlin.crypto.toUInt8Array
|
||||
import org.khronos.webgl.Uint8Array
|
||||
|
||||
/**
|
||||
* Created by Ugljesa Jovanovic
|
||||
* ugljesa.jovanovic@ionspin.com
|
||||
* on 25-Jun-2020
|
||||
*/
|
||||
|
||||
/**
|
||||
* Created by Ugljesa Jovanovic
|
||||
* ugljesa.jovanovic@ionspin.com
|
||||
* on 14-Jun-2020
|
||||
*/
|
||||
actual class XChaCha20Poly1305Delegated internal actual constructor() {
|
||||
actual companion object {
|
||||
actual fun encrypt(
|
||||
key: UByteArray,
|
||||
nonce: UByteArray,
|
||||
message: UByteArray,
|
||||
associatedData: UByteArray
|
||||
): UByteArray {
|
||||
val encrypted = getSodium().crypto_aead_xchacha20poly1305_ietf_encrypt(
|
||||
message.toUInt8Array(),
|
||||
associatedData.toUInt8Array(),
|
||||
Uint8Array(0),
|
||||
nonce.toUInt8Array(),
|
||||
key.toUInt8Array()
|
||||
)
|
||||
return encrypted.toUByteArray()
|
||||
}
|
||||
|
||||
actual fun decrypt(
|
||||
key: UByteArray,
|
||||
nonce: UByteArray,
|
||||
ciphertext: UByteArray,
|
||||
associatedData: UByteArray
|
||||
): UByteArray {
|
||||
val decrypted = getSodium().crypto_aead_xchacha20poly1305_ietf_decrypt(
|
||||
Uint8Array(0),
|
||||
ciphertext.toUInt8Array(),
|
||||
associatedData.toUInt8Array(),
|
||||
nonce.toUInt8Array(),
|
||||
key.toUInt8Array()
|
||||
)
|
||||
return decrypted.toUByteArray()
|
||||
}
|
||||
}
|
||||
|
||||
var state : dynamic = null
|
||||
var isInitialized = false
|
||||
var isEncryptor = false
|
||||
|
||||
actual fun initializeForEncryption(key: UByteArray) : UByteArray {
|
||||
println("Initializaing for encryption")
|
||||
val stateAndHeader = getSodium().crypto_secretstream_xchacha20poly1305_init_push(key.toUInt8Array())
|
||||
state = stateAndHeader.state
|
||||
val header = stateAndHeader.header as Uint8Array
|
||||
console.log(state)
|
||||
console.log(header)
|
||||
println("Done initializaing for encryption")
|
||||
isInitialized = true
|
||||
isEncryptor = true
|
||||
return header.toUByteArray()
|
||||
}
|
||||
|
||||
actual fun initializeForDecryption(key: UByteArray, header: UByteArray) {
|
||||
println("Initializing for decryption")
|
||||
header.hexColumsPrint()
|
||||
state = getSodium().crypto_secretstream_xchacha20poly1305_init_pull(header.toUInt8Array(), key.toUInt8Array())
|
||||
console.log(state)
|
||||
isInitialized = true
|
||||
isEncryptor = false
|
||||
}
|
||||
|
||||
internal actual constructor(
|
||||
key: UByteArray,
|
||||
testState: UByteArray,
|
||||
testHeader: UByteArray,
|
||||
isDecryptor: Boolean
|
||||
) : this() {
|
||||
state = getSodium().crypto_secretstream_xchacha20poly1305_init_pull(testHeader.toUInt8Array(), key.toUInt8Array())
|
||||
console.log(state)
|
||||
println("Done initializaing test state")
|
||||
isInitialized = true
|
||||
isEncryptor = !isDecryptor
|
||||
}
|
||||
|
||||
actual fun encrypt(data: UByteArray, associatedData: UByteArray): UByteArray {
|
||||
if (!isInitialized) {
|
||||
throw RuntimeException("Not initalized!")
|
||||
}
|
||||
if (!isEncryptor) {
|
||||
throw RuntimeException("Initialized as decryptor, attempted to use as encryptor")
|
||||
}
|
||||
val encrypted = getSodium().crypto_secretstream_xchacha20poly1305_push(state, data.toUInt8Array(), associatedData.toUInt8Array(), 0U)
|
||||
return encrypted.toUByteArray()
|
||||
}
|
||||
|
||||
actual fun decrypt(data: UByteArray, associatedData: UByteArray): UByteArray {
|
||||
if (!isInitialized) {
|
||||
throw RuntimeException("Not initalized!")
|
||||
}
|
||||
if (isEncryptor) {
|
||||
throw RuntimeException("Initialized as encryptor, attempted to use as decryptor")
|
||||
}
|
||||
val decryptedWithTag = getSodium().crypto_secretstream_xchacha20poly1305_pull(state, data.toUInt8Array(), associatedData.toUInt8Array())
|
||||
val decrypted = decryptedWithTag.message as Uint8Array
|
||||
val validTag = decryptedWithTag.tag
|
||||
|
||||
if (validTag != 0U) {
|
||||
println("Tag validation failed")
|
||||
throw InvalidTagException()
|
||||
}
|
||||
return decrypted.toUByteArray()
|
||||
}
|
||||
|
||||
actual fun cleanup() {
|
||||
//TODO JS cleanup
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
@ -1,60 +0,0 @@
|
||||
package com.ionspin.kotlin.crypto.hash.blake2b
|
||||
|
||||
import com.ionspin.kotlin.crypto.getSodium
|
||||
import org.khronos.webgl.Uint8Array
|
||||
import org.khronos.webgl.get
|
||||
|
||||
/**
|
||||
* Created by Ugljesa Jovanovic
|
||||
* ugljesa.jovanovic@ionspin.com
|
||||
* on 14-Jul-2019
|
||||
*/
|
||||
|
||||
|
||||
actual class Blake2bDelegated actual constructor(key: UByteArray?, val hashLength: Int) : Blake2bMultipart {
|
||||
override val MAX_HASH_BYTES: Int = 64
|
||||
|
||||
|
||||
val state : dynamic
|
||||
|
||||
init {
|
||||
state = getSodium().crypto_generichash_init(
|
||||
Uint8Array(key?.toByteArray()?.toTypedArray() ?: arrayOf()),
|
||||
hashLength
|
||||
)
|
||||
}
|
||||
|
||||
override fun update(data: UByteArray) {
|
||||
getSodium().crypto_generichash_update(state, Uint8Array(data.toByteArray().toTypedArray()))
|
||||
}
|
||||
|
||||
override fun digest(): UByteArray {
|
||||
val hashed = getSodium().crypto_generichash_final(state, hashLength)
|
||||
val hash = UByteArray(hashLength)
|
||||
for (i in 0 until hashLength) {
|
||||
hash[i] = hashed[i].toUByte()
|
||||
}
|
||||
return hash
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
actual object Blake2bDelegatedStateless : Blake2b {
|
||||
override val MAX_HASH_BYTES: Int = 64
|
||||
|
||||
override fun digest(inputMessage: UByteArray, key: UByteArray, hashLength: Int): UByteArray {
|
||||
val hashed = getSodium().crypto_generichash(hashLength,
|
||||
Uint8Array(inputMessage.toByteArray().toTypedArray()),
|
||||
Uint8Array(key.toByteArray().toTypedArray())
|
||||
)
|
||||
val hash = UByteArray(hashLength)
|
||||
for (i in 0 until hashLength) {
|
||||
hash[i] = hashed[i].toUByte()
|
||||
}
|
||||
return hash
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
package com.ionspin.kotlin.crypto.hash.sha
|
||||
|
||||
import com.ionspin.kotlin.crypto.getSodium
|
||||
|
||||
import org.khronos.webgl.Uint8Array
|
||||
import org.khronos.webgl.get
|
||||
|
||||
/**
|
||||
* Created by Ugljesa Jovanovic
|
||||
* ugljesa.jovanovic@ionspin.com
|
||||
* on 17-Jul-2019
|
||||
*/
|
||||
|
||||
|
||||
actual class Sha256Delegated : Sha256 {
|
||||
|
||||
val state : dynamic
|
||||
|
||||
init {
|
||||
state = getSodium().crypto_hash_sha256_init()
|
||||
}
|
||||
|
||||
override fun update(data: UByteArray) {
|
||||
getSodium().crypto_hash_sha256_update(state, Uint8Array(data.toByteArray().toTypedArray()))
|
||||
}
|
||||
|
||||
override fun digest(): UByteArray {
|
||||
val hashed = getSodium().crypto_hash_sha256_final(state)
|
||||
val hash = UByteArray(Sha256StatelessDelegated.MAX_HASH_BYTES)
|
||||
console.log(hashed)
|
||||
for (i in 0 until Sha256StatelessDelegated.MAX_HASH_BYTES) {
|
||||
hash[i] = hashed[i].toUByte()
|
||||
}
|
||||
return hash
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
actual object Sha256StatelessDelegated : StatelessSha256 {
|
||||
|
||||
override fun digest(inputMessage: UByteArray): UByteArray {
|
||||
val hashed = getSodium().crypto_hash_sha256(Uint8Array(inputMessage.toByteArray().toTypedArray()))
|
||||
val hash = UByteArray(MAX_HASH_BYTES)
|
||||
for (i in 0 until MAX_HASH_BYTES) {
|
||||
hash[i] = hashed[i].toUByte()
|
||||
}
|
||||
return hash
|
||||
}
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
package com.ionspin.kotlin.crypto.hash.sha
|
||||
|
||||
import com.ionspin.kotlin.crypto.getSodium
|
||||
|
||||
import org.khronos.webgl.Uint8Array
|
||||
import org.khronos.webgl.get
|
||||
|
||||
/**
|
||||
* Created by Ugljesa Jovanovic
|
||||
* ugljesa.jovanovic@ionspin.com
|
||||
* on 17-Jul-2019
|
||||
*/
|
||||
|
||||
|
||||
actual class Sha512Delegated : Sha512Multipart {
|
||||
val state : dynamic
|
||||
|
||||
init {
|
||||
state = getSodium().crypto_hash_sha512_init()
|
||||
}
|
||||
|
||||
override fun update(data: UByteArray) {
|
||||
getSodium().crypto_hash_sha512_update(state, Uint8Array(data.toByteArray().toTypedArray()))
|
||||
}
|
||||
|
||||
override fun digest(): UByteArray {
|
||||
val hashed = getSodium().crypto_hash_sha512_final(state)
|
||||
val hash = UByteArray(Sha512StatelessDelegated.MAX_HASH_BYTES)
|
||||
for (i in 0 until Sha512StatelessDelegated.MAX_HASH_BYTES) {
|
||||
hash[i] = hashed[i].toUByte()
|
||||
}
|
||||
return hash
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
actual object Sha512StatelessDelegated : Sha512 {
|
||||
|
||||
override fun digest(inputMessage: UByteArray): UByteArray {
|
||||
val hashed = getSodium().crypto_hash_sha512(Uint8Array(inputMessage.toByteArray().toTypedArray()))
|
||||
val hash = UByteArray(Sha512StatelessDelegated.MAX_HASH_BYTES)
|
||||
for (i in 0 until Sha512StatelessDelegated.MAX_HASH_BYTES) {
|
||||
hash[i] = hashed[i].toUByte()
|
||||
}
|
||||
return hash
|
||||
}
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
@file:JsModule("libsodium-wrappers-sumo")
|
||||
@file:JsNonModule
|
||||
package ext.libsodium
|
||||
|
||||
import org.khronos.webgl.Uint8Array
|
||||
import kotlin.js.Promise
|
||||
|
||||
|
||||
/**
|
||||
* Created by Ugljesa Jovanovic
|
||||
* ugljesa.jovanovic@ionspin.com
|
||||
* on 25-May-2020
|
||||
*/
|
||||
|
||||
@JsName("ready")
|
||||
external val _libsodiumPromise : Promise<dynamic>
|
||||
|
||||
external fun crypto_generichash(hashLength: Int, inputMessage: Uint8Array) : Uint8Array
|
||||
|
||||
external fun crypto_hash_sha256(message: Uint8Array) : Uint8Array
|
||||
external fun crypto_hash_sha512(message: Uint8Array) : Uint8Array
|
||||
|
||||
external fun crypto_hash_sha256_init(): dynamic
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,52 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019 Ugljesa Jovanovic
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.ionspin.kotlin.crypto
|
||||
|
||||
import com.ionspin.kotlin.crypto.util.testBlocking
|
||||
import ext.libsodium.com.ionspin.kotlin.crypto.JsSodiumLoader
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
/**
|
||||
* Created by Ugljesa Jovanovic
|
||||
* ugljesa.jovanovic@ionspin.com
|
||||
* on 05-Jan-2020
|
||||
*/
|
||||
|
||||
class SRNGJsTest {
|
||||
|
||||
@Test
|
||||
fun testJsSrng() = testBlocking {
|
||||
JsSodiumLoader.load()
|
||||
val bytes1 = SRNG.getRandomBytes(10)
|
||||
val bytes2 = SRNG.getRandomBytes(10)
|
||||
// println("BYTES1\n")
|
||||
// bytes1.forEach {
|
||||
// print(it.toString(16).padStart(2, '0'))
|
||||
// }
|
||||
// println("BYTES2\n")
|
||||
// bytes2.forEach {
|
||||
// print(it.toString(16).padStart(2, '0'))
|
||||
// }
|
||||
assertTrue {
|
||||
!bytes1.contentEquals(bytes2) &&
|
||||
bytes1.size == 10 &&
|
||||
bytes2.size == 10
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019 Ugljesa Jovanovic
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.ionspin.kotlin.crypto.util
|
||||
//
|
||||
//import kotlinx.coroutines.GlobalScope
|
||||
//import kotlinx.coroutines.promise
|
||||
//
|
||||
//
|
||||
///**
|
||||
// * Created by Ugljesa Jovanovic
|
||||
// * ugljesa.jovanovic@ionspin.com
|
||||
// * on 20-Jul-2019
|
||||
// */
|
||||
//actual fun testBlocking(block: suspend ()-> Unit) : dynamic = GlobalScope.promise { block() }
|
@ -1,25 +0,0 @@
|
||||
package com.ionspin.kotlin.crypto
|
||||
|
||||
import com.goterl.lazycode.lazysodium.SodiumJava
|
||||
|
||||
actual object Initializer {
|
||||
private var isPlatformInitialized = false
|
||||
|
||||
lateinit var sodium : SodiumJava
|
||||
actual suspend fun initialize() {
|
||||
sodium = SodiumJava()
|
||||
isPlatformInitialized = true
|
||||
}
|
||||
|
||||
actual fun initializeWithCallback(done: () -> Unit) {
|
||||
sodium = SodiumJava()
|
||||
isPlatformInitialized = true
|
||||
done()
|
||||
}
|
||||
|
||||
actual fun isInitialized(): Boolean {
|
||||
return isPlatformInitialized
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019 Ugljesa Jovanovic
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.ionspin.kotlin.crypto
|
||||
|
||||
import java.security.SecureRandom
|
||||
|
||||
/**
|
||||
* Created by Ugljesa Jovanovic
|
||||
* ugljesa.jovanovic@ionspin.com
|
||||
* on 21-Sep-2019
|
||||
*/
|
||||
|
||||
actual object SRNG {
|
||||
val secureRandom = SecureRandom()
|
||||
actual fun getRandomBytes(amount: Int): UByteArray {
|
||||
val byteArray = ByteArray(amount)
|
||||
secureRandom.nextBytes(byteArray)
|
||||
return byteArray.asUByteArray()
|
||||
}
|
||||
}
|
@ -1,142 +0,0 @@
|
||||
package com.ionspin.kotlin.crypto.authenticated
|
||||
|
||||
import com.goterl.lazycode.lazysodium.SodiumJava
|
||||
import com.goterl.lazycode.lazysodium.interfaces.SecretStream
|
||||
import com.ionspin.kotlin.crypto.InvalidTagException
|
||||
import com.ionspin.kotlin.crypto.util.hexColumsPrint
|
||||
|
||||
/**
|
||||
* Created by Ugljesa Jovanovic
|
||||
* ugljesa.jovanovic@ionspin.com
|
||||
* on 14-Jun-2020
|
||||
*/
|
||||
actual class XChaCha20Poly1305Delegated internal actual constructor() {
|
||||
actual companion object {
|
||||
actual fun encrypt(
|
||||
key: UByteArray,
|
||||
nonce: UByteArray,
|
||||
message: UByteArray,
|
||||
associatedData: UByteArray
|
||||
): UByteArray {
|
||||
val ciphertext = ByteArray(message.size + 16)
|
||||
SodiumJava().crypto_aead_xchacha20poly1305_ietf_encrypt(
|
||||
ciphertext,
|
||||
longArrayOf(ciphertext.size.toLong()),
|
||||
message.toByteArray(),
|
||||
message.size.toLong(),
|
||||
associatedData.toByteArray(),
|
||||
associatedData.size.toLong(),
|
||||
null,
|
||||
nonce.toByteArray(),
|
||||
key.toByteArray()
|
||||
|
||||
)
|
||||
return ciphertext.asUByteArray()
|
||||
}
|
||||
|
||||
actual fun decrypt(
|
||||
key: UByteArray,
|
||||
nonce: UByteArray,
|
||||
ciphertext: UByteArray,
|
||||
associatedData: UByteArray
|
||||
): UByteArray {
|
||||
val message = ByteArray(ciphertext.size - 16)
|
||||
SodiumJava().crypto_aead_xchacha20poly1305_ietf_decrypt(
|
||||
message,
|
||||
longArrayOf(ciphertext.size.toLong()),
|
||||
null,
|
||||
ciphertext.toByteArray(),
|
||||
ciphertext.size.toLong(),
|
||||
associatedData.toByteArray(),
|
||||
associatedData.size.toLong(),
|
||||
nonce.toByteArray(),
|
||||
key.toByteArray()
|
||||
|
||||
)
|
||||
return message.asUByteArray()
|
||||
}
|
||||
}
|
||||
|
||||
val state : SecretStream.State = SecretStream.State()
|
||||
val sodium = SodiumJava()
|
||||
|
||||
var isInitialized = false
|
||||
var isEncryptor = false
|
||||
|
||||
internal actual constructor(
|
||||
key: UByteArray,
|
||||
testState: UByteArray,
|
||||
testHeader: UByteArray,
|
||||
isDecryptor: Boolean
|
||||
) : this() {
|
||||
state.k = testState.sliceArray(0 until 32).toByteArray()
|
||||
state.nonce = testState.sliceArray(32 until 44).toByteArray()
|
||||
isInitialized = true
|
||||
isEncryptor = !isDecryptor
|
||||
}
|
||||
|
||||
actual fun initializeForEncryption(key: UByteArray) : UByteArray {
|
||||
val header = UByteArray(24)
|
||||
sodium.crypto_secretstream_xchacha20poly1305_init_push(state, header.asByteArray(), key.asByteArray())
|
||||
isInitialized = true
|
||||
isEncryptor = true
|
||||
return header
|
||||
}
|
||||
|
||||
actual fun initializeForDecryption(key: UByteArray, header: UByteArray) {
|
||||
sodium.crypto_secretstream_xchacha20poly1305_init_pull(state, header.asByteArray(), key.asByteArray())
|
||||
isInitialized = true
|
||||
isEncryptor = false
|
||||
}
|
||||
|
||||
actual fun encrypt(data: UByteArray, associatedData: UByteArray): UByteArray {
|
||||
if (!isInitialized) {
|
||||
throw RuntimeException("Not initalized!")
|
||||
}
|
||||
if (!isEncryptor) {
|
||||
throw RuntimeException("Initialized as decryptor, attempted to use as encryptor")
|
||||
}
|
||||
val ciphertext = ByteArray(1 + data.size + 16)
|
||||
sodium.crypto_secretstream_xchacha20poly1305_push(
|
||||
state, ciphertext, null,
|
||||
data.asByteArray(), data.size.toLong(),
|
||||
associatedData.asByteArray(), associatedData.size.toLong(),
|
||||
0
|
||||
)
|
||||
return ciphertext.asUByteArray()
|
||||
}
|
||||
|
||||
actual fun decrypt(data: UByteArray, associatedData: UByteArray): UByteArray {
|
||||
if (!isInitialized) {
|
||||
throw RuntimeException("Not initalized!")
|
||||
}
|
||||
if (isEncryptor) {
|
||||
throw RuntimeException("Initialized as encryptor, attempted to use as decryptor")
|
||||
}
|
||||
val plaintext = ByteArray(data.size - 17)
|
||||
|
||||
val validTag = sodium.crypto_secretstream_xchacha20poly1305_pull(
|
||||
state, plaintext, null,
|
||||
null,
|
||||
data.asByteArray(),
|
||||
(data.size).toLong(),
|
||||
associatedData.asByteArray(),
|
||||
associatedData.size.toLong()
|
||||
)
|
||||
if (validTag != 0) {
|
||||
println("Tag validation failed")
|
||||
throw InvalidTagException()
|
||||
}
|
||||
return plaintext.asUByteArray()
|
||||
|
||||
}
|
||||
|
||||
actual fun cleanup() {
|
||||
sodium.sodium_memzero(state.k, 32)
|
||||
sodium.sodium_memzero(state.nonce, 12)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
package com.ionspin.kotlin.crypto.hash.blake2b
|
||||
|
||||
import com.ionspin.kotlin.crypto.Initializer.sodium
|
||||
/**
|
||||
* Created by Ugljesa Jovanovic
|
||||
* ugljesa.jovanovic@ionspin.com
|
||||
* on 14-Jul-2019
|
||||
*/
|
||||
|
||||
|
||||
actual class Blake2bDelegated actual constructor(key: UByteArray?, val hashLength: Int) : Blake2bMultipart {
|
||||
|
||||
val state = ByteArray(sodium.crypto_generichash_statebytes())
|
||||
|
||||
init {
|
||||
sodium.crypto_generichash_init(state,key?.toByteArray() ?: byteArrayOf(), key?.size ?: 0, hashLength)
|
||||
}
|
||||
|
||||
override fun update(data: UByteArray) {
|
||||
sodium.crypto_generichash_update(state, data.toByteArray(), data.size.toLong())
|
||||
}
|
||||
|
||||
override fun digest(): UByteArray {
|
||||
val hashed = ByteArray(hashLength)
|
||||
sodium.crypto_generichash_final(state, hashed, hashLength)
|
||||
return hashed.asUByteArray()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
actual object Blake2bDelegatedStateless : Blake2b {
|
||||
|
||||
|
||||
override fun digest(inputMessage: UByteArray, key: UByteArray, hashLength: Int): UByteArray {
|
||||
val hashed = ByteArray(hashLength)
|
||||
sodium.crypto_generichash(hashed, hashed.size, inputMessage.toByteArray(), inputMessage.size.toLong(), key.toByteArray(), key.size)
|
||||
return hashed.asUByteArray()
|
||||
}
|
||||
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
package com.ionspin.kotlin.crypto.hash.sha
|
||||
|
||||
import com.goterl.lazycode.lazysodium.interfaces.Hash
|
||||
import com.ionspin.kotlin.crypto.Initializer.sodium
|
||||
|
||||
|
||||
/**
|
||||
* Created by Ugljesa Jovanovic
|
||||
* ugljesa.jovanovic@ionspin.com
|
||||
* on 17-Jul-2019
|
||||
*/
|
||||
|
||||
|
||||
actual class Sha256Delegated actual constructor() : Sha256 {
|
||||
|
||||
val state = Hash.State256()
|
||||
|
||||
init {
|
||||
sodium.crypto_hash_sha256_init(state)
|
||||
}
|
||||
|
||||
override fun update(data: UByteArray) {
|
||||
sodium.crypto_hash_sha256_update(state, data.toByteArray(), data.size.toLong())
|
||||
}
|
||||
|
||||
override fun digest(): UByteArray {
|
||||
val hashed = ByteArray(Sha256Properties.MAX_HASH_BYTES)
|
||||
sodium.crypto_hash_sha256_final(state, hashed)
|
||||
return hashed.asUByteArray()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
actual object Sha256StatelessDelegated : StatelessSha256 {
|
||||
|
||||
override fun digest(inputMessage: UByteArray): UByteArray {
|
||||
val hashed = ByteArray(Sha256Properties.MAX_HASH_BYTES)
|
||||
sodium.crypto_hash_sha256(hashed, inputMessage.toByteArray(), inputMessage.size.toLong())
|
||||
return hashed.asUByteArray()
|
||||
}
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
package com.ionspin.kotlin.crypto.hash.sha
|
||||
|
||||
import com.goterl.lazycode.lazysodium.interfaces.Hash
|
||||
import com.ionspin.kotlin.crypto.Initializer
|
||||
|
||||
/**
|
||||
* Created by Ugljesa Jovanovic
|
||||
* ugljesa.jovanovic@ionspin.com
|
||||
* on 17-Jul-2019
|
||||
*/
|
||||
|
||||
|
||||
actual class Sha512Delegated : Sha512Multipart {
|
||||
|
||||
val state = Hash.State512()
|
||||
|
||||
init {
|
||||
Initializer.sodium.crypto_hash_sha512_init(state)
|
||||
}
|
||||
|
||||
override fun update(data: UByteArray) {
|
||||
Initializer.sodium.crypto_hash_sha512_update(state, data.toByteArray(), data.size.toLong())
|
||||
}
|
||||
|
||||
override fun digest(): UByteArray {
|
||||
val hashed = ByteArray(Sha512Properties.MAX_HASH_BYTES)
|
||||
Initializer.sodium.crypto_hash_sha512_final(state, hashed)
|
||||
return hashed.asUByteArray()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
actual object Sha512StatelessDelegated : Sha512 {
|
||||
|
||||
override fun digest(inputMessage: UByteArray): UByteArray {
|
||||
val hashed = ByteArray(Sha512Properties.MAX_HASH_BYTES)
|
||||
Initializer.sodium.crypto_hash_sha512(hashed, inputMessage.toByteArray(), inputMessage.size.toLong())
|
||||
return hashed.asUByteArray()
|
||||
}
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019 Ugljesa Jovanovic
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.ionspin.kotlin.crypto.util
|
||||
|
||||
import kotlin.coroutines.Continuation
|
||||
import kotlin.coroutines.EmptyCoroutineContext
|
||||
import kotlin.coroutines.startCoroutine
|
||||
|
||||
/**
|
||||
* Created by Ugljesa Jovanovic
|
||||
* ugljesa.jovanovic@ionspin.com
|
||||
* on 20-Jul-2019
|
||||
*/
|
||||
//actual fun testBlocking(block: suspend () -> Unit) {
|
||||
// val continuation = Continuation<Unit>(EmptyCoroutineContext) {
|
||||
// println("Done")
|
||||
// }
|
||||
// block.startCoroutine(continuation)
|
||||
//
|
||||
//}
|
@ -1,9 +0,0 @@
|
||||
package com.ionspin.kotlin.crypto.hash.sha
|
||||
|
||||
/**
|
||||
* Created by Ugljesa Jovanovic
|
||||
* ugljesa.jovanovic@ionspin.com
|
||||
* on 07-Jun-2020
|
||||
*/
|
||||
import platform.posix.*
|
||||
//import cin
|
@ -1,44 +0,0 @@
|
||||
//We'll handle SRNG through libsodium
|
||||
///*
|
||||
// * Copyright 2019 Ugljesa Jovanovic
|
||||
// *
|
||||
// * Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// * you may not use this file except in compliance with the License.
|
||||
// * You may obtain a copy of the License at
|
||||
// *
|
||||
// * http://www.apache.org/licenses/LICENSE-2.0
|
||||
// *
|
||||
// * Unless required by applicable law or agreed to in writing, software
|
||||
// * distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// * See the License for the specific language governing permissions and
|
||||
// * limitations under the License.
|
||||
// */
|
||||
//
|
||||
//package com.ionspin.kotlin.crypto
|
||||
//
|
||||
//import kotlinx.cinterop.*
|
||||
//import platform.windows.*
|
||||
//
|
||||
///**
|
||||
// * Created by Ugljesa Jovanovic
|
||||
// * ugljesa.jovanovic@ionspin.com
|
||||
// * on 21-Sep-2019
|
||||
// */
|
||||
//actual object SRNG {
|
||||
// private val advapi by lazy { LoadLibraryA("ADVAPI32.DLL")}
|
||||
//
|
||||
// private val advapiRandom by lazy {
|
||||
// GetProcAddress(advapi, "SystemFunction036")?.reinterpret<CFunction<Function2<CPointer<ByteVar>, ULong, Int>>>() ?: error("Failed getting advapi random")
|
||||
// }
|
||||
//
|
||||
// @Suppress("EXPERIMENTAL_UNSIGNED_LITERALS")
|
||||
// actual fun getRandomBytes(amount: Int): UByteArray {
|
||||
// memScoped {
|
||||
// val randArray = allocArray<ByteVar>(amount)
|
||||
// val pointer = randArray.getPointer(this)
|
||||
// val status = advapiRandom(pointer.reinterpret(), amount.convert())
|
||||
// return UByteArray(amount) { pointer[it].toUByte() }
|
||||
// }
|
||||
// }
|
||||
//}
|
@ -1,6 +0,0 @@
|
||||
headers = sodium.h
|
||||
headerFilter = sodium.h sodium/**
|
||||
#staticLibraries = libsodium.a
|
||||
#libraryPaths = sodiumWrapper/lib
|
||||
#compilerOpts = -I./sodiumWrapper/include
|
||||
linkerOpts =
|
@ -1,30 +0,0 @@
|
||||
@file:Suppress("VARIABLE_IN_SINGLETON_WITHOUT_THREAD_LOCAL")
|
||||
|
||||
package com.ionspin.kotlin.crypto
|
||||
|
||||
import libsodium.sodium_init
|
||||
import kotlin.native.concurrent.AtomicInt
|
||||
|
||||
actual object Initializer {
|
||||
|
||||
private var isPlatformInitialized : AtomicInt = AtomicInt(0)
|
||||
|
||||
actual suspend fun initialize() {
|
||||
if (isPlatformInitialized.compareAndSet(0, 1)) {
|
||||
sodium_init()
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
actual fun initializeWithCallback(done: () -> Unit) {
|
||||
if (isPlatformInitialized.compareAndSet(0, 1)) {
|
||||
sodium_init()
|
||||
}
|
||||
done()
|
||||
}
|
||||
|
||||
actual fun isInitialized(): Boolean {
|
||||
return isPlatformInitialized.value != 0
|
||||
}
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019 Ugljesa Jovanovic
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.ionspin.kotlin.crypto
|
||||
|
||||
import kotlinx.cinterop.*
|
||||
import libsodium.randombytes_buf
|
||||
import platform.posix.*
|
||||
//import libsod
|
||||
|
||||
/**
|
||||
* Created by Ugljesa Jovanovic
|
||||
* ugljesa.jovanovic@ionspin.com
|
||||
* on 21-Sep-2019
|
||||
*/
|
||||
actual object SRNG {
|
||||
@Suppress("EXPERIMENTAL_UNSIGNED_LITERALS")
|
||||
actual fun getRandomBytes(amount: Int): UByteArray {
|
||||
memScoped {
|
||||
val array = allocArray<UByteVar>(amount)
|
||||
randombytes_buf(array, amount.convert())
|
||||
return UByteArray(amount) {
|
||||
array[it]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,164 +0,0 @@
|
||||
package com.ionspin.kotlin.crypto.authenticated
|
||||
|
||||
import com.ionspin.kotlin.bignum.integer.util.hexColumsPrint
|
||||
import com.ionspin.kotlin.crypto.InvalidTagException
|
||||
import com.ionspin.kotlin.crypto.util.toPtr
|
||||
import kotlinx.cinterop.*
|
||||
import libsodium.*
|
||||
|
||||
/**
|
||||
* Created by Ugljesa Jovanovic
|
||||
* ugljesa.jovanovic@ionspin.com
|
||||
* on 14-Jun-2020
|
||||
*/
|
||||
actual class XChaCha20Poly1305Delegated internal actual constructor() {
|
||||
actual companion object {
|
||||
actual fun encrypt(
|
||||
key: UByteArray,
|
||||
nonce: UByteArray,
|
||||
message: UByteArray,
|
||||
associatedData: UByteArray
|
||||
): UByteArray {
|
||||
val ciphertextLength = message.size + crypto_aead_xchacha20poly1305_IETF_ABYTES.toInt()
|
||||
val ciphertext = UByteArray(ciphertextLength)
|
||||
val ciphertextPinned = ciphertext.pin()
|
||||
crypto_aead_xchacha20poly1305_ietf_encrypt(
|
||||
ciphertextPinned.toPtr(),
|
||||
ulongArrayOf(ciphertextLength.convert()).toCValues(),
|
||||
message.toCValues(),
|
||||
message.size.convert(),
|
||||
associatedData.toCValues(),
|
||||
associatedData.size.convert(),
|
||||
null,
|
||||
nonce.toCValues(),
|
||||
key.toCValues()
|
||||
)
|
||||
ciphertextPinned.unpin()
|
||||
return ciphertext
|
||||
}
|
||||
|
||||
actual fun decrypt(
|
||||
key: UByteArray,
|
||||
nonce: UByteArray,
|
||||
ciphertext: UByteArray,
|
||||
associatedData: UByteArray
|
||||
): UByteArray {
|
||||
val messageLength = ciphertext.size - crypto_aead_xchacha20poly1305_IETF_ABYTES.toInt()
|
||||
val message = UByteArray(messageLength)
|
||||
val messagePinned = message.pin()
|
||||
crypto_aead_xchacha20poly1305_ietf_decrypt(
|
||||
messagePinned.toPtr(),
|
||||
ulongArrayOf(messageLength.convert()).toCValues(),
|
||||
null,
|
||||
ciphertext.toCValues(),
|
||||
ciphertext.size.convert(),
|
||||
associatedData.toCValues(),
|
||||
associatedData.size.convert(),
|
||||
nonce.toCValues(),
|
||||
key.toCValues()
|
||||
)
|
||||
messagePinned.unpin()
|
||||
return message
|
||||
}
|
||||
}
|
||||
|
||||
var state =
|
||||
sodium_malloc(crypto_secretstream_xchacha20poly1305_state.size.convert())!!
|
||||
.reinterpret<crypto_secretstream_xchacha20poly1305_state>()
|
||||
.pointed
|
||||
val header = UByteArray(crypto_secretstream_xchacha20poly1305_HEADERBYTES.toInt()) { 0U }
|
||||
|
||||
var isInitialized = false
|
||||
var isEncryptor = false
|
||||
|
||||
actual internal constructor(
|
||||
key: UByteArray,
|
||||
testState: UByteArray,
|
||||
testHeader: UByteArray,
|
||||
isDecryptor: Boolean
|
||||
) : this() {
|
||||
val pointer = state.ptr.reinterpret<UByteVar>()
|
||||
for (i in 0 until crypto_secretstream_xchacha20poly1305_state.size.toInt()) {
|
||||
pointer[i] = testState[i]
|
||||
}
|
||||
println("state after setting-----------")
|
||||
state.ptr.readBytes(crypto_secretstream_xchacha20poly1305_state.size.toInt()).asUByteArray().hexColumsPrint()
|
||||
println("state after setting-----------")
|
||||
println("header after setting-----------")
|
||||
testHeader.copyInto(header)
|
||||
header.hexColumsPrint()
|
||||
println("header after setting-----------")
|
||||
isInitialized = true
|
||||
isEncryptor = !isDecryptor
|
||||
}
|
||||
|
||||
|
||||
|
||||
actual fun initializeForEncryption(key: UByteArray) : UByteArray {
|
||||
val pinnedHeader = header.pin()
|
||||
crypto_secretstream_xchacha20poly1305_init_push(state.ptr, pinnedHeader.toPtr(), key.toCValues())
|
||||
println("state-----------")
|
||||
state.ptr.readBytes(crypto_secretstream_xchacha20poly1305_state.size.toInt()).asUByteArray().hexColumsPrint()
|
||||
println("state-----------")
|
||||
println("--------header-----------")
|
||||
header.hexColumsPrint()
|
||||
println("--------header-----------")
|
||||
pinnedHeader.unpin()
|
||||
return header
|
||||
}
|
||||
|
||||
actual fun initializeForDecryption(key: UByteArray, header: UByteArray) {
|
||||
crypto_secretstream_xchacha20poly1305_init_pull(state.ptr, header.toCValues(), key.toCValues())
|
||||
}
|
||||
|
||||
|
||||
actual fun encrypt(data: UByteArray, associatedData: UByteArray): UByteArray {
|
||||
val ciphertextWithTag = UByteArray(data.size + crypto_secretstream_xchacha20poly1305_ABYTES.toInt())
|
||||
val ciphertextWithTagPinned = ciphertextWithTag.pin()
|
||||
crypto_secretstream_xchacha20poly1305_push(
|
||||
state.ptr,
|
||||
ciphertextWithTagPinned.toPtr(),
|
||||
null,
|
||||
data.toCValues(),
|
||||
data.size.convert(),
|
||||
associatedData.toCValues(),
|
||||
associatedData.size.convert(),
|
||||
0U,
|
||||
)
|
||||
println("Encrypt partial")
|
||||
ciphertextWithTag.hexColumsPrint()
|
||||
println("Encrypt partial end")
|
||||
ciphertextWithTagPinned.unpin()
|
||||
return ciphertextWithTag
|
||||
}
|
||||
|
||||
actual fun decrypt(data: UByteArray, associatedData: UByteArray): UByteArray {
|
||||
val plaintext = UByteArray(data.size - crypto_secretstream_xchacha20poly1305_ABYTES.toInt())
|
||||
val plaintextPinned = plaintext.pin()
|
||||
val validTag = crypto_secretstream_xchacha20poly1305_pull(
|
||||
state.ptr,
|
||||
plaintextPinned.toPtr(),
|
||||
null,
|
||||
null,
|
||||
data.toCValues(),
|
||||
data.size.convert(),
|
||||
associatedData.toCValues(),
|
||||
associatedData.size.convert()
|
||||
)
|
||||
plaintextPinned.unpin()
|
||||
println("tag: $validTag")
|
||||
if (validTag != 0) {
|
||||
println("Tag validation failed")
|
||||
throw InvalidTagException()
|
||||
}
|
||||
return plaintext
|
||||
}
|
||||
|
||||
actual fun cleanup() {
|
||||
sodium_free(state.ptr)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
@ -1,61 +0,0 @@
|
||||
package com.ionspin.kotlin.crypto.hash.blake2b
|
||||
import com.ionspin.kotlin.crypto.util.toHexString
|
||||
import com.ionspin.kotlin.crypto.util.toPtr
|
||||
import kotlinx.cinterop.*
|
||||
import libsodium.*
|
||||
import platform.posix.free
|
||||
import platform.posix.malloc
|
||||
/**
|
||||
* Created by Ugljesa Jovanovic
|
||||
* ugljesa.jovanovic@ionspin.com
|
||||
* on 14-Jul-2019
|
||||
*/
|
||||
|
||||
|
||||
actual class Blake2bDelegated actual constructor(key: UByteArray?, hashLength: Int) : Blake2bMultipart {
|
||||
override val MAX_HASH_BYTES: Int = 64
|
||||
|
||||
val requestedHashLength : Int
|
||||
val state : crypto_generichash_state
|
||||
init {
|
||||
requestedHashLength = hashLength
|
||||
val allocated = malloc(crypto_generichash_state.size.convert())!!
|
||||
state = allocated.reinterpret<crypto_generichash_state>().pointed
|
||||
crypto_generichash_init(state.ptr, key?.run { this.toCValues() }, key?.size?.convert() ?: 0UL.convert(), hashLength.convert())
|
||||
}
|
||||
|
||||
override fun update(data: UByteArray) {
|
||||
crypto_generichash_update(state.ptr, data.toCValues(), data.size.convert())
|
||||
}
|
||||
|
||||
override fun digest(): UByteArray {
|
||||
val hashResult = UByteArray(requestedHashLength)
|
||||
val hashResultPinned = hashResult.pin()
|
||||
crypto_generichash_final(state.ptr, hashResultPinned.toPtr(), requestedHashLength.convert())
|
||||
free(state.ptr)
|
||||
return hashResult
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Suppress("EXPERIMENTAL_API_USAGE", "EXPERIMENTAL_UNSIGNED_LITERALS")
|
||||
actual object Blake2bDelegatedStateless : Blake2b {
|
||||
|
||||
override fun digest(inputMessage: UByteArray, key: UByteArray, hashLength: Int): UByteArray {
|
||||
val hashResult = UByteArray(MAX_HASH_BYTES)
|
||||
val hashResultPinned = hashResult.pin()
|
||||
crypto_generichash(
|
||||
hashResultPinned.toPtr(),
|
||||
hashLength.convert(),
|
||||
inputMessage.toCValues(),
|
||||
inputMessage.size.convert(),
|
||||
key.toCValues(),
|
||||
key.size.convert()
|
||||
)
|
||||
hashResultPinned.unpin()
|
||||
return hashResult
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -1,55 +0,0 @@
|
||||
package com.ionspin.kotlin.crypto.hash.sha
|
||||
|
||||
import com.ionspin.kotlin.crypto.hash.blake2b.Blake2bDelegatedStateless
|
||||
import com.ionspin.kotlin.crypto.util.toPtr
|
||||
import kotlinx.cinterop.*
|
||||
import libsodium.*
|
||||
import platform.posix.free
|
||||
import platform.posix.malloc
|
||||
|
||||
/**
|
||||
* Created by Ugljesa Jovanovic
|
||||
* ugljesa.jovanovic@ionspin.com
|
||||
* on 17-Jul-2019
|
||||
*/
|
||||
|
||||
|
||||
actual class Sha256Delegated : Sha256 {
|
||||
|
||||
val state : crypto_hash_sha256_state
|
||||
|
||||
init {
|
||||
val allocated = sodium_malloc(crypto_hash_sha256_state.size.convert())!!
|
||||
state = allocated.reinterpret<crypto_hash_sha256_state>().pointed
|
||||
crypto_hash_sha256_init(state.ptr)
|
||||
}
|
||||
|
||||
override fun update(data: UByteArray) {
|
||||
crypto_hash_sha256_update(state.ptr, data.toCValues(), data.size.convert())
|
||||
}
|
||||
|
||||
|
||||
|
||||
override fun digest(): UByteArray {
|
||||
val hashResult = UByteArray(Sha256Properties.MAX_HASH_BYTES)
|
||||
val hashResultPinned = hashResult.pin()
|
||||
crypto_hash_sha256_final(state.ptr, hashResultPinned.toPtr())
|
||||
sodium_free(state.ptr)
|
||||
return hashResult
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
actual object Sha256StatelessDelegated : StatelessSha256 {
|
||||
|
||||
override fun digest(inputMessage: UByteArray): UByteArray {
|
||||
val hashResult = UByteArray(MAX_HASH_BYTES)
|
||||
val hashResultPinned = hashResult.pin()
|
||||
crypto_hash_sha256(hashResultPinned.toPtr(), inputMessage.toCValues(), inputMessage.size.convert())
|
||||
hashResultPinned.unpin()
|
||||
return hashResult
|
||||
}
|
||||
|
||||
}
|
@ -1,50 +0,0 @@
|
||||
package com.ionspin.kotlin.crypto.hash.sha
|
||||
|
||||
import com.ionspin.kotlin.crypto.util.toPtr
|
||||
import kotlinx.cinterop.*
|
||||
import libsodium.*
|
||||
import platform.posix.free
|
||||
import platform.posix.malloc
|
||||
|
||||
/**
|
||||
* Created by Ugljesa Jovanovic
|
||||
* ugljesa.jovanovic@ionspin.com
|
||||
* on 17-Jul-2019
|
||||
*/
|
||||
|
||||
|
||||
actual class Sha512Delegated : Sha512Multipart {
|
||||
val state : crypto_hash_sha512_state
|
||||
|
||||
init {
|
||||
val allocated = malloc(crypto_hash_sha512_state.size.convert())!!
|
||||
state = allocated.reinterpret<crypto_hash_sha512_state>().pointed
|
||||
crypto_hash_sha512_init(state.ptr)
|
||||
}
|
||||
|
||||
override fun update(data: UByteArray) {
|
||||
crypto_hash_sha512_update(state.ptr, data.toCValues(), data.size.convert())
|
||||
}
|
||||
|
||||
|
||||
|
||||
override fun digest(): UByteArray {
|
||||
val hashResult = UByteArray(Sha512Properties.MAX_HASH_BYTES)
|
||||
val hashResultPinned = hashResult.pin()
|
||||
crypto_hash_sha512_final(state.ptr, hashResultPinned.toPtr())
|
||||
free(state.ptr)
|
||||
return hashResult
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
actual object Sha512StatelessDelegated : Sha512 {
|
||||
|
||||
override fun digest(inputMessage: UByteArray): UByteArray {
|
||||
val hashResult = UByteArray(Sha512StatelessDelegated.MAX_HASH_BYTES)
|
||||
val hashResultPinned = hashResult.pin()
|
||||
crypto_hash_sha512(hashResultPinned.toPtr(), inputMessage.toCValues(), inputMessage.size.convert())
|
||||
hashResultPinned.unpin()
|
||||
return hashResult
|
||||
}
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
package com.ionspin.kotlin.crypto.util
|
||||
|
||||
import kotlinx.cinterop.CPointer
|
||||
import kotlinx.cinterop.Pinned
|
||||
import kotlinx.cinterop.UByteVar
|
||||
import kotlinx.cinterop.addressOf
|
||||
|
||||
/**
|
||||
* Created by Ugljesa Jovanovic
|
||||
* ugljesa.jovanovic@ionspin.com
|
||||
* on 27-Aug-2020
|
||||
*/
|
||||
fun Pinned<UByteArray>.toPtr() : CPointer<UByteVar> = addressOf(0)
|
@ -1,77 +0,0 @@
|
||||
package com.ionspin.kotlin.crypto
|
||||
|
||||
import com.ionspin.kotlin.crypto.hash.encodeToUByteArray
|
||||
import com.ionspin.kotlin.crypto.util.toHexString
|
||||
import com.ionspin.kotlin.crypto.util.toPtr
|
||||
import kotlinx.cinterop.*
|
||||
import libsodium.*
|
||||
import platform.posix.free
|
||||
import platform.posix.malloc
|
||||
import kotlin.test.Ignore
|
||||
import kotlin.test.Test
|
||||
|
||||
/**
|
||||
* Created by Ugljesa Jovanovic
|
||||
* ugljesa.jovanovic@ionspin.com
|
||||
* on 13-Jul-2020
|
||||
*/
|
||||
class HelperTest {
|
||||
@Ignore //Just used for debugging pure implementation
|
||||
@Test
|
||||
fun longSha256() {
|
||||
for (target in 0L until 10L) {
|
||||
generateForRounds256(target)
|
||||
}
|
||||
for (target in 0L until 16_777_216L step 1_000_000L) {
|
||||
generateForRounds256(target)
|
||||
}
|
||||
generateForRounds256(16_777_216L)
|
||||
}
|
||||
|
||||
fun generateForRounds256(target: Long) {
|
||||
val updateValue =
|
||||
"abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmno".encodeToUByteArray().toCValues()
|
||||
val state = malloc(crypto_hash_sha256_state.size.convert())!!
|
||||
.reinterpret<crypto_hash_sha256_state>()
|
||||
|
||||
crypto_hash_sha256_init(state)
|
||||
for (i in 0 until target) {
|
||||
crypto_hash_sha256_update(state, updateValue, updateValue.size.convert())
|
||||
}
|
||||
val result = UByteArray(32)
|
||||
val resultPinned = result.pin()
|
||||
crypto_hash_sha256_final(state, resultPinned.toPtr())
|
||||
println("$target to \"${result.toHexString()}\",")
|
||||
free(state)
|
||||
}
|
||||
@Ignore //Just used for debugging pure implementation
|
||||
@Test
|
||||
fun longSha512() {
|
||||
|
||||
for (target in 0L until 10L) {
|
||||
generateForRounds512(target)
|
||||
}
|
||||
for (target in 0L until 16_777_216L step 1_000_000L) {
|
||||
generateForRounds512(target)
|
||||
}
|
||||
generateForRounds512(16_777_216L)
|
||||
}
|
||||
|
||||
fun generateForRounds512(target: Long) {
|
||||
println("Wut")
|
||||
val updateValue =
|
||||
"abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmno".encodeToUByteArray().toCValues()
|
||||
val state = malloc(crypto_hash_sha512_state.size.convert())!!
|
||||
.reinterpret<crypto_hash_sha512_state>()
|
||||
|
||||
crypto_hash_sha512_init(state)
|
||||
for (i in 0 until target) {
|
||||
crypto_hash_sha512_update(state, updateValue, updateValue.size.convert())
|
||||
}
|
||||
val result = UByteArray(32)
|
||||
val resultPinned = result.pin()
|
||||
crypto_hash_sha512_final(state, resultPinned.toPtr())
|
||||
println("$target to \"${result.toHexString()}\",")
|
||||
free(state)
|
||||
}
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019 Ugljesa Jovanovic
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
//package com.ionspin.kotlin.crypto.util
|
||||
//
|
||||
//import kotlinx.coroutines.CoroutineScope
|
||||
//import kotlinx.coroutines.runBlocking
|
||||
//
|
||||
///**
|
||||
// * Created by Ugljesa Jovanovic
|
||||
// * ugljesa.jovanovic@ionspin.com
|
||||
// * on 20-Jul-2019
|
||||
// */
|
||||
//actual fun testBlocking(block: suspend () -> Unit) = runBlocking { block() }
|
@ -20,6 +20,8 @@
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
|
||||
import org.jetbrains.kotlin.gradle.targets.js.testing.KotlinJsTest
|
||||
import org.jetbrains.kotlin.gradle.targets.native.tasks.KotlinNativeTest
|
||||
import org.gradle.api.tasks.testing.logging.TestExceptionFormat
|
||||
import org.jetbrains.dokka.Platform
|
||||
|
||||
plugins {
|
||||
kotlin(PluginsDeps.multiplatform)
|
||||
@ -593,18 +595,43 @@ tasks {
|
||||
dokkaJavadoc {
|
||||
println("Dokka !")
|
||||
dokkaSourceSets {
|
||||
create("commonMain") {
|
||||
displayName = "common"
|
||||
platform = "common"
|
||||
named("commonMain") {
|
||||
displayName.set("common")
|
||||
platform.set(Platform.common)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
dokkaHtml {
|
||||
println("Dokka Html!")
|
||||
dokkaSourceSets {
|
||||
named("commonMain") {
|
||||
// displayName.set("common")
|
||||
// platform.set(Platform.common)
|
||||
moduleDisplayName.set("Kotlin Multiplatform Libsodium Bindings")
|
||||
includes.from(
|
||||
"src/commonMain/kotlin/com.ionspin.kotlin.crypto/aead/Aead.md",
|
||||
"src/commonMain/kotlin/com.ionspin.kotlin.crypto/auth/Auth.md",
|
||||
"src/commonMain/kotlin/com.ionspin.kotlin.crypto/box/Box.md",
|
||||
"src/commonMain/kotlin/com.ionspin.kotlin.crypto/CryptoModule.md")
|
||||
displayName.set("Kotlin multiplatform")
|
||||
}
|
||||
configureEach {
|
||||
if (name != "commonMain") {
|
||||
suppress.set(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (getHostOsName() == "linux" && getHostArchitecture() == "x86-64") {
|
||||
val jvmTest by getting(Test::class) {
|
||||
testLogging {
|
||||
events("PASSED", "FAILED", "SKIPPED")
|
||||
exceptionFormat = TestExceptionFormat.FULL
|
||||
showStandardStreams = true
|
||||
showStackTraces = true
|
||||
}
|
||||
}
|
||||
|
||||
@ -612,14 +639,18 @@ tasks {
|
||||
|
||||
testLogging {
|
||||
events("PASSED", "FAILED", "SKIPPED")
|
||||
exceptionFormat = TestExceptionFormat.FULL
|
||||
showStandardStreams = true
|
||||
showStackTraces = true
|
||||
}
|
||||
}
|
||||
|
||||
val jsNodeTest by getting(KotlinJsTest::class) {
|
||||
testLogging {
|
||||
events("PASSED", "FAILED", "SKIPPED")
|
||||
// showStandardStreams = true
|
||||
exceptionFormat = TestExceptionFormat.FULL
|
||||
showStandardStreams = true
|
||||
showStackTraces = true
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,10 @@
|
||||
# Module Kotlin Multiplatform Libsodium Bindings
|
||||
|
||||
### What
|
||||
Kotlin Multiplatform Libsodium Bindings is a library providing kotlin idiomatic API to libsodium implementations on various platforms
|
||||
|
||||
### Why
|
||||
To provide easy to use cryptographic library, based on a well-known and audited libsodium library. T
|
||||
### How
|
||||
By using built from source libsodium to provide native implementations, LazySodium (JNA wrapper around libsodium) to provide
|
||||
JVM and Android implementations and libsodium.js to provide node and browser implementation
|
@ -0,0 +1,28 @@
|
||||
# Package com.ionspin.kotlin.crypto.aead
|
||||
|
||||
## Authenticated encryption with associated data
|
||||
|
||||
This is a form of symmetric encryption, that assures both confidentiality and authenticity of the data to be encrypted as well
|
||||
as associated data that will not be encrypted.
|
||||
|
||||
In general, it works like this:
|
||||
|
||||
Inputs:
|
||||
- Message to encrypt and authenticate
|
||||
- Key to use for encryption
|
||||
- **Unique** nonce
|
||||
- Additional data that is not encrypted but also authenticated
|
||||
|
||||
Simplified encryption algorithm:
|
||||
1. Encrypt a message with key and nonce
|
||||
1. Apply MAC algorithm to encrypted message + unencrypted associated data to generate authentication data (tag)
|
||||
1. Send the encrypted data + associated data + authentication data + nonce
|
||||
|
||||
Simplified decryption algorithm:
|
||||
1. Apply MAC algorithm to encrypted message + unencrypted associated data to generate authentication data
|
||||
1. If the generated authenticated data, and the received authentication data match, proceed, otherwise sound the alarm and stop.
|
||||
1. Decrypt the encrypted data
|
||||
1. Return the decrypted data and associated data to the user
|
||||
|
||||
|
||||
|
@ -22,13 +22,52 @@ val crypto_aead_chacha20poly1305_KEYBYTES = 32
|
||||
val crypto_aead_chacha20poly1305_NPUBBYTES = 8
|
||||
val crypto_aead_chacha20poly1305_ABYTES = 16
|
||||
|
||||
|
||||
/**
|
||||
* A data class wrapping returned encrypted data and and tag from aead encrypt functions.
|
||||
*/
|
||||
data class AeadEncryptedDataAndTag(val data: UByteArray, val tag: UByteArray)
|
||||
|
||||
class AeadCorrupedOrTamperedDataException() : RuntimeException("MAC validation failed. Data is corrupted or tampered with.")
|
||||
/**
|
||||
* An exception thrown when tag generated from received data and key doesn't match the received tag
|
||||
*/
|
||||
class AeadCorrupedOrTamperedDataException() :
|
||||
RuntimeException("Tag (authentication data) validation failed. Data is corrupted or tampered with.")
|
||||
|
||||
/**
|
||||
* This is a form of symmetric encryption, that assures both confidentiality and authenticity of the data to be encrypted as well
|
||||
as associated data that will not be encrypted.
|
||||
*
|
||||
* Offered here are three implementations of (x)ChaCha20-Poly1305 construction:
|
||||
* - ChaCha20Poly1305 - uses 64bit nonce, safe to encrypt
|
||||
* - ChaCha20Poly1305-IETF - uses 96bit nonce (standardised by [RFC8439](https://tools.ietf.org/html/rfc8439)
|
||||
* - XChaCha20Poly1305 - uses 192bit nonce - recommended choice
|
||||
*
|
||||
* The only difference is the size of the nonce, and how is the nonce used.
|
||||
*
|
||||
* (x)ChaCha20 is a streaming cipher develop by Daniel J. Bernstein. He is also the author of Poly1305 a fast Message
|
||||
* Authentication Code system
|
||||
*
|
||||
* Libsodium offers two additional variants for each of the aforementioned variants:
|
||||
* - Combined
|
||||
* - Detached
|
||||
*
|
||||
* Combined mode returns encrypted data and tag as one UByteArray, while detached mode returns them as separate UByteArrays.
|
||||
* To be kotlin idiomatic we are returning detached tag and encrypted data inside a wrapper data class [AeadEncryptedDataAndTag]
|
||||
*
|
||||
* Also provided are key generation convenience functions for each variant. (Which is in practice the same, since the keys
|
||||
* same length for each variant)
|
||||
*/
|
||||
expect object AuthenticatedEncryptionWithAssociatedData {
|
||||
// X - Ietf
|
||||
/**
|
||||
* Encrypt the message and return encrypted data and tag using xChaChaPoly1305 (192 bit nonce)
|
||||
*
|
||||
* @param message message to encrypt
|
||||
* @param associatedData associated data the won't be encrypted, but will be authenticated
|
||||
* @param nonce a **unique** nonce
|
||||
* @param key secret key
|
||||
* @return encrypted data and tag (in that order)
|
||||
*/
|
||||
fun xChaCha20Poly1305IetfEncrypt(
|
||||
message: UByteArray,
|
||||
associatedData: UByteArray,
|
||||
@ -36,13 +75,34 @@ expect object AuthenticatedEncryptionWithAssociatedData {
|
||||
key: UByteArray
|
||||
): UByteArray
|
||||
|
||||
/**
|
||||
* Check if authentication data (tag) is correct, then decrypt the message and return decrypted data.
|
||||
* Using xChaChaPoly1305 (192 bit nonce)
|
||||
*
|
||||
* @param ciphertextAndTag message to decrypt
|
||||
* @param associatedData associated data the won't be encrypted, but will be authenticated
|
||||
* @param nonce a nonce used to encrypt the message
|
||||
* @param key secret key
|
||||
* @return decrypted data
|
||||
* @throws AeadCorrupedOrTamperedDataException if authentication data (tag) cannot be verified
|
||||
*/
|
||||
fun xChaCha20Poly1305IetfDecrypt(
|
||||
ciphertext: UByteArray,
|
||||
ciphertextAndTag: UByteArray,
|
||||
associatedData: UByteArray,
|
||||
nonce: UByteArray,
|
||||
key: UByteArray
|
||||
): UByteArray
|
||||
|
||||
/**
|
||||
* Encrypt the message and return encrypted data and tag using xChaChaPoly1305 (192 bit nonce) as
|
||||
* separate arrays (but wrapped inside [AeadEncryptedDataAndTag])
|
||||
*
|
||||
* @param message message to encrypt
|
||||
* @param associatedData associated data the won't be encrypted, but will be authenticated
|
||||
* @param nonce a **unique** nonce
|
||||
* @param key secret key
|
||||
* @return encrypted data and tag wrapped inside [AeadEncryptedDataAndTag] data class instance
|
||||
*/
|
||||
fun xChaCha20Poly1305IetfEncryptDetached(
|
||||
message: UByteArray,
|
||||
associatedData: UByteArray,
|
||||
@ -50,6 +110,18 @@ expect object AuthenticatedEncryptionWithAssociatedData {
|
||||
key: UByteArray
|
||||
): AeadEncryptedDataAndTag
|
||||
|
||||
/**
|
||||
* Check if authentication data (tag) is correct, then decrypt the message and return decrypted data.
|
||||
* Using xChaChaPoly1305 (192 bit nonce)
|
||||
*
|
||||
* @param ciphertext message to decrypt
|
||||
* @param tag authenticatoin data (tag)
|
||||
* @param associatedData associated data the won't be encrypted, but will be authenticated
|
||||
* @param nonce a nonce used to encrypt the message
|
||||
* @param key secret key
|
||||
* @return decrypted data
|
||||
* @throws AeadCorrupedOrTamperedDataException if authentication data (tag) cannot be verified
|
||||
*/
|
||||
fun xChaCha20Poly1305IetfDecryptDetached(
|
||||
ciphertext: UByteArray,
|
||||
tag: UByteArray,
|
||||
@ -59,21 +131,48 @@ expect object AuthenticatedEncryptionWithAssociatedData {
|
||||
): UByteArray
|
||||
|
||||
// Ietf
|
||||
|
||||
/**
|
||||
* Encrypt the message and return encrypted data and tag using ChaChaPoly1305-IETF (96 bit nonce)
|
||||
*
|
||||
* @param message message to encrypt
|
||||
* @param associatedData associated data the won't be encrypted, but will be authenticated
|
||||
* @param nonce a **unique** nonce
|
||||
* @param key secret key
|
||||
* @return encrypted data and tag (in that order)
|
||||
*/
|
||||
fun chaCha20Poly1305IetfEncrypt(
|
||||
message: UByteArray,
|
||||
associatedData: UByteArray,
|
||||
nonce: UByteArray,
|
||||
key: UByteArray
|
||||
): UByteArray
|
||||
|
||||
/**
|
||||
* Check if authentication data (tag) is correct, then decrypt the message and return decrypted data.
|
||||
* Using ChaChaPoly1305-IETF (96 bit nonce)
|
||||
*
|
||||
* @param ciphertextAndTag message to decrypt
|
||||
* @param associatedData associated data the won't be encrypted, but will be authenticated
|
||||
* @param nonce a nonce used to encrypt the message
|
||||
* @param key secret key
|
||||
* @return decrypted data
|
||||
* @throws AeadCorrupedOrTamperedDataException if authentication data (tag) cannot be verified
|
||||
*/
|
||||
fun chaCha20Poly1305IetfDecrypt(
|
||||
ciphertext: UByteArray,
|
||||
ciphertextAndTag: UByteArray,
|
||||
associatedData: UByteArray,
|
||||
nonce: UByteArray,
|
||||
key: UByteArray
|
||||
): UByteArray
|
||||
|
||||
/**
|
||||
* Encrypt the message and return encrypted data and tag using ChaChaPoly1305-IETF (96 bit nonce) as
|
||||
* separate arrays (but wrapped inside [AeadEncryptedDataAndTag])
|
||||
*
|
||||
* @param message message to encrypt
|
||||
* @param associatedData associated data the won't be encrypted, but will be authenticated
|
||||
* @param nonce a **unique** nonce
|
||||
* @param key secret key
|
||||
* @return encrypted data and tag wrapped inside [AeadEncryptedDataAndTag] data class instance
|
||||
*/
|
||||
fun chaCha20Poly1305IetfEncryptDetached(
|
||||
message: UByteArray,
|
||||
associatedData: UByteArray,
|
||||
@ -81,6 +180,18 @@ expect object AuthenticatedEncryptionWithAssociatedData {
|
||||
key: UByteArray
|
||||
): AeadEncryptedDataAndTag
|
||||
|
||||
/**
|
||||
* Check if authentication data (tag) is correct, then decrypt the message and return decrypted data.
|
||||
* Using xChaChaPoly1305 (96 bit nonce)
|
||||
*
|
||||
* @param ciphertext message to decrypt
|
||||
* @param tag authenticatoin data (tag)
|
||||
* @param associatedData associated data the won't be encrypted, but will be authenticated
|
||||
* @param nonce a nonce used to encrypt the message
|
||||
* @param key secret key
|
||||
* @return decrypted data
|
||||
* @throws AeadCorrupedOrTamperedDataException if authentication data (tag) cannot be verified
|
||||
*/
|
||||
fun chaCha20Poly1305IetfDecryptDetached(
|
||||
ciphertext: UByteArray,
|
||||
tag: UByteArray,
|
||||
@ -90,28 +201,66 @@ expect object AuthenticatedEncryptionWithAssociatedData {
|
||||
): UByteArray
|
||||
|
||||
// Original chacha20poly1305
|
||||
|
||||
/**
|
||||
* Encrypt the message and return encrypted data and tag using ChaChaPoly1305 (64 bit nonce)
|
||||
*
|
||||
* @param message message to encrypt
|
||||
* @param associatedData associated data the won't be encrypted, but will be authenticated
|
||||
* @param nonce a **unique** nonce
|
||||
* @param key secret key
|
||||
* @return encrypted data and tag (in that order)
|
||||
*/
|
||||
fun chaCha20Poly1305Encrypt(
|
||||
message: UByteArray,
|
||||
associatedData: UByteArray,
|
||||
nonce: UByteArray,
|
||||
key: UByteArray
|
||||
): UByteArray
|
||||
|
||||
/**
|
||||
* Check if authentication data (tag) is correct, then decrypt the message and return decrypted data.
|
||||
* Using ChaChaPoly1305 (64 bit nonce)
|
||||
*
|
||||
* @param ciphertextAndTag message to decrypt
|
||||
* @param associatedData associated data the won't be encrypted, but will be authenticated
|
||||
* @param nonce a nonce used to encrypt the message
|
||||
* @param key secret key
|
||||
* @return decrypted data
|
||||
* @throws AeadCorrupedOrTamperedDataException if authentication data (tag) cannot be verified
|
||||
*/
|
||||
fun chaCha20Poly1305Decrypt(
|
||||
ciphertext: UByteArray,
|
||||
ciphertextAndTag: UByteArray,
|
||||
associatedData: UByteArray,
|
||||
nonce: UByteArray,
|
||||
key: UByteArray
|
||||
): UByteArray
|
||||
|
||||
/**
|
||||
* Encrypt the message and return encrypted data and tag using ChaChaPoly1305 (64 bit nonce) as
|
||||
* separate arrays (but wrapped inside [AeadEncryptedDataAndTag])
|
||||
*
|
||||
* @param message message to encrypt
|
||||
* @param associatedData associated data the won't be encrypted, but will be authenticated
|
||||
* @param nonce a **unique** nonce
|
||||
* @param key secret key
|
||||
* @return encrypted data and tag wrapped inside [AeadEncryptedDataAndTag] data class instance
|
||||
*/
|
||||
fun chaCha20Poly1305EncryptDetached(
|
||||
message: UByteArray,
|
||||
associatedData: UByteArray,
|
||||
nonce: UByteArray,
|
||||
key: UByteArray
|
||||
): AeadEncryptedDataAndTag
|
||||
|
||||
/**
|
||||
* Check if authentication data (tag) is correct, then decrypt the message and return decrypted data.
|
||||
* Using xChaChaPoly1305 (64 bit nonce)
|
||||
*
|
||||
* @param ciphertext message to decrypt
|
||||
* @param tag authenticatoin data (tag)
|
||||
* @param associatedData associated data the won't be encrypted, but will be authenticated
|
||||
* @param nonce a nonce used to encrypt the message
|
||||
* @param key secret key
|
||||
* @return decrypted data
|
||||
* @throws AeadCorrupedOrTamperedDataException if authentication data (tag) cannot be verified
|
||||
*/
|
||||
fun chaCha20Poly1305DecryptDetached(
|
||||
ciphertext: UByteArray,
|
||||
tag: UByteArray,
|
||||
@ -120,9 +269,20 @@ expect object AuthenticatedEncryptionWithAssociatedData {
|
||||
key: UByteArray
|
||||
): UByteArray
|
||||
|
||||
|
||||
fun xChaCha20Poly1305IetfKeygen() : UByteArray
|
||||
fun chaCha20Poly1305IetfKeygen() : UByteArray
|
||||
fun chaCha20Poly1305Keygen() : UByteArray
|
||||
/**
|
||||
* Generate a random 32byte key for use with xChaCha20Poly1305
|
||||
* @return secret key
|
||||
*/
|
||||
fun xChaCha20Poly1305IetfKeygen(): UByteArray
|
||||
/**
|
||||
* Generate a random 32 byte key for use with ChaCha20Poly1305-IETF
|
||||
* @return secret key
|
||||
*/
|
||||
fun chaCha20Poly1305IetfKeygen(): UByteArray
|
||||
/**
|
||||
* Generate a random 32 byte key for use with ChaCha20Poly1305
|
||||
* @return secret key
|
||||
*/
|
||||
fun chaCha20Poly1305Keygen(): UByteArray
|
||||
|
||||
}
|
||||
|
@ -19,18 +19,60 @@ val crypto_auth_hmacsha256_BYTES = 32
|
||||
val crypto_auth_hmacsha512_KEYBYTES = 32
|
||||
val crypto_auth_hmacsha512_BYTES = 64
|
||||
|
||||
/**
|
||||
* Authentication is a process of generating authentication data (tag) for a certain message. Its purpose is to assure
|
||||
* that the data hasn't been corrupted or tampered with during the transport.
|
||||
*
|
||||
* We support 3 variants:
|
||||
* - without suffix - HMAC-SHA512-256 (HMAC SHA512 with just the first 256 bits used)
|
||||
* - *HmacSha256 - HMAC-SHA256
|
||||
* - *HmacSha512 - HMAC-SHA512
|
||||
*
|
||||
* Each variant supports three operations:
|
||||
* - keygen - generate appropriate key for MAC function
|
||||
* - auth - generate the authentication data (tag/mac)
|
||||
* - verify - verify that the authenticatoin data (tag/mac) is correct
|
||||
*/
|
||||
expect object Auth {
|
||||
|
||||
/**
|
||||
* Generate a secret key, meant to be used with auth function.
|
||||
*/
|
||||
fun authKeygen() : UByteArray
|
||||
|
||||
/**
|
||||
* Generate a HMAC-SHA512-256 authentication data - Message Authentication Code - tag
|
||||
*/
|
||||
fun auth(message: UByteArray, key: UByteArray) : UByteArray
|
||||
fun authVerify(mac: UByteArray, message: UByteArray, key: UByteArray) : Boolean
|
||||
|
||||
/**
|
||||
* Verify that given message, secret key and tag, a newly calculated tag matches the received HMAC-SHA512-256 tag.
|
||||
*/
|
||||
fun authVerify(tag: UByteArray, message: UByteArray, key: UByteArray) : Boolean
|
||||
|
||||
/**
|
||||
* Generate a secret key, meant to be used with auth function.
|
||||
*/
|
||||
fun authHmacSha256Keygen() : UByteArray
|
||||
/**
|
||||
* Generate a HMAC-SHA256 authentication data - Message Authentication Code - tag
|
||||
*/
|
||||
fun authHmacSha256(message: UByteArray, key: UByteArray) : UByteArray
|
||||
fun authHmacSha256Verify(mac: UByteArray, message: UByteArray, key: UByteArray) : Boolean
|
||||
/**
|
||||
* Verify that given message, secret key and tag, a newly calculated tag matches the received HMAC-SHA256 tag.
|
||||
*/
|
||||
fun authHmacSha256Verify(tag: UByteArray, message: UByteArray, key: UByteArray) : Boolean
|
||||
|
||||
/**
|
||||
* Generate a secret key, meant to be used with auth function.
|
||||
*/
|
||||
fun authHmacSha512Keygen() : UByteArray
|
||||
/**
|
||||
* Generate a HMAC-SHA512 authentication data - Message Authentication Code - tag
|
||||
*/
|
||||
fun authHmacSha512(message: UByteArray, key: UByteArray) : UByteArray
|
||||
fun authHmacSha512Verify(mac: UByteArray, message: UByteArray, key: UByteArray) : Boolean
|
||||
/**
|
||||
* Verify that given message, secret key and tag, a newly calculated tag matches the received HMAC-SHA512 tag.
|
||||
*/
|
||||
fun authHmacSha512Verify(tag: UByteArray, message: UByteArray, key: UByteArray) : Boolean
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,21 @@
|
||||
# Package com.ionspin.kotlin.crypto.auth
|
||||
|
||||
## Authentication
|
||||
|
||||
Authentication is a process of generating authentication data (tag) for a certain message. Its purpose is to assure
|
||||
that the data hasn't been corrupted or tampered with during the transport.
|
||||
|
||||
In general, it works like this:
|
||||
|
||||
Inputs:
|
||||
- Message to authenticate
|
||||
- Key to use for authentication
|
||||
|
||||
Sending side algorithm:
|
||||
1. Apply MAC to message
|
||||
1. Send the message + authentication data (tag)
|
||||
|
||||
Receiving side:
|
||||
1. Apply the MAC to the received message
|
||||
1. If the generated authenticated data (tag), and the received authentication data (received tag) match, proceed, otherwise sound the alarm and stop.
|
||||
1. Return the message to the user
|
@ -19,6 +19,9 @@ data class BoxEncryptedDataAndTag(val ciphertext: UByteArray, val tag: UByteArra
|
||||
|
||||
class BoxCorruptedOrTamperedDataException() : RuntimeException("MAC validation failed. Data is corrupted or tampered with.")
|
||||
|
||||
/**
|
||||
* Box API uses public-key (asymmetric) encryption to
|
||||
*/
|
||||
expect object Box {
|
||||
/**
|
||||
* The crypto_box_keypair() function randomly generates a secret key and a corresponding public key.
|
||||
@ -87,4 +90,4 @@ expect object Box {
|
||||
|
||||
fun sealOpen(ciphertext: UByteArray, recipientsPublicKey: UByteArray, recipientsSecretKey: UByteArray) : UByteArray
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,31 @@
|
||||
# Package com.ionspin.kotlin.crypto.box
|
||||
|
||||
## Box API - Asymmetric/Public-key authenticated encryption
|
||||
|
||||
Public key encryption is a system that relies on a pair of keys to establish secure communication.
|
||||
|
||||
A simplified overview of communication between Bob and Alice using public-key encryption:
|
||||
#### Key exchange
|
||||
1. Alice creates 2 keys, one public, one private (public key is actually calculated from the private key)
|
||||
1. Bob creates 2 keys, one public, one private
|
||||
1. Alice sends her **public** key to Bob
|
||||
1. Bob does the same and sends his **public** key to Alice
|
||||
|
||||
#### Encryption
|
||||
|
||||
Alice wants to establish a secure communication channel with Bob, they already exchanged public keys in previous steps.
|
||||
|
||||
1. Alice uses Bobs **private** key to encrypt a *secret value* (Usually just a key for symmetric encryption)
|
||||
1. Alice sends encrypted data to Bob
|
||||
1. Bob is the only one who has the matching private key, and can decrypt the data
|
||||
1. Bob and Alice now posses the same *secret value* and can start communicating (i.e. by using XChaCha20Poly1305
|
||||
symmetric encryption and using the *secret value* as the symmetric key)
|
||||
|
||||
Bob would do the same if he wanted to initiate the secure communication.
|
||||
|
||||
This set of functions also contains another use case called `sealed boxes` in libsodium.
|
||||
Sealed box is designed to anonymously send a message to a recipient. Libsodium documentation explains it as follows:
|
||||
> A message is encrypted using an ephemeral key pair, whose secret part is destroyed right after the encryption process.
|
||||
Without knowing the secret key used for a given message, the sender cannot decrypt its own message later. And without additional data, a message cannot be correlated with the identity of its sender.
|
||||
|
||||
|
@ -21,14 +21,34 @@ data class GenericHashState(val hashLength: Int, val internalState: GenericHashS
|
||||
|
||||
|
||||
expect object GenericHash {
|
||||
/**
|
||||
* Request computing a hash of message, with a specific hash length and optional key. The specific hash length can be
|
||||
* between [crypto_generichash_blake2b_BYTES_MIN] and [crypto_generichash_blake2b_BYTES_MAX]. If the key is provided
|
||||
* it needs the hash will be different for each different key.
|
||||
*/
|
||||
fun genericHash(message : UByteArray, requestedHashLength: Int = crypto_generichash_BYTES, key : UByteArray? = null) : UByteArray
|
||||
|
||||
fun genericHash(message : UByteArray, requestedHashLength: Int, key : UByteArray? = null) : UByteArray
|
||||
/**
|
||||
* Prepare a Generic Hash State object that will be used to compute hash of data with arbitrary length. Secific hash length
|
||||
* can be requested
|
||||
*/
|
||||
fun genericHashInit(requestedHashLength: Int = crypto_generichash_BYTES, key : UByteArray? = null) : GenericHashState
|
||||
|
||||
fun genericHashInit(requestedHashLength: Int, key : UByteArray? = null) : GenericHashState
|
||||
/**
|
||||
* Feed another chunk of message to the updateable hash object
|
||||
*/
|
||||
fun genericHashUpdate(state: GenericHashState, messagePart : UByteArray)
|
||||
|
||||
/**
|
||||
* Feed the last chunk of message to the updateable hash object. This returns the actual hash.
|
||||
*/
|
||||
fun genericHashFinal(state : GenericHashState) : UByteArray
|
||||
|
||||
/**
|
||||
* Generate a key of length [crypto_generichash_blake2b_KEYBYTES] that can be used with the generic hash funciton
|
||||
*/
|
||||
fun genericHashKeygen() : UByteArray
|
||||
|
||||
// ---- Not present in LazySodium nor libsodium.js
|
||||
// fun blake2b(message : UByteArray, requestedHashLength: Int, key : UByteArray? = null) : UByteArray
|
||||
//
|
||||
|
@ -0,0 +1,23 @@
|
||||
# Package com.ionspin.kotlin.crypto.generichash
|
||||
|
||||
## Generic hash
|
||||
|
||||
Generic hash package provides a easy to use hashing API that computes fixed-length fingerprint for an arbitrary long message.
|
||||
|
||||
In this case hashing is a process of mapping a set of input bytes to a fixed length (32 bytes) output. Loosely speaking
|
||||
hash function should be practically irreversible and resistant to collisions (a case where two different inputs result in a same output)
|
||||
|
||||
Some examples of hash function usage:
|
||||
- Verifying data integrity, i.e. downloading a file and it's hash and then recalculating the hash of the downloaded
|
||||
file to verify that it hasn't changed
|
||||
- Creating unique identifiers to index long data
|
||||
- Password verification, i.e. server stores just the hash of the users password and then when user wants to log in, they send
|
||||
the password, which server then hashes and compares to the stored hash. This way in case of breach of server security cleartext
|
||||
passwords are not revealed. With that said **DONT USE GENERIC HASH FOR PASSWORD HASHING**. Use PasswordHash funcitons.
|
||||
|
||||
Underneath this set of functions uses BLAKE2b secure hash function, Here is what Libsodium documentation says about it
|
||||
>The crypto_generichash_* function set is implemented using BLAKE2b, a simple, standardized (RFC 7693) secure hash
|
||||
>function that is as strong as SHA-3 but faster than SHA-1 and MD5.
|
||||
>Unlike MD5, SHA-1 and SHA-256, this function is safe against hash length extension attacks.
|
||||
>BLAKE2b is not suitable for hashing passwords. For this purpose, use the crypto_pwhash API documented
|
||||
>in the Password Hashing section.
|
@ -9,10 +9,14 @@ fun String.hexStringToUByteArray() : UByteArray {
|
||||
return this.chunked(2).map { it.toUByte(16) }.toUByteArray()
|
||||
}
|
||||
|
||||
fun String.encodeToUByteArray() : UByteArray{
|
||||
fun String.encodeToUByteArray() : UByteArray{
|
||||
return encodeToByteArray().asUByteArray()
|
||||
}
|
||||
|
||||
fun UByteArray.decodeFromUByteArray() : String {
|
||||
return asByteArray().decodeToString()
|
||||
}
|
||||
|
||||
fun UByteArray.toHexString() : String {
|
||||
return this.joinToString(separator = "") {
|
||||
if (it <= 0x0FU) {
|
||||
|
@ -26,7 +26,7 @@ actual object AuthenticatedEncryptionWithAssociatedData {
|
||||
}
|
||||
|
||||
actual fun xChaCha20Poly1305IetfDecrypt(
|
||||
ciphertext: UByteArray,
|
||||
ciphertextAndTag: UByteArray,
|
||||
associatedData: UByteArray,
|
||||
nonce: UByteArray,
|
||||
key: UByteArray
|
||||
@ -34,7 +34,7 @@ actual object AuthenticatedEncryptionWithAssociatedData {
|
||||
try {
|
||||
return getSodium().crypto_aead_xchacha20poly1305_ietf_decrypt(
|
||||
null,
|
||||
ciphertext.toUInt8Array(),
|
||||
ciphertextAndTag.toUInt8Array(),
|
||||
associatedData.toUInt8Array(),
|
||||
nonce.toUInt8Array(),
|
||||
key.toUInt8Array()
|
||||
@ -100,7 +100,7 @@ actual object AuthenticatedEncryptionWithAssociatedData {
|
||||
}
|
||||
|
||||
actual fun chaCha20Poly1305IetfDecrypt(
|
||||
ciphertext: UByteArray,
|
||||
ciphertextAndTag: UByteArray,
|
||||
associatedData: UByteArray,
|
||||
nonce: UByteArray,
|
||||
key: UByteArray
|
||||
@ -108,7 +108,7 @@ actual object AuthenticatedEncryptionWithAssociatedData {
|
||||
try {
|
||||
return getSodium().crypto_aead_chacha20poly1305_ietf_decrypt(
|
||||
null,
|
||||
ciphertext.toUInt8Array(),
|
||||
ciphertextAndTag.toUInt8Array(),
|
||||
associatedData.toUInt8Array(),
|
||||
nonce.toUInt8Array(),
|
||||
key.toUInt8Array()
|
||||
@ -174,7 +174,7 @@ actual object AuthenticatedEncryptionWithAssociatedData {
|
||||
}
|
||||
|
||||
actual fun chaCha20Poly1305Decrypt(
|
||||
ciphertext: UByteArray,
|
||||
ciphertextAndTag: UByteArray,
|
||||
associatedData: UByteArray,
|
||||
nonce: UByteArray,
|
||||
key: UByteArray
|
||||
@ -182,7 +182,7 @@ actual object AuthenticatedEncryptionWithAssociatedData {
|
||||
try {
|
||||
return getSodium().crypto_aead_chacha20poly1305_decrypt(
|
||||
null,
|
||||
ciphertext.toUInt8Array(),
|
||||
ciphertextAndTag.toUInt8Array(),
|
||||
associatedData.toUInt8Array(),
|
||||
nonce.toUInt8Array(),
|
||||
key.toUInt8Array()
|
||||
|
@ -3,7 +3,6 @@ package com.ionspin.kotlin.crypto.auth
|
||||
import com.ionspin.kotlin.crypto.getSodium
|
||||
import ext.libsodium.com.ionspin.kotlin.crypto.toUByteArray
|
||||
import ext.libsodium.com.ionspin.kotlin.crypto.toUInt8Array
|
||||
import org.khronos.webgl.Uint8Array
|
||||
|
||||
actual object Auth {
|
||||
actual fun authKeygen(): UByteArray {
|
||||
@ -18,9 +17,9 @@ actual object Auth {
|
||||
|
||||
}
|
||||
|
||||
actual fun authVerify(mac: UByteArray, message: UByteArray, key: UByteArray): Boolean {
|
||||
actual fun authVerify(tag: UByteArray, message: UByteArray, key: UByteArray): Boolean {
|
||||
return getSodium().crypto_auth_verify(
|
||||
mac.toUInt8Array(),
|
||||
tag.toUInt8Array(),
|
||||
message.toUInt8Array(),
|
||||
key.toUInt8Array()
|
||||
)
|
||||
@ -38,12 +37,12 @@ actual object Auth {
|
||||
}
|
||||
|
||||
actual fun authHmacSha256Verify(
|
||||
mac: UByteArray,
|
||||
tag: UByteArray,
|
||||
message: UByteArray,
|
||||
key: UByteArray
|
||||
): Boolean {
|
||||
return getSodium().crypto_auth_hmacsha256_verify(
|
||||
mac.toUInt8Array(),
|
||||
tag.toUInt8Array(),
|
||||
message.toUInt8Array(),
|
||||
key.toUInt8Array()
|
||||
)
|
||||
@ -61,12 +60,12 @@ actual object Auth {
|
||||
}
|
||||
|
||||
actual fun authHmacSha512Verify(
|
||||
mac: UByteArray,
|
||||
tag: UByteArray,
|
||||
message: UByteArray,
|
||||
key: UByteArray
|
||||
): Boolean {
|
||||
return getSodium().crypto_auth_hmacsha512_verify(
|
||||
mac.toUInt8Array(),
|
||||
tag.toUInt8Array(),
|
||||
message.toUInt8Array(),
|
||||
key.toUInt8Array()
|
||||
)
|
||||
|
@ -29,18 +29,18 @@ actual object AuthenticatedEncryptionWithAssociatedData {
|
||||
}
|
||||
|
||||
actual fun xChaCha20Poly1305IetfDecrypt(
|
||||
ciphertext: UByteArray,
|
||||
ciphertextAndTag: UByteArray,
|
||||
associatedData: UByteArray,
|
||||
nonce: UByteArray,
|
||||
key: UByteArray
|
||||
): UByteArray {
|
||||
val message = UByteArray(ciphertext.size - crypto_aead_xchacha20poly1305_ietf_ABYTES)
|
||||
val message = UByteArray(ciphertextAndTag.size - crypto_aead_xchacha20poly1305_ietf_ABYTES)
|
||||
val validationResult = sodium.crypto_aead_xchacha20poly1305_ietf_decrypt(
|
||||
message.asByteArray(),
|
||||
null,
|
||||
null,
|
||||
ciphertext.asByteArray(),
|
||||
ciphertext.size.toLong(),
|
||||
ciphertextAndTag.asByteArray(),
|
||||
ciphertextAndTag.size.toLong(),
|
||||
associatedData.asByteArray(),
|
||||
associatedData.size.toLong(),
|
||||
nonce.asByteArray(),
|
||||
@ -122,18 +122,18 @@ actual object AuthenticatedEncryptionWithAssociatedData {
|
||||
}
|
||||
|
||||
actual fun chaCha20Poly1305IetfDecrypt(
|
||||
ciphertext: UByteArray,
|
||||
ciphertextAndTag: UByteArray,
|
||||
associatedData: UByteArray,
|
||||
nonce: UByteArray,
|
||||
key: UByteArray
|
||||
): UByteArray {
|
||||
val message = UByteArray(ciphertext.size - crypto_aead_chacha20poly1305_ietf_ABYTES)
|
||||
val message = UByteArray(ciphertextAndTag.size - crypto_aead_chacha20poly1305_ietf_ABYTES)
|
||||
val validationResult = sodium.crypto_aead_chacha20poly1305_ietf_decrypt(
|
||||
message.asByteArray(),
|
||||
null,
|
||||
null,
|
||||
ciphertext.asByteArray(),
|
||||
ciphertext.size.toLong(),
|
||||
ciphertextAndTag.asByteArray(),
|
||||
ciphertextAndTag.size.toLong(),
|
||||
associatedData.asByteArray(),
|
||||
associatedData.size.toLong(),
|
||||
nonce.asByteArray(),
|
||||
@ -215,18 +215,18 @@ actual object AuthenticatedEncryptionWithAssociatedData {
|
||||
}
|
||||
|
||||
actual fun chaCha20Poly1305Decrypt(
|
||||
ciphertext: UByteArray,
|
||||
ciphertextAndTag: UByteArray,
|
||||
associatedData: UByteArray,
|
||||
nonce: UByteArray,
|
||||
key: UByteArray
|
||||
): UByteArray {
|
||||
val message = UByteArray(ciphertext.size - crypto_aead_chacha20poly1305_ABYTES)
|
||||
val message = UByteArray(ciphertextAndTag.size - crypto_aead_chacha20poly1305_ABYTES)
|
||||
val validationResult = sodium.crypto_aead_chacha20poly1305_decrypt(
|
||||
message.asByteArray(),
|
||||
null,
|
||||
null,
|
||||
ciphertext.asByteArray(),
|
||||
ciphertext.size.toLong(),
|
||||
ciphertextAndTag.asByteArray(),
|
||||
ciphertextAndTag.size.toLong(),
|
||||
associatedData.asByteArray(),
|
||||
associatedData.size.toLong(),
|
||||
nonce.asByteArray(),
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user