Adding scalrmult_ native impl, starting work on sample
This commit is contained in:
parent
60dfdb01cc
commit
c66fde8502
@ -0,0 +1,34 @@
|
||||
package com.ionspin.kotlin.crypto.scalarmut
|
||||
|
||||
/**
|
||||
* Created by Ugljesa Jovanovic
|
||||
* ugljesa.jovanovic@ionspin.com
|
||||
* on 15-Oct-2020
|
||||
*/
|
||||
const val crypto_scalarmult_BYTES = 32
|
||||
const val crypto_scalarmult_SCALARBYTES = 32
|
||||
|
||||
expect object ScalarMultiplication {
|
||||
|
||||
/**
|
||||
* This function can be used to compute a shared secret q given a user's secret key and another user's public key.
|
||||
* n is crypto_scalarmult_SCALARBYTES bytes long, p and the output are crypto_scalarmult_BYTES bytes long.
|
||||
* q represents the X coordinate of a point on the curve. As a result, the number of possible keys is limited to
|
||||
* the group size (≈2^252), which is smaller than the key space.
|
||||
* For this reason, and to mitigate subtle attacks due to the fact many (p, n) pairs produce the same result,
|
||||
* using the output of the multiplication q directly as a shared key is not recommended.
|
||||
* A better way to compute a shared key is h(q ‖ pk1 ‖ pk2), with pk1 and pk2 being the public keys.
|
||||
* By doing so, each party can prove what exact public key they intended to perform a key exchange with
|
||||
* (for a given public key, 11 other public keys producing the same shared secret can be trivially computed).
|
||||
* This can be achieved with the following code snippet:
|
||||
*/
|
||||
fun scalarMultiplication(secretKeyN : UByteArray, publicKeyP: UByteArray) : UByteArray
|
||||
|
||||
/**
|
||||
* Given a user's secret key n (crypto_scalarmult_SCALARBYTES bytes), the crypto_scalarmult_base() function
|
||||
* computes the user's public key and puts it into q (crypto_scalarmult_BYTES bytes).
|
||||
* crypto_scalarmult_BYTES and crypto_scalarmult_SCALARBYTES are provided for consistency,
|
||||
* but it is safe to assume that crypto_scalarmult_BYTES == crypto_scalarmult_SCALARBYTES.
|
||||
*/
|
||||
fun scalarMultiplicationBase(secretKeyN : UByteArray) : UByteArray
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
package com.ionspin.kotlin.crypto.scalarmut
|
||||
|
||||
import com.ionspin.kotlin.crypto.util.toPtr
|
||||
import kotlinx.cinterop.pin
|
||||
import libsodium.crypto_scalarmult
|
||||
import libsodium.crypto_scalarmult_base
|
||||
|
||||
actual object ScalarMultiplication {
|
||||
|
||||
/**
|
||||
* This function can be used to compute a shared secret q given a user's secret key and another user's public key.
|
||||
* n is crypto_scalarmult_SCALARBYTES bytes long, p and the output are crypto_scalarmult_BYTES bytes long.
|
||||
* q represents the X coordinate of a point on the curve. As a result, the number of possible keys is limited to
|
||||
* the group size (≈2^252), which is smaller than the key space.
|
||||
* For this reason, and to mitigate subtle attacks due to the fact many (p, n) pairs produce the same result,
|
||||
* using the output of the multiplication q directly as a shared key is not recommended.
|
||||
* A better way to compute a shared key is h(q ‖ pk1 ‖ pk2), with pk1 and pk2 being the public keys.
|
||||
* By doing so, each party can prove what exact public key they intended to perform a key exchange with
|
||||
* (for a given public key, 11 other public keys producing the same shared secret can be trivially computed).
|
||||
* This can be achieved with the following code snippet:
|
||||
*/
|
||||
actual fun scalarMultiplication(secretKeyN: UByteArray, publicKeyP: UByteArray): UByteArray {
|
||||
val result = UByteArray(crypto_scalarmult_BYTES)
|
||||
val resultPinned = result.pin()
|
||||
val secretKeyNPinned = secretKeyN.pin()
|
||||
val publicKeyPPinned = publicKeyP.pin()
|
||||
|
||||
crypto_scalarmult(resultPinned.toPtr(), secretKeyNPinned.toPtr(), publicKeyPPinned.toPtr())
|
||||
|
||||
resultPinned.unpin()
|
||||
secretKeyNPinned.unpin()
|
||||
publicKeyPPinned.unpin()
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a user's secret key n (crypto_scalarmult_SCALARBYTES bytes), the crypto_scalarmult_base() function
|
||||
* computes the user's public key and puts it into q (crypto_scalarmult_BYTES bytes).
|
||||
* crypto_scalarmult_BYTES and crypto_scalarmult_SCALARBYTES are provided for consistency,
|
||||
* but it is safe to assume that crypto_scalarmult_BYTES == crypto_scalarmult_SCALARBYTES.
|
||||
*/
|
||||
actual fun scalarMultiplicationBase(
|
||||
secretKeyN: UByteArray
|
||||
): UByteArray {
|
||||
val result = UByteArray(crypto_scalarmult_BYTES)
|
||||
val resultPinned = result.pin()
|
||||
val secretKeyNPinned = secretKeyN.pin()
|
||||
|
||||
crypto_scalarmult_base(resultPinned.toPtr(), secretKeyNPinned.toPtr())
|
||||
|
||||
resultPinned.unpin()
|
||||
secretKeyNPinned.unpin()
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
}
|
@ -144,7 +144,7 @@ kotlin {
|
||||
implementation(kotlin(Deps.Common.stdLib))
|
||||
implementation(kotlin(Deps.Common.test))
|
||||
implementation(Deps.Common.kotlinBigNum)
|
||||
implementation(project(":multiplatform-crypto-delegated"))
|
||||
implementation(project(":multiplatform-crypto-libsodium-bindings"))
|
||||
}
|
||||
}
|
||||
val commonTest by getting {
|
||||
|
@ -1,28 +1,12 @@
|
||||
package com.ionspin.kotlin.crypto.sample
|
||||
|
||||
import com.ionspin.kotlin.crypto.Crypto
|
||||
import com.ionspin.kotlin.crypto.CryptoInitializerDelegated
|
||||
import com.ionspin.kotlin.crypto.CryptoPrimitives
|
||||
import com.ionspin.kotlin.crypto.hash.encodeToUByteArray
|
||||
import com.ionspin.kotlin.crypto.util.LibsodiumRandom
|
||||
import com.ionspin.kotlin.crypto.util.toHexString
|
||||
|
||||
|
||||
object Sample {
|
||||
fun runSample() {
|
||||
println("Initializing crypto library")
|
||||
CryptoInitializerDelegated.initializeWithCallback {
|
||||
blake2b()
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
fun blake2b() {
|
||||
println("Blake2b updateable")
|
||||
val blake2bUpdateable = CryptoPrimitives.Blake2b.updateable()
|
||||
blake2bUpdateable.update("test".encodeToUByteArray())
|
||||
println(blake2bUpdateable.digest().toHexString())
|
||||
println("Blake2b stateless")
|
||||
val statelessResult = CryptoPrimitives.Blake2b.stateless("test".encodeToUByteArray())
|
||||
println("Blake2b stateless: ${statelessResult.toHexString()}")
|
||||
val random = LibsodiumRandom.buf(32)
|
||||
println("Random: ${random.toHexString()}")
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,6 @@ import com.ionspin.kotlin.crypto.sample.Sample
|
||||
import kotlin.time.ExperimentalTime
|
||||
|
||||
@ExperimentalTime
|
||||
|
||||
fun main() {
|
||||
|
||||
Sample.runSample()
|
||||
|
@ -1,7 +1,5 @@
|
||||
import com.ionspin.kotlin.crypto.sample.Sample
|
||||
|
||||
|
||||
|
||||
fun main() {
|
||||
Sample.runSample()
|
||||
}
|
||||
|
@ -156,6 +156,7 @@ native libsodium library.
|
||||
|
||||
## Constants
|
||||
| Constant name| Implemented |
|
||||
|-------------|-------------|
|
||||
| SODIUM_LIBRARY_VERSION_MAJOR | |
|
||||
| SODIUM_LIBRARY_VERSION_MINOR | |
|
||||
| crypto_aead_chacha20poly1305_ABYTES | |
|
||||
|
Loading…
x
Reference in New Issue
Block a user