[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[taler-wallet-kotlin] 03/03: Add SHA-512 implementations for all platfor
From: |
gnunet |
Subject: |
[taler-wallet-kotlin] 03/03: Add SHA-512 implementations for all platforms |
Date: |
Wed, 03 Jun 2020 14:09:50 +0200 |
This is an automated email from the git hooks/post-receive script.
torsten-grote pushed a commit to branch master
in repository wallet-kotlin.
commit 72c020c3077cb3c0df1ab0fa629f11ea686e140d
Author: Torsten Grote <t@grobox.de>
AuthorDate: Tue Jun 2 17:03:19 2020 -0300
Add SHA-512 implementations for all platforms
---
.idea/.gitignore | 6 +-
.idea/compiler.xml | 14 +++-
.idea/dictionaries/user.xml | 7 ++
.idea/misc.xml | 76 +++++++++++++++++++++-
.idea/modules.xml | 17 ++---
build.gradle | 17 +++--
.../taler/wallet/kotlin/crypto/CryptoFactory.kt | 22 +++++++
.../net/taler/wallet/kotlin/crypto/Crypto.kt | 21 ++++++
.../net/taler/wallet/kotlin/crypto/Sha512Test.kt | 52 +++++++++++++++
.../taler/wallet/kotlin/crypto/CryptoFactory.kt | 37 +++++++++++
.../taler/wallet/kotlin/crypto/CryptoFactory.kt | 26 ++++++++
src/nativeInterop/cinterop/sodium.def | 4 ++
12 files changed, 282 insertions(+), 17 deletions(-)
diff --git a/.idea/.gitignore b/.idea/.gitignore
index 4cbb824..3127cf3 100644
--- a/.idea/.gitignore
+++ b/.idea/.gitignore
@@ -3,4 +3,8 @@
/artifacts
/modules
/workspace.xml
-/gradle.xml
\ No newline at end of file
+/gradle.xml
+/libraries
+/caches
+/runConfigurations.xml
+/encodings.xml
\ No newline at end of file
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
index 756b946..ad4fc3c 100644
--- a/.idea/compiler.xml
+++ b/.idea/compiler.xml
@@ -1,9 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
+ <wildcardResourcePatterns>
+ <entry name="!?*.java" />
+ <entry name="!?*.form" />
+ <entry name="!?*.class" />
+ <entry name="!?*.groovy" />
+ <entry name="!?*.scala" />
+ <entry name="!?*.flex" />
+ <entry name="!?*.kt" />
+ <entry name="!?*.clj" />
+ </wildcardResourcePatterns>
<bytecodeTargetLevel target="1.8">
- <module name="wallet-kotlin.jvmMain" target="1.6" />
- <module name="wallet-kotlin.jvmTest" target="1.6" />
+ <module name="wallet-kotlin_androidMain" target="1.6" />
+ <module name="wallet-kotlin_androidTest" target="1.6" />
</bytecodeTargetLevel>
</component>
</project>
\ No newline at end of file
diff --git a/.idea/dictionaries/user.xml b/.idea/dictionaries/user.xml
new file mode 100644
index 0000000..55989af
--- /dev/null
+++ b/.idea/dictionaries/user.xml
@@ -0,0 +1,7 @@
+<component name="ProjectDictionaryState">
+ <dictionary name="user">
+ <words>
+ <w>nacl</w>
+ </words>
+ </dictionary>
+</component>
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
index 38167d7..21353ae 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -1,7 +1,79 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
- <component name="ExternalStorageConfigurationManager" enabled="true" />
+ <component name="CMakeSettings">
+ <configurations>
+ <configuration PROFILE_NAME="Debug" CONFIG_NAME="Debug" />
+ </configurations>
+ </component>
+ <component name="MarkdownProjectSettings">
+ <PreviewSettings splitEditorLayout="SPLIT" splitEditorPreview="PREVIEW"
useGrayscaleRendering="false" zoomFactor="1.0" maxImageWidth="0"
showGitHubPageIfSynced="false" allowBrowsingInPreview="false"
synchronizePreviewPosition="true" highlightPreviewType="NONE"
highlightFadeOut="5" highlightOnTyping="true" synchronizeSourcePosition="true">
+ <PanelProvider>
+ <provider
providerId="com.vladsch.idea.multimarkdown.editor.swing.html.panel"
providerName="Default - Swing" />
+ </PanelProvider>
+ </PreviewSettings>
+ <ParserSettings>
+ <PegdownExtensions>
+ <option name="ABBREVIATIONS" value="false" />
+ <option name="ANCHORLINKS" value="true" />
+ <option name="ATXHEADERSPACE" value="true" />
+ <option name="AUTOLINKS" value="true" />
+ <option name="DEFINITIONS" value="false" />
+ <option name="FENCED_CODE_BLOCKS" value="true" />
+ <option name="FOOTNOTES" value="false" />
+ <option name="HARDWRAPS" value="false" />
+ <option name="INSERTED" value="false" />
+ <option name="QUOTES" value="false" />
+ <option name="RELAXEDHRULES" value="true" />
+ <option name="SMARTS" value="false" />
+ <option name="STRIKETHROUGH" value="true" />
+ <option name="SUBSCRIPT" value="false" />
+ <option name="SUPERSCRIPT" value="false" />
+ <option name="SUPPRESS_HTML_BLOCKS" value="false" />
+ <option name="SUPPRESS_INLINE_HTML" value="false" />
+ <option name="TABLES" value="true" />
+ <option name="TASKLISTITEMS" value="true" />
+ <option name="TOC" value="false" />
+ <option name="WIKILINKS" value="true" />
+ </PegdownExtensions>
+ <ParserOptions>
+ <option name="COMMONMARK_LISTS" value="false" />
+ <option name="DUMMY" value="false" />
+ <option name="EMOJI_SHORTCUTS" value="true" />
+ <option name="FLEXMARK_FRONT_MATTER" value="false" />
+ <option name="GFM_TABLE_RENDERING" value="true" />
+ <option name="GITBOOK_URL_ENCODING" value="false" />
+ <option name="GITHUB_EMOJI_URL" value="false" />
+ <option name="GITHUB_LISTS" value="true" />
+ <option name="GITHUB_WIKI_LINKS" value="true" />
+ <option name="JEKYLL_FRONT_MATTER" value="false" />
+ <option name="SIM_TOC_BLANK_LINE_SPACER" value="true" />
+ </ParserOptions>
+ </ParserSettings>
+ <HtmlSettings headerTopEnabled="false" headerBottomEnabled="false"
bodyTopEnabled="false" bodyBottomEnabled="false" embedUrlContent="false"
addPageHeader="true">
+ <GeneratorProvider>
+ <provider
providerId="com.vladsch.idea.multimarkdown.editor.swing.html.generator"
providerName="Default Swing HTML Generator" />
+ </GeneratorProvider>
+ <headerTop />
+ <headerBottom />
+ <bodyTop />
+ <bodyBottom />
+ </HtmlSettings>
+ <CssSettings previewScheme="UI_SCHEME" cssUri="" isCssUriEnabled="false"
isCssTextEnabled="false" isDynamicPageWidth="true">
+ <StylesheetProvider>
+ <provider
providerId="com.vladsch.idea.multimarkdown.editor.swing.html.css"
providerName="Default Swing Stylesheet" />
+ </StylesheetProvider>
+ <ScriptProviders />
+ <cssText />
+ </CssSettings>
+ <HtmlExportSettings updateOnSave="false" parentDir="$ProjectFileDir$"
targetDir="$ProjectFileDir$" cssDir="" scriptDir="" plainHtml="false"
imageDir="" copyLinkedImages="false" imageUniquifyType="0" targetExt=""
useTargetExt="false" noCssNoScripts="false" linkToExportedHtml="true"
exportOnSettingsChange="true" regenerateOnProjectOpen="false" />
+ <LinkMapSettings>
+ <textMaps />
+ </LinkMapSettings>
+ </component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8"
default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
- <output url="file://$PROJECT_DIR$/out" />
+ <output url="file://$PROJECT_DIR$/build/classes" />
+ </component>
+ <component name="ProjectType">
+ <option name="id" value="Android" />
</component>
</project>
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
index dacd95f..d8c63dd 100644
--- a/.idea/modules.xml
+++ b/.idea/modules.xml
@@ -2,14 +2,15 @@
<project version="4">
<component name="ProjectModuleManager">
<modules>
- <module
fileurl="file://$PROJECT_DIR$/.idea/modules/wallet-kotlin.commonMain.iml"
filepath="$PROJECT_DIR$/.idea/modules/wallet-kotlin.commonMain.iml" />
- <module
fileurl="file://$PROJECT_DIR$/.idea/modules/wallet-kotlin.commonTest.iml"
filepath="$PROJECT_DIR$/.idea/modules/wallet-kotlin.commonTest.iml" />
- <module
fileurl="file://$PROJECT_DIR$/.idea/modules/wallet-kotlin.jsMain.iml"
filepath="$PROJECT_DIR$/.idea/modules/wallet-kotlin.jsMain.iml" />
- <module
fileurl="file://$PROJECT_DIR$/.idea/modules/wallet-kotlin.jsTest.iml"
filepath="$PROJECT_DIR$/.idea/modules/wallet-kotlin.jsTest.iml" />
- <module
fileurl="file://$PROJECT_DIR$/.idea/modules/wallet-kotlin.jvmMain.iml"
filepath="$PROJECT_DIR$/.idea/modules/wallet-kotlin.jvmMain.iml" />
- <module
fileurl="file://$PROJECT_DIR$/.idea/modules/wallet-kotlin.jvmTest.iml"
filepath="$PROJECT_DIR$/.idea/modules/wallet-kotlin.jvmTest.iml" />
- <module
fileurl="file://$PROJECT_DIR$/.idea/modules/wallet-kotlin.linuxMain.iml"
filepath="$PROJECT_DIR$/.idea/modules/wallet-kotlin.linuxMain.iml" />
- <module
fileurl="file://$PROJECT_DIR$/.idea/modules/wallet-kotlin.linuxTest.iml"
filepath="$PROJECT_DIR$/.idea/modules/wallet-kotlin.linuxTest.iml" />
+ <module fileurl="file://$PROJECT_DIR$/.idea/modules/wallet-kotlin.iml"
filepath="$PROJECT_DIR$/.idea/modules/wallet-kotlin.iml" group="wallet-kotlin"
/>
+ <module
fileurl="file://$PROJECT_DIR$/.idea/modules/wallet-kotlin_androidMain.iml"
filepath="$PROJECT_DIR$/.idea/modules/wallet-kotlin_androidMain.iml"
group="wallet-kotlin" />
+ <module
fileurl="file://$PROJECT_DIR$/.idea/modules/wallet-kotlin_androidTest.iml"
filepath="$PROJECT_DIR$/.idea/modules/wallet-kotlin_androidTest.iml"
group="wallet-kotlin" />
+ <module
fileurl="file://$PROJECT_DIR$/.idea/modules/wallet-kotlin_commonMain.iml"
filepath="$PROJECT_DIR$/.idea/modules/wallet-kotlin_commonMain.iml"
group="wallet-kotlin" />
+ <module
fileurl="file://$PROJECT_DIR$/.idea/modules/wallet-kotlin_commonTest.iml"
filepath="$PROJECT_DIR$/.idea/modules/wallet-kotlin_commonTest.iml"
group="wallet-kotlin" />
+ <module
fileurl="file://$PROJECT_DIR$/.idea/modules/wallet-kotlin_jsMain.iml"
filepath="$PROJECT_DIR$/.idea/modules/wallet-kotlin_jsMain.iml"
group="wallet-kotlin" />
+ <module
fileurl="file://$PROJECT_DIR$/.idea/modules/wallet-kotlin_jsTest.iml"
filepath="$PROJECT_DIR$/.idea/modules/wallet-kotlin_jsTest.iml"
group="wallet-kotlin" />
+ <module
fileurl="file://$PROJECT_DIR$/.idea/modules/wallet-kotlin_linuxMain.iml"
filepath="$PROJECT_DIR$/.idea/modules/wallet-kotlin_linuxMain.iml"
group="wallet-kotlin" />
+ <module
fileurl="file://$PROJECT_DIR$/.idea/modules/wallet-kotlin_linuxTest.iml"
filepath="$PROJECT_DIR$/.idea/modules/wallet-kotlin_linuxTest.iml"
group="wallet-kotlin" />
</modules>
</component>
</project>
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index d9f4cb0..7e06be1 100644
--- a/build.gradle
+++ b/build.gradle
@@ -9,8 +9,9 @@ version '0.0.1'
apply plugin: 'maven-publish'
+
kotlin {
- jvm()
+ jvm("android")
js {
browser {
}
@@ -21,7 +22,13 @@ kotlin {
// For Linux, should be changed to e.g. linuxX64
// For MacOS, should be changed to e.g. macosX64
// For Windows, should be changed to e.g. mingwX64
- linuxX64("linux")
+ linuxX64("linux") {
+ compilations.main.cinterops {
+ sodium {
+ packageName 'org.libsodium'
+ }
+ }
+ }
sourceSets {
commonMain {
dependencies {
@@ -34,12 +41,13 @@ kotlin {
implementation kotlin('test-annotations-common')
}
}
- jvmMain {
+ androidMain {
dependencies {
implementation kotlin('stdlib-jdk8')
+ implementation 'org.bouncycastle:bcprov-jdk15on:1.65.01'
}
}
- jvmTest {
+ androidTest {
dependencies {
implementation kotlin('test')
implementation kotlin('test-junit')
@@ -48,6 +56,7 @@ kotlin {
jsMain {
dependencies {
implementation kotlin('stdlib-js')
+ implementation npm('tweetnacl', '1.0.3')
}
}
jsTest {
diff --git
a/src/androidMain/kotlin/net/taler/wallet/kotlin/crypto/CryptoFactory.kt
b/src/androidMain/kotlin/net/taler/wallet/kotlin/crypto/CryptoFactory.kt
new file mode 100644
index 0000000..509fabb
--- /dev/null
+++ b/src/androidMain/kotlin/net/taler/wallet/kotlin/crypto/CryptoFactory.kt
@@ -0,0 +1,22 @@
+package net.taler.wallet.kotlin.crypto
+
+import org.bouncycastle.jce.provider.BouncyCastleProvider
+import java.security.MessageDigest
+import java.security.Security
+
+actual object CryptoFactory {
+ actual fun getCrypto(): Crypto = CryptoJvmImpl
+}
+
+object CryptoJvmImpl : Crypto {
+
+ init {
+ Security.addProvider(BouncyCastleProvider())
+ }
+
+ override fun sha512(input: ByteArray): ByteArray {
+ val digest = MessageDigest.getInstance("SHA-512", "BC")
+ return digest.digest(input)
+ }
+
+}
diff --git a/src/commonMain/kotlin/net/taler/wallet/kotlin/crypto/Crypto.kt
b/src/commonMain/kotlin/net/taler/wallet/kotlin/crypto/Crypto.kt
new file mode 100644
index 0000000..a5eeb69
--- /dev/null
+++ b/src/commonMain/kotlin/net/taler/wallet/kotlin/crypto/Crypto.kt
@@ -0,0 +1,21 @@
+package net.taler.wallet.kotlin.crypto
+
+interface Crypto {
+ fun sha512(input: ByteArray): ByteArray
+}
+
+expect object CryptoFactory {
+ fun getCrypto(): Crypto
+}
+
+private val hexArray = arrayOf('0', '1', '2', '3', '4', '5', '6', '7', '8',
'9', 'a', 'b', 'c', 'd', 'e', 'f')
+
+fun ByteArray.toHexString(): String {
+ val hexChars = CharArray(this.size * 2)
+ for (j in this.indices) {
+ val v = (this[j].toInt() and 0xFF)
+ hexChars[j * 2] = hexArray[v ushr 4]
+ hexChars[j * 2 + 1] = hexArray[v and 0x0F]
+ }
+ return String(hexChars)
+}
diff --git a/src/commonTest/kotlin/net/taler/wallet/kotlin/crypto/Sha512Test.kt
b/src/commonTest/kotlin/net/taler/wallet/kotlin/crypto/Sha512Test.kt
new file mode 100644
index 0000000..f41080f
--- /dev/null
+++ b/src/commonTest/kotlin/net/taler/wallet/kotlin/crypto/Sha512Test.kt
@@ -0,0 +1,52 @@
+package net.taler.wallet.kotlin.crypto
+
+import kotlin.test.Test
+import kotlin.test.assertEquals
+
+@kotlin.ExperimentalStdlibApi
+class Sha512Test {
+
+ private val crypto = CryptoFactory.getCrypto()
+
+ @Test
+ fun testAbc() {
+ assertEquals(
+
"ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f",
+ crypto.sha512("abc".encodeToByteArray()).toHexString()
+ )
+ }
+
+ @Test
+ fun testEmptyString() {
+ assertEquals(
+
"cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e",
+ crypto.sha512("".encodeToByteArray()).toHexString()
+ )
+ }
+
+ @Test
+ fun testAbc448bits() {
+ assertEquals(
+
"204a8fc6dda82f0a0ced7beb8e08a41657c16ef468b228a8279be331a703c33596fd15c13b1b07f9aa1d3bea57789ca031ad85c7a71dd70354ec631238ca3445",
+
crypto.sha512("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq".encodeToByteArray()).toHexString()
+ )
+ }
+
+ @Test
+ fun testAbc896bits() {
+ assertEquals(
+
"8e959b75dae313da8cf4f72814fc143f8f7779c6eb9f7fa17299aeadb6889018501d289e4900f7e4331b99dec4b5433ac7d329eeb6dd26545e96e55b874be909",
+
crypto.sha512("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu".encodeToByteArray()).toHexString()
+ )
+ }
+
+ @Test
+ fun testAMillionAs() {
+ val input = ByteArray(1_000_000) { 0x61 }
+ assertEquals(
+
"e718483d0ce769644e2e42c7bc15b4638e1f98b13b2044285632a803afa973ebde0ff244877ea60a4cb0432ce577c31beb009c5c2c49aa2e4eadb217ad8cc09b",
+ crypto.sha512(input).toHexString()
+ )
+ }
+
+}
diff --git a/src/jsMain/kotlin/net/taler/wallet/kotlin/crypto/CryptoFactory.kt
b/src/jsMain/kotlin/net/taler/wallet/kotlin/crypto/CryptoFactory.kt
new file mode 100644
index 0000000..e1786d9
--- /dev/null
+++ b/src/jsMain/kotlin/net/taler/wallet/kotlin/crypto/CryptoFactory.kt
@@ -0,0 +1,37 @@
+package net.taler.wallet.kotlin.crypto
+
+import org.khronos.webgl.Uint8Array
+import org.khronos.webgl.get
+
+actual object CryptoFactory {
+ actual fun getCrypto(): Crypto = CryptoJsImpl
+}
+
+object CryptoJsImpl : Crypto {
+
+ override fun sha512(input: ByteArray): ByteArray {
+ return nacl.hash(input.toUint8Array()).toByteArray()
+ }
+
+}
+
+private fun Uint8Array.toByteArray(): ByteArray {
+ val result = ByteArray(this.length)
+ for (i in 0 until this.length) {
+ result[i] = this[i]
+ }
+ return result
+}
+
+private fun ByteArray.toUint8Array():Uint8Array {
+ return Uint8Array(this.toTypedArray())
+}
+
+@Suppress("ClassName")
+@JsModule("tweetnacl")
+@JsNonModule
+external class nacl {
+ companion object {
+ fun hash(input: Uint8Array): Uint8Array
+ }
+}
diff --git
a/src/linuxMain/kotlin/net/taler/wallet/kotlin/crypto/CryptoFactory.kt
b/src/linuxMain/kotlin/net/taler/wallet/kotlin/crypto/CryptoFactory.kt
new file mode 100644
index 0000000..d1ec46a
--- /dev/null
+++ b/src/linuxMain/kotlin/net/taler/wallet/kotlin/crypto/CryptoFactory.kt
@@ -0,0 +1,26 @@
+package net.taler.wallet.kotlin.crypto
+
+import org.libsodium.*
+import kotlinx.cinterop.*
+
+actual object CryptoFactory {
+ @ExperimentalUnsignedTypes
+ actual fun getCrypto(): Crypto = CryptoNativeImpl
+}
+
+@ExperimentalUnsignedTypes
+object CryptoNativeImpl : Crypto {
+
+ override fun sha512(input: ByteArray): ByteArray {
+ val output = ByteArray(crypto_hash_sha512_bytes().toInt())
+ val cInput = if (input.isEmpty()) null else
input.toUByteArray().refTo(0)
+ val cInputSize = input.size.toULong()
+ output.usePinned { pinned ->
+ @Suppress("UNCHECKED_CAST")
+ val cOutput = pinned.addressOf(0) as CValuesRef<UByteVar>
+ crypto_hash_sha512(cOutput, cInput, cInputSize)
+ }
+ return output
+ }
+
+}
diff --git a/src/nativeInterop/cinterop/sodium.def
b/src/nativeInterop/cinterop/sodium.def
new file mode 100644
index 0000000..b41f11b
--- /dev/null
+++ b/src/nativeInterop/cinterop/sodium.def
@@ -0,0 +1,4 @@
+headers = sodium.h
+headerFilter = sodium.h sodium/**
+compilerOpts = -I/usr/include -I/usr/include/x86_64-linux-gnu/
+linkerOpts = -lsodium -L/usr/lib/x86_64-linux-gnu -L/usr/lib64/
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.