WIP: Fix build/test issues

This commit is contained in:
Johannes Leupold 2024-08-14 11:47:29 +02:00
parent 338c1f0012
commit 9a4a776bbd
14 changed files with 1378 additions and 1152 deletions

View File

@ -17,11 +17,17 @@ const val crypto_core_ed25519_NONREDUCEDSCALARBYTES = 64
const val crypto_scalarmult_ed25519_BYTES = 32U
const val crypto_scalarmult_ed25519_SCALARBYTES = 32U
enum class HashToCurveAlgorithm(val id: Int) {
SHA256(1),
SHA512(2),
}
expect abstract class Ed25519LowLevel() {
fun isValidPoint(encoded: UByteArray): Boolean
fun addPoints(p: UByteArray, q: UByteArray): UByteArray
fun subtractPoints(p: UByteArray, q: UByteArray): UByteArray
fun encodedPointFromHash(hash: UByteArray): UByteArray
fun encodedPointFromString(ctx: String?, msg: UByteArray, hashAlg: HashToCurveAlgorithm): UByteArray
fun encodedPointFromStringRo(ctx: String?, msg: UByteArray, hashAlg: HashToCurveAlgorithm): UByteArray
fun encodedPointFromUniform(uniform: UByteArray): UByteArray
fun randomEncodedPoint(): UByteArray
fun randomEncodedScalar(): UByteArray
@ -45,7 +51,11 @@ object Ed25519 : Ed25519LowLevel() {
fun subtract(p: Point, q: Point): Point =
Point(subtractPoints(p.encoded, q.encoded))
fun pointFromHash(hash: UByteArray): Point = Point(encodedPointFromHash(hash))
fun pointFromString(ctx: String?, msg: UByteArray, hashAlg: HashToCurveAlgorithm): Point =
Point(encodedPointFromString(ctx, msg, hashAlg))
fun pointFromStringRo(ctx: String?, msg: UByteArray, hashAlg: HashToCurveAlgorithm): Point =
Point(encodedPointFromStringRo(ctx, msg, hashAlg))
fun pointFromUniform(uniform: UByteArray): Point = Point(encodedPointFromUniform(uniform))
@ -103,8 +113,6 @@ object Ed25519 : Ed25519LowLevel() {
val IDENTITY: Point = Point(UByteArray(crypto_core_ed25519_BYTES))
val BASE: Point = scalarMultiplicationBaseNoClamp(Scalar.ONE)
fun fromHash(hash: UByteArray): Point = pointFromHash(hash)
fun fromUniform(uniform: UByteArray): Point = pointFromUniform(uniform)
fun random(): Point = randomPoint()

View File

@ -1,5 +1,6 @@
package com.ionspin.kotlin.crypto.ristretto255
import com.ionspin.kotlin.crypto.ed25519.HashToCurveAlgorithm
import com.ionspin.kotlin.crypto.util.LibsodiumUtil
import kotlin.UByteArray
@ -22,6 +23,8 @@ expect abstract class Ristretto255LowLevel() {
fun addPoints(p: UByteArray, q: UByteArray): UByteArray
fun subtractPoints(p: UByteArray, q: UByteArray): UByteArray
fun encodedPointFromHash(hash: UByteArray): UByteArray
fun encodedPointFromString(ctx: String?, msg: UByteArray, hashAlg: HashToCurveAlgorithm): UByteArray
fun encodedPointFromStringRo(ctx: String?, msg: UByteArray, hashAlg: HashToCurveAlgorithm): UByteArray
fun randomEncodedPoint(): UByteArray
fun randomEncodedScalar(): UByteArray
fun invertScalar(scalar: UByteArray): UByteArray
@ -44,6 +47,12 @@ object Ristretto255 : Ristretto255LowLevel() {
fun pointFromHash(hash: UByteArray): Point = Point(encodedPointFromHash(hash))
fun pointFromString(ctx: String?, msg: UByteArray, hashAlg: HashToCurveAlgorithm): Point =
Point(encodedPointFromString(ctx, msg, hashAlg))
fun pointFromStringRo(ctx: String?, msg: UByteArray, hashAlg: HashToCurveAlgorithm): Point =
Point(encodedPointFromStringRo(ctx, msg, hashAlg))
fun randomPoint(): Point = Point(randomEncodedPoint())
fun randomScalar(): Scalar = Scalar(randomEncodedScalar())

View File

@ -1,9 +1,7 @@
package com.ionspin.kotlin.crypto.ed25519
import com.ionspin.kotlin.crypto.LibsodiumInitializer
import com.ionspin.kotlin.crypto.hash.Hash
import com.ionspin.kotlin.crypto.util.LibsodiumUtil
import com.ionspin.kotlin.crypto.util.encodeToUByteArray
import com.ionspin.kotlin.crypto.util.runTest
import kotlin.test.Test
import kotlin.test.assertEquals
@ -183,18 +181,6 @@ class Ed25519Test {
}
}
@Test
fun testPointFromHash() = runTest {
LibsodiumInitializer.initializeWithCallback {
for ((input, output) in fromHashTestVectors) {
val outPoint = Ed25519.Point.fromHex(output)
val hash = Hash.sha512(input.encodeToUByteArray())
assertEquals(outPoint, Ed25519.Point.fromHash(hash))
}
}
}
@Test
fun testPointFromUniform() = runTest {
LibsodiumInitializer.initializeWithCallback {

View File

@ -63,8 +63,6 @@ class Ristretto255Test {
// Test vectors from https://ristretto.group/test_vectors/ristretto255.html
val basePointSmallMultiples = arrayOf(
// This is the identity point
"0000000000000000000000000000000000000000000000000000000000000000",
// This is the basepoint
"e2f2ae0a6abc4e71a884a961c500515f58e30b6aa582dd8db6a65945e08d2d76",
// These are small multiples of the basepoint
@ -131,7 +129,7 @@ class Ristretto255Test {
for (i in basePointSmallMultiples.indices) {
val p = Ristretto255.Point.fromHex(basePointSmallMultiples[i])
val b = Ristretto255.Point.BASE
val n = Ristretto255.Scalar.fromUInt(i.toUInt())
val n = Ristretto255.Scalar.fromUInt(i.toUInt() + 1U)
assertEquals(p, Ristretto255.scalarMultiplicationBase(n))
assertEquals(p, Ristretto255.scalarMultiplication(b, n))
@ -146,7 +144,7 @@ class Ristretto255Test {
assertEquals(q, p - b * m)
}
for (j in i..<basePointSmallMultiples.size) {
for (j in i + 1..<basePointSmallMultiples.size) {
val q = Ristretto255.Point.fromHex(basePointSmallMultiples[j])
val m = Ristretto255.Scalar.fromUInt(j.toUInt() - i.toUInt())

View File

@ -375,6 +375,12 @@ external object JsSodiumInterface {
@JsName("crypto_core_ristretto255_from_hash")
fun crypto_core_ristretto255_from_hash(r: Uint8Array): Uint8Array
@JsName("crypto_core_ristretto255_from_string")
fun crypto_core_ed25519_from_string(ctx: String?, message: Uint8Array, hashAlg: Int): Uint8Array
@JsName("crypto_core_ristretto255_from_string_ro")
fun crypto_core_ed25519_from_string_ro(ctx: String?, message: Uint8Array, hashAlg: Int): Uint8Array
@JsName("crypto_core_ristretto255_add")
fun crypto_core_ristretto255_add(p: Uint8Array, q: Uint8Array): Uint8Array
@ -424,8 +430,11 @@ external object JsSodiumInterface {
@JsName("crypto_core_ed25519_random")
fun crypto_core_ed25519_random(): Uint8Array
@JsName("crypto_core_ed25519_from_hash")
fun crypto_core_ed25519_from_hash(r: Uint8Array): Uint8Array
@JsName("crypto_core_ed25519_from_string")
fun crypto_core_ed25519_from_string(ctx: String, message: Uint8Array, hashAlg: Int): Uint8Array
@JsName("crypto_core_ed25519_from_string_ro")
fun crypto_core_ed25519_from_string_ro(ctx: String, message: Uint8Array, hashAlg: Int): Uint8Array
@JsName("crypto_core_ed25519_from_uniform")
fun crypto_core_ed25519_from_uniform(r: Uint8Array): Uint8Array

View File

@ -6,28 +6,34 @@ import ext.libsodium.com.ionspin.kotlin.crypto.toUInt8Array
actual abstract class Ed25519LowLevel actual constructor() {
actual fun isValidPoint(encoded: UByteArray): Boolean =
getSodium().crypto_core_ed25519_is_valid_point(encoded.toUint8Array())
getSodium().crypto_core_ed25519_is_valid_point(encoded.toUInt8Array())
actual fun addPoints(p: UByteArray, q: UByteArray): UByteArray {
val result = getSodium().crypto_core_ed25519_add(p.toUint8Array(), q.toUint8Array())
val result = getSodium().crypto_core_ed25519_add(p.toUInt8Array(), q.toUInt8Array())
return result.toUByteArray()
}
actual fun subtractPoints(p: UByteArray, q: UByteArray): UByteArray {
val result = getSodium().crypto_core_ed25519_sub(p.toUint8Array(), q.toUint8Array())
val result = getSodium().crypto_core_ed25519_sub(p.toUInt8Array(), q.toUInt8Array())
return result
return result.toUByteArray()
}
actual fun encodedPointFromHash(hash: UByteArray): UByteArray {
val result = getSodium().crypto_core_ed25519_from_hash(hash.toUint8Array())
actual fun encodedPointFromString(ctx: String?, msg: UByteArray, hashAlg: HashToCurveAlgorithm): UByteArray {
val result = getSodium().crypto_core_ed25519_from_string(ctx, msg.toUInt8Array(), hashAlg.id)
return result.toUByteArray()
}
actual fun encodedPointFromStringRo(ctx: String?, msg: UByteArray, hashAlg: HashToCurveAlgorithm): UByteArray {
val result = getSodium().crypto_core_ed25519_from_string_ro(ctx, msg.toUInt8Array(), hashAlg.id)
return result.toUByteArray()
}
actual fun encodedPointFromUniform(uniform: UByteArray): UByteArray {
val result = getSodium().crypto_core_ed25519_from_uniform(hash.toUint8Array())
val result = getSodium().crypto_core_ed25519_from_uniform(uniform.toUInt8Array())
return result.toUByteArray()
}
@ -45,67 +51,67 @@ actual abstract class Ed25519LowLevel actual constructor() {
}
actual fun invertScalar(scalar: UByteArray): UByteArray {
val result = getSodium().crypto_core_ed25519_scalar_invert(scalar.toUint8Array())
val result = getSodium().crypto_core_ed25519_scalar_invert(scalar.toUInt8Array())
return result.toUByteArray()
}
actual fun negateScalar(scalar: UByteArray): UByteArray {
val result = getSodium().crypto_core_ed25519_scalar_negate(scalar.toUint8Array())
val result = getSodium().crypto_core_ed25519_scalar_negate(scalar.toUInt8Array())
return result.toUByteArray()
}
actual fun complementScalar(scalar: UByteArray): UByteArray {
val result = getSodium().crypto_core_ed25519_scalar_complement(scalar.toUint8Array())
val result = getSodium().crypto_core_ed25519_scalar_complement(scalar.toUInt8Array())
return result.toUByteArray()
}
actual fun addScalars(x: UByteArray, y: UByteArray): UByteArray {
val result = getSodium().crypto_core_ed25519_scalar_add(x.toUint8Array(), y.toUint8Array())
val result = getSodium().crypto_core_ed25519_scalar_add(x.toUInt8Array(), y.toUInt8Array())
return result.toUByteArray()
}
actual fun subtractScalars(x: UByteArray, y: UByteArray): UByteArray {
val result = getSodium().crypto_core_ed25519_scalar_sub(x.toUint8Array(), y.toUint8Array())
val result = getSodium().crypto_core_ed25519_scalar_sub(x.toUInt8Array(), y.toUInt8Array())
return result.toUByteArray()
}
actual fun multiplyScalars(x: UByteArray, y: UByteArray): UByteArray {
val result = getSodium().crypto_core_ed25519_scalar_mul(x.toUint8Array(), y.toUint8Array())
val result = getSodium().crypto_core_ed25519_scalar_mul(x.toUInt8Array(), y.toUInt8Array())
return result.toUByteArray()
}
actual fun reduceScalar(scalar: UByteArray): UByteArray {
val result = getSodium().crypto_core_ed25519_scalar_reduce(scalar.toUint8Array())
val result = getSodium().crypto_core_ed25519_scalar_reduce(scalar.toUInt8Array())
return result.toUByteArray()
}
actual fun scalarMultiplication(n: UByteArray, p: UByteArray): UByteArray {
val result = getSodium().crypto_scalarmult_ed25519(n.toUint8Array(), p.toUint8Array())
val result = getSodium().crypto_scalarmult_ed25519(n.toUInt8Array(), p.toUInt8Array())
return result.toUByteArray()
}
actual fun scalarMultiplicationNoClamp(n: UByteArray, p: UByteArray): UByteArray {
val result = getSodium().crypto_scalarmult_ed25519_noclamp(n.toUint8Array(), p.toUint8Array())
val result = getSodium().crypto_scalarmult_ed25519_noclamp(n.toUInt8Array(), p.toUInt8Array())
return result.toUByteArray()
}
actual fun scalarMultiplicationBase(n: UByteArray): UByteArray {
val result = getSodium().crypto_scalarmult_ed25519_base(n.toUint8Array())
val result = getSodium().crypto_scalarmult_ed25519_base(n.toUInt8Array())
return result.toUByteArray()
}
actual fun scalarMultiplicationBaseNoClamp(n: UByteArray): UByteArray {
val result = getSodium().crypto_scalarmult_ed25519_base_noclamp(n.toUint8Array())
val result = getSodium().crypto_scalarmult_ed25519_base_noclamp(n.toUInt8Array())
return result.toUByteArray()
}

View File

@ -6,22 +6,34 @@ import ext.libsodium.com.ionspin.kotlin.crypto.toUInt8Array
actual abstract class Ristretto255LowLevel actual constructor() {
actual fun isValidPoint(encoded: UByteArray): Boolean =
getSodium().crypto_core_ristretto255_is_valid_point(encoded.toUint8Array())
getSodium().crypto_core_ristretto255_is_valid_point(encoded.toUInt8Array())
actual fun addPoints(p: UByteArray, q: UByteArray): UByteArray {
val result = getSodium().crypto_core_ristretto255_add(p.toUint8Array(), q.toUint8Array())
val result = getSodium().crypto_core_ristretto255_add(p.toUInt8Array(), q.toUInt8Array())
return result.toUByteArray()
}
actual fun subtractPoints(p: UByteArray, q: UByteArray): UByteArray {
val result = getSodium().crypto_core_ristretto255_sub(p.toUint8Array(), q.toUint8Array())
val result = getSodium().crypto_core_ristretto255_sub(p.toUInt8Array(), q.toUInt8Array())
return result
return result.toUByteArray()
}
actual fun encodedPointFromHash(hash: UByteArray): UByteArray {
val result = getSodium().crypto_core_ristretto255_from_hash(hash.toUint8Array())
val result = getSodium().crypto_core_ristretto255_from_hash(hash.toUInt8Array())
return result.toUByteArray()
}
actual fun encodedPointFromString(ctx: String?, msg: UByteArray, hashAlg: HashToCurveAlgorithm): UByteArray {
val result = getSodium().crypto_core_ristretto255_from_string(ctx, msg.toUInt8Array(), hashAlg.id)
return result.toUByteArray()
}
actual fun encodedPointFromStringRo(ctx: String?, msg: UByteArray, hashAlg: HashToCurveAlgorithm): UByteArray {
val result = getSodium().crypto_core_ristretto255_from_string_ro(ctx, msg.toUInt8Array(), hashAlg.id)
return result.toUByteArray()
}
@ -39,55 +51,55 @@ actual abstract class Ristretto255LowLevel actual constructor() {
}
actual fun invertScalar(scalar: UByteArray): UByteArray {
val result = getSodium().crypto_core_ristretto255_scalar_invert(scalar.toUint8Array())
val result = getSodium().crypto_core_ristretto255_scalar_invert(scalar.toUInt8Array())
return result.toUByteArray()
}
actual fun negateScalar(scalar: UByteArray): UByteArray {
val result = getSodium().crypto_core_ristretto255_scalar_negate(scalar.toUint8Array())
val result = getSodium().crypto_core_ristretto255_scalar_negate(scalar.toUInt8Array())
return result.toUByteArray()
}
actual fun complementScalar(scalar: UByteArray): UByteArray {
val result = getSodium().crypto_core_ristretto255_scalar_complement(scalar.toUint8Array())
val result = getSodium().crypto_core_ristretto255_scalar_complement(scalar.toUInt8Array())
return result.toUByteArray()
}
actual fun addScalars(x: UByteArray, y: UByteArray): UByteArray {
val result = getSodium().crypto_core_ristretto255_scalar_add(x.toUint8Array(), y.toUint8Array())
val result = getSodium().crypto_core_ristretto255_scalar_add(x.toUInt8Array(), y.toUInt8Array())
return result.toUByteArray()
}
actual fun subtractScalars(x: UByteArray, y: UByteArray): UByteArray {
val result = getSodium().crypto_core_ristretto255_scalar_sub(x.toUint8Array(), y.toUint8Array())
val result = getSodium().crypto_core_ristretto255_scalar_sub(x.toUInt8Array(), y.toUInt8Array())
return result.toUByteArray()
}
actual fun multiplyScalars(x: UByteArray, y: UByteArray): UByteArray {
val result = getSodium().crypto_core_ristretto255_scalar_mul(x.toUint8Array(), y.toUint8Array())
val result = getSodium().crypto_core_ristretto255_scalar_mul(x.toUInt8Array(), y.toUInt8Array())
return result.toUByteArray()
}
actual fun reduceScalar(scalar: UByteArray): UByteArray {
val result = getSodium().crypto_core_ristretto255_scalar_reduce(scalar.toUint8Array())
val result = getSodium().crypto_core_ristretto255_scalar_reduce(scalar.toUInt8Array())
return result.toUByteArray()
}
actual fun scalarMultiplication(n: UByteArray, p: UByteArray): UByteArray {
val result = getSodium().crypto_scalarmult_ristretto255(n.toUint8Array(), p.toUint8Array())
val result = getSodium().crypto_scalarmult_ristretto255(n.toUInt8Array(), p.toUInt8Array())
return result.toUByteArray()
}
actual fun scalarMultiplicationBase(n: UByteArray): UByteArray {
val result = getSodium().crypto_scalarmult_ristretto255_base(n.toUint8Array())
val result = getSodium().crypto_scalarmult_ristretto255_base(n.toUInt8Array())
return result.toUByteArray()
}

View File

@ -2,7 +2,7 @@ package com.ionspin.kotlin.crypto.ed25519
import com.ionspin.kotlin.crypto.GeneralLibsodiumException.Companion.ensureLibsodiumSuccess
import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodiumJna
import kotlin.UByteArray
import com.ionspin.kotlin.crypto.util.toCString
actual abstract class Ed25519LowLevel actual constructor() {
actual fun isValidPoint(encoded: UByteArray): Boolean =
@ -26,10 +26,32 @@ actual abstract class Ed25519LowLevel actual constructor() {
return result
}
actual fun encodedPointFromHash(hash: UByteArray): UByteArray {
actual fun encodedPointFromString(ctx: String?, msg: UByteArray, hashAlg: HashToCurveAlgorithm): UByteArray {
val result = UByteArray(crypto_core_ed25519_BYTES)
val ctxEncoded = ctx?.toCString()
sodiumJna.crypto_core_ed25519_from_hash(result.asByteArray(), hash.asByteArray())
sodiumJna.crypto_core_ed25519_from_string(
result.asByteArray(),
ctxEncoded?.asByteArray(),
msg.asByteArray(),
msg.size,
hashAlg.id
).ensureLibsodiumSuccess()
return result
}
actual fun encodedPointFromStringRo(ctx: String?, msg: UByteArray, hashAlg: HashToCurveAlgorithm): UByteArray {
val result = UByteArray(crypto_core_ed25519_BYTES)
val ctxEncoded = ctx?.toCString()
sodiumJna.crypto_core_ed25519_from_string_ro(
result.asByteArray(),
ctxEncoded?.asByteArray(),
msg.asByteArray(),
msg.size,
hashAlg.id
).ensureLibsodiumSuccess()
return result
}

View File

@ -2,7 +2,8 @@ package com.ionspin.kotlin.crypto.ristretto255
import com.ionspin.kotlin.crypto.GeneralLibsodiumException.Companion.ensureLibsodiumSuccess
import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodiumJna
import kotlin.UByteArray
import com.ionspin.kotlin.crypto.ed25519.HashToCurveAlgorithm
import com.ionspin.kotlin.crypto.util.toCString
actual abstract class Ristretto255LowLevel actual constructor() {
actual fun isValidPoint(encoded: UByteArray): Boolean =
@ -34,6 +35,36 @@ actual abstract class Ristretto255LowLevel actual constructor() {
return result
}
actual fun encodedPointFromString(ctx: String?, msg: UByteArray, hashAlg: HashToCurveAlgorithm): UByteArray {
val result = UByteArray(crypto_core_ristretto255_BYTES)
val ctxEncoded = ctx?.toCString()
sodiumJna.crypto_core_ristretto255_from_string(
result.asByteArray(),
ctxEncoded?.asByteArray(),
msg.asByteArray(),
msg.size,
hashAlg.id
).ensureLibsodiumSuccess()
return result
}
actual fun encodedPointFromStringRo(ctx: String?, msg: UByteArray, hashAlg: HashToCurveAlgorithm): UByteArray {
val result = UByteArray(crypto_core_ristretto255_BYTES)
val ctxEncoded = ctx?.toCString()
sodiumJna.crypto_core_ristretto255_from_string_ro(
result.asByteArray(),
ctxEncoded?.asByteArray(),
msg.asByteArray(),
msg.size,
hashAlg.id
).ensureLibsodiumSuccess()
return result
}
actual fun randomEncodedPoint(): UByteArray = UByteArray(crypto_core_ristretto255_BYTES).also {
sodiumJna.crypto_core_ristretto255_random(it.asByteArray())
}

View File

@ -0,0 +1,12 @@
package com.ionspin.kotlin.crypto.util
fun String.toCString(): UByteArray {
val encoded = encodeToUByteArray()
val cStr = UByteArray(encoded.size + 1)
encoded.copyInto(cStr)
LibsodiumUtil.memzero(encoded)
return cStr
}

View File

@ -1,10 +1,11 @@
package com.ionspin.kotlin.crypto.ed25519
import com.ionspin.kotlin.crypto.GeneralLibsodiumException.Companion.ensureLibsodiumSuccess
import com.ionspin.kotlin.crypto.util.toCString
import com.ionspin.kotlin.crypto.util.toPtr
import kotlinx.cinterop.usePinned
import libsodium.crypto_core_ed25519_add
import libsodium.crypto_core_ed25519_from_hash
import libsodium.crypto_core_ed25519_from_string
import libsodium.crypto_core_ed25519_from_uniform
import libsodium.crypto_core_ed25519_is_valid_point
import libsodium.crypto_core_ed25519_random
@ -58,12 +59,53 @@ actual abstract class Ed25519LowLevel actual constructor() {
return result
}
actual fun encodedPointFromHash(hash: UByteArray): UByteArray {
actual fun encodedPointFromString(ctx: String?, msg: UByteArray, hashAlg: HashToCurveAlgorithm): UByteArray {
val result = UByteArray(crypto_core_ed25519_BYTES)
val ctxEncoded = ctx?.toCString()
result.usePinned { resultPinned ->
hash.usePinned { hashPinned ->
crypto_core_ed25519_from_hash(resultPinned.toPtr(), hashPinned.toPtr())
msg.usePinned { msgPinned ->
if (ctxEncoded == null) {
crypto_core_ed25519_from_string(resultPinned.toPtr(), null, msgPinned.toPtr(), msg.size, hashAlg.id)
.ensureLibsodiumSuccess()
} else {
ctxEncoded.usePinned { ctxPinned ->
crypto_core_ed25519_from_string(
resultPinned.toPtr(),
ctxPinned.toPtr(),
msgPinned.toPtr(),
msg.size,
hashAlg.id
)
.ensureLibsodiumSuccess()
}
}
}
}
return result
}
actual fun encodedPointFromStringRo(ctx: String?, msg: UByteArray, hashAlg: HashToCurveAlgorithm): UByteArray {
val result = UByteArray(crypto_core_ed25519_BYTES)
val ctxEncoded = ctx?.toCString()
result.usePinned { resultPinned ->
msg.usePinned { msgPinned ->
if (ctxEncoded == null) {
crypto_core_ed25519_from_string_ro(resultPinned.toPtr(), null, msgPinned.toPtr(), msg.size, hashAlg.id)
.ensureLibsodiumSuccess()
} else {
ctxEncoded.usePinned { ctxPinned ->
crypto_core_ed25519_from_string_ro(
resultPinned.toPtr(),
ctxPinned.toPtr(),
msgPinned.toPtr(),
msg.size,
hashAlg.id
).ensureLibsodiumSuccess()
}
}
}
}

View File

@ -1,10 +1,14 @@
package com.ionspin.kotlin.crypto.ristretto255
import com.ionspin.kotlin.crypto.GeneralLibsodiumException.Companion.ensureLibsodiumSuccess
import com.ionspin.kotlin.crypto.ed25519.HashToCurveAlgorithm
import com.ionspin.kotlin.crypto.util.toCString
import com.ionspin.kotlin.crypto.util.toPtr
import kotlinx.cinterop.usePinned
import libsodium.crypto_core_ristretto255_add
import libsodium.crypto_core_ristretto255_from_hash
import libsodium.crypto_core_ristretto255_from_string
import libsodium.crypto_core_ristretto255_from_string_ro
import libsodium.crypto_core_ristretto255_is_valid_point
import libsodium.crypto_core_ristretto255_random
import libsodium.crypto_core_ristretto255_scalar_add
@ -67,6 +71,59 @@ actual abstract class Ristretto255LowLevel actual constructor() {
return result
}
actual fun encodedPointFromString(ctx: String?, msg: UByteArray, hashAlg: HashToCurveAlgorithm): UByteArray {
val result = UByteArray(crypto_core_ristretto255_BYTES)
val ctxEncoded = ctx?.toCString()
result.usePinned { resultPinned ->
msg.usePinned { msgPinned ->
if (ctxEncoded == null) {
crypto_core_ristretto255_from_string(resultPinned.toPtr(), null, msgPinned.toPtr(), msg.size, hashAlg.id)
.ensureLibsodiumSuccess()
} else {
ctxEncoded.usePinned { ctxPinned ->
crypto_core_ristretto255_from_string(
resultPinned.toPtr(),
ctxPinned.toPtr(),
msgPinned.toPtr(),
msg.size,
hashAlg.id
)
.ensureLibsodiumSuccess()
}
}
}
}
return result
}
actual fun encodedPointFromStringRo(ctx: String?, msg: UByteArray, hashAlg: HashToCurveAlgorithm): UByteArray {
val result = UByteArray(crypto_core_ristretto255_BYTES)
val ctxEncoded = ctx?.toCString()
result.usePinned { resultPinned ->
msg.usePinned { msgPinned ->
if (ctxEncoded == null) {
crypto_core_ristretto255_from_string_ro(resultPinned.toPtr(), null, msgPinned.toPtr(), msg.size, hashAlg.id)
.ensureLibsodiumSuccess()
} else {
ctxEncoded.usePinned { ctxPinned ->
crypto_core_ristretto255_from_string_ro(
resultPinned.toPtr(),
ctxPinned.toPtr(),
msgPinned.toPtr(),
msg.size,
hashAlg.id
).ensureLibsodiumSuccess()
}
}
}
}
return result
}
actual fun randomEncodedPoint(): UByteArray = UByteArray(crypto_core_ristretto255_BYTES).apply {
usePinned { crypto_core_ristretto255_random(it.toPtr()) }
}

View File

@ -4,7 +4,6 @@ import kotlinx.cinterop.CPointer
import kotlinx.cinterop.Pinned
import kotlinx.cinterop.UByteVar
import kotlinx.cinterop.addressOf
import kotlinx.cinterop.toCPointer
/**
* Created by Ugljesa Jovanovic
@ -18,3 +17,14 @@ fun Pinned<UByteArray>.toPtr() : CPointer<UByteVar>? {
null
}
}
fun String.toCString(): UByteArray {
val encoded = encodeToUByteArray()
val cStr = UByteArray(encoded.size + 1)
encoded.copyInto(cStr)
LibsodiumUtil.memzero(encoded)
return cStr
}