Add Ed25519 arithmetic and fix more bugs
This commit is contained in:
parent
e785bde585
commit
fafa0aa0c5
@ -0,0 +1,196 @@
|
|||||||
|
package com.ionspin.kotlin.crypto.ed25519
|
||||||
|
|
||||||
|
import com.ionspin.kotlin.crypto.util.LibsodiumUtil
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Johannes Leupold
|
||||||
|
* johannes.leupold@kobil.com
|
||||||
|
* on 12-Aug-2024
|
||||||
|
*/
|
||||||
|
|
||||||
|
const val crypto_core_ed25519_BYTES = 32
|
||||||
|
const val crypto_core_ed25519_UNIFORMBYTES = 32
|
||||||
|
const val crypto_core_ed25519_HASHBYTES = 64
|
||||||
|
const val crypto_core_ed25519_SCALARBYTES = 32
|
||||||
|
const val crypto_core_ed25519_NONREDUCEDSCALARBYTES = 64
|
||||||
|
|
||||||
|
const val crypto_scalarmult_ed25519_BYTES = 32U
|
||||||
|
const val crypto_scalarmult_ed25519_SCALARBYTES = 32U
|
||||||
|
|
||||||
|
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 encodedPointFromUniform(uniform: UByteArray): UByteArray
|
||||||
|
fun randomEncodedPoint(): UByteArray
|
||||||
|
fun randomEncodedScalar(): UByteArray
|
||||||
|
fun invertScalar(scalar: UByteArray): UByteArray
|
||||||
|
fun negateScalar(scalar: UByteArray): UByteArray
|
||||||
|
fun complementScalar(scalar: UByteArray): UByteArray
|
||||||
|
fun addScalars(x: UByteArray, y: UByteArray): UByteArray
|
||||||
|
fun subtractScalars(x: UByteArray, y: UByteArray): UByteArray
|
||||||
|
fun multiplyScalars(x: UByteArray, y: UByteArray): UByteArray
|
||||||
|
fun reduceScalar(scalar: UByteArray): UByteArray
|
||||||
|
fun scalarMultiplication(n: UByteArray, p: UByteArray): UByteArray
|
||||||
|
fun scalarMultiplicationNoClamp(n: UByteArray, p: UByteArray): UByteArray
|
||||||
|
fun scalarMultiplicationBase(n: UByteArray): UByteArray
|
||||||
|
fun scalarMultiplicationBaseNoClamp(n: UByteArray): UByteArray
|
||||||
|
}
|
||||||
|
|
||||||
|
object Ed25519 : Ed25519LowLevel() {
|
||||||
|
fun add(p: Point, q: Point): Point =
|
||||||
|
Point(addPoints(p.encoded, q.encoded))
|
||||||
|
|
||||||
|
fun subtract(p: Point, q: Point): Point =
|
||||||
|
Point(subtractPoints(p.encoded, q.encoded))
|
||||||
|
|
||||||
|
fun pointFromHash(hash: UByteArray): Point = Point(encodedPointFromHash(hash))
|
||||||
|
|
||||||
|
fun pointFromUniform(uniform: UByteArray): Point = Point(encodedPointFromUniform(uniform))
|
||||||
|
|
||||||
|
fun randomPoint(): Point = Point(randomEncodedPoint())
|
||||||
|
|
||||||
|
fun randomScalar(): Scalar = Scalar(randomEncodedScalar())
|
||||||
|
|
||||||
|
fun invert(scalar: Scalar): Scalar =
|
||||||
|
Scalar(invertScalar(scalar.encoded))
|
||||||
|
|
||||||
|
fun negate(scalar: Scalar): Scalar =
|
||||||
|
Scalar(negateScalar(scalar.encoded))
|
||||||
|
|
||||||
|
fun complement(scalar: Scalar): Scalar =
|
||||||
|
Scalar(complementScalar(scalar.encoded))
|
||||||
|
|
||||||
|
fun add(x: Scalar, y: Scalar): Scalar =
|
||||||
|
Scalar(addScalars(x.encoded, y.encoded))
|
||||||
|
|
||||||
|
fun subtract(x: Scalar, y: Scalar): Scalar =
|
||||||
|
Scalar(subtractScalars(x.encoded, y.encoded))
|
||||||
|
|
||||||
|
fun multiply(x: Scalar, y: Scalar): Scalar =
|
||||||
|
Scalar(multiplyScalars(x.encoded, y.encoded))
|
||||||
|
|
||||||
|
fun reduce(scalar: Scalar): Scalar =
|
||||||
|
Scalar(reduceScalar(scalar.encoded))
|
||||||
|
|
||||||
|
fun scalarMultiplication(p: Point, n: Scalar): Point =
|
||||||
|
Point(scalarMultiplication(n.encoded, p.encoded))
|
||||||
|
|
||||||
|
fun scalarMultiplicationNoClamp(p: Point, n: Scalar): Point =
|
||||||
|
Point(scalarMultiplicationNoClamp(n.encoded, p.encoded))
|
||||||
|
|
||||||
|
fun scalarMultiplicationBase(n: Scalar): Point =
|
||||||
|
Point(scalarMultiplicationBase(n.encoded))
|
||||||
|
|
||||||
|
fun scalarMultiplicationBaseNoClamp(n: Scalar): Point =
|
||||||
|
Point(scalarMultiplicationBaseNoClamp(n.encoded))
|
||||||
|
|
||||||
|
data class Point(val encoded: UByteArray) {
|
||||||
|
operator fun plus(q: Point): Point = add(this, q)
|
||||||
|
operator fun minus(q: Point): Point = subtract(this, q)
|
||||||
|
|
||||||
|
operator fun times(n: Scalar): Point = scalarMultiplication(this, n)
|
||||||
|
fun times(n: Scalar, clamp: Boolean): Point =
|
||||||
|
if (clamp) scalarMultiplication(this, n) else scalarMultiplicationNoClamp(this, n)
|
||||||
|
|
||||||
|
fun toHex(): String = LibsodiumUtil.toHex(encoded)
|
||||||
|
|
||||||
|
override fun equals(other: Any?): Boolean = (other as? Point)?.encoded?.contentEquals(encoded) == true
|
||||||
|
override fun hashCode(): Int = encoded.contentHashCode()
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val IDENTITY: Point = Point(UByteArray(crypto_core_ed25519_BYTES))
|
||||||
|
val BASE: Point = scalarMultiplicationBase(Scalar.ONE)
|
||||||
|
|
||||||
|
fun fromHash(hash: UByteArray): Point = pointFromHash(hash)
|
||||||
|
|
||||||
|
fun fromUniform(uniform: UByteArray): Point = pointFromUniform(uniform)
|
||||||
|
|
||||||
|
fun random(): Point = randomPoint()
|
||||||
|
|
||||||
|
fun multiplyBase(n: Scalar): Point = scalarMultiplicationBase(n)
|
||||||
|
|
||||||
|
fun multiplyBaseNoClamp(n: Scalar): Point = scalarMultiplicationBaseNoClamp(n)
|
||||||
|
|
||||||
|
fun fromHex(hex: String): Point = Point(LibsodiumUtil.fromHex(hex))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data class Scalar(val encoded: UByteArray) {
|
||||||
|
operator fun plus(y: Scalar): Scalar = add(this, y)
|
||||||
|
operator fun plus(y: UInt): Scalar = this + fromUInt(y)
|
||||||
|
operator fun plus(y: ULong): Scalar = this + fromULong(y)
|
||||||
|
|
||||||
|
operator fun minus(y: Scalar): Scalar = subtract(this, y)
|
||||||
|
operator fun minus(y: UInt): Scalar = this - fromUInt(y)
|
||||||
|
operator fun minus(y: ULong): Scalar = this - fromULong(y)
|
||||||
|
|
||||||
|
operator fun times(y: Scalar): Scalar = multiply(this, y)
|
||||||
|
operator fun times(y: UInt): Scalar = this * fromUInt(y)
|
||||||
|
operator fun times(y: ULong): Scalar = this * fromULong(y)
|
||||||
|
|
||||||
|
operator fun div(y: Scalar): Scalar = multiply(this, invert(y))
|
||||||
|
operator fun div(y: UInt): Scalar = this / fromUInt(y)
|
||||||
|
operator fun div(y: ULong): Scalar = this / fromULong(y)
|
||||||
|
|
||||||
|
operator fun unaryMinus(): Scalar = negate(this)
|
||||||
|
|
||||||
|
operator fun times(p: Point): Point = scalarMultiplication(p, this)
|
||||||
|
fun times(p: Point, clamp: Boolean): Point =
|
||||||
|
if (clamp) scalarMultiplication(p, this) else scalarMultiplicationNoClamp(p, this)
|
||||||
|
|
||||||
|
fun reduce(): Scalar = reduce(this)
|
||||||
|
fun invert(): Scalar = invert(this)
|
||||||
|
fun complement(): Scalar = complement(this)
|
||||||
|
|
||||||
|
fun multiplyWithBase(): Point = scalarMultiplicationBase(this)
|
||||||
|
|
||||||
|
fun multiplyWithBaseNoClamp(): Point = scalarMultiplicationBaseNoClamp(this)
|
||||||
|
|
||||||
|
fun toHex(): String = LibsodiumUtil.toHex(encoded)
|
||||||
|
|
||||||
|
override fun equals(other: Any?): Boolean = (other as? Scalar)?.encoded?.contentEquals(encoded) == true
|
||||||
|
override fun hashCode(): Int = encoded.contentHashCode()
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val ZERO = fromUInt(0U)
|
||||||
|
val ONE = fromUInt(1U)
|
||||||
|
val TWO = fromUInt(2U)
|
||||||
|
|
||||||
|
fun random(): Scalar = randomScalar()
|
||||||
|
|
||||||
|
fun fromUInt(i: UInt): Scalar = fromULong(i.toULong())
|
||||||
|
|
||||||
|
fun fromULong(l: ULong): Scalar {
|
||||||
|
val encoded = UByteArray(crypto_core_ed25519_SCALARBYTES)
|
||||||
|
var rem = l
|
||||||
|
|
||||||
|
for (i in 0..7) {
|
||||||
|
encoded[i] = (rem and 0xffU).toUByte()
|
||||||
|
rem = rem shr 8
|
||||||
|
}
|
||||||
|
|
||||||
|
return Scalar(encoded)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun fromHex(hex: String): Scalar {
|
||||||
|
require(hex.length <= 2 * crypto_core_ed25519_NONREDUCEDSCALARBYTES) {
|
||||||
|
"Scalars must be at most $crypto_core_ed25519_NONREDUCEDSCALARBYTES bytes long"
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hex.length > 2 * crypto_core_ed25519_SCALARBYTES) {
|
||||||
|
val encoded = LibsodiumUtil.fromHex(hex.padEnd(2 * crypto_core_ed25519_NONREDUCEDSCALARBYTES, '0'))
|
||||||
|
// Scalars are encoded in little-endian order, so the end can be padded with zeroes up to the size of a
|
||||||
|
// non-reduced scalar. After decoding, it is reduced, to obtain a scalar in the canonical range
|
||||||
|
return Scalar(reduceScalar(encoded))
|
||||||
|
} else {
|
||||||
|
val encoded = LibsodiumUtil.fromHex(hex.padEnd(2 * crypto_core_ed25519_SCALARBYTES, '0'))
|
||||||
|
// Scalars are encoded in little-endian order, so the end can be padded with zeroes up to the size of a
|
||||||
|
// scalar.
|
||||||
|
return Scalar(encoded)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -24,13 +24,13 @@ expect abstract class Ristretto255LowLevel() {
|
|||||||
fun encodedPointFromHash(hash: UByteArray): UByteArray
|
fun encodedPointFromHash(hash: UByteArray): UByteArray
|
||||||
fun randomEncodedPoint(): UByteArray
|
fun randomEncodedPoint(): UByteArray
|
||||||
fun randomEncodedScalar(): UByteArray
|
fun randomEncodedScalar(): UByteArray
|
||||||
fun invert(scalar: UByteArray): UByteArray
|
fun invertScalar(scalar: UByteArray): UByteArray
|
||||||
fun negate(scalar: UByteArray): UByteArray
|
fun negateScalar(scalar: UByteArray): UByteArray
|
||||||
fun complement(scalar: UByteArray): UByteArray
|
fun complementScalar(scalar: UByteArray): UByteArray
|
||||||
fun addScalars(x: UByteArray, y: UByteArray): UByteArray
|
fun addScalars(x: UByteArray, y: UByteArray): UByteArray
|
||||||
fun subtractScalars(x: UByteArray, y: UByteArray): UByteArray
|
fun subtractScalars(x: UByteArray, y: UByteArray): UByteArray
|
||||||
fun multiplyScalars(x: UByteArray, y: UByteArray): UByteArray
|
fun multiplyScalars(x: UByteArray, y: UByteArray): UByteArray
|
||||||
fun reduce(scalar: UByteArray): UByteArray
|
fun reduceScalar(scalar: UByteArray): UByteArray
|
||||||
fun scalarMultiplication(n: UByteArray, p: UByteArray): UByteArray
|
fun scalarMultiplication(n: UByteArray, p: UByteArray): UByteArray
|
||||||
fun scalarMultiplicationBase(n: UByteArray): UByteArray
|
fun scalarMultiplicationBase(n: UByteArray): UByteArray
|
||||||
}
|
}
|
||||||
@ -49,13 +49,13 @@ object Ristretto255 : Ristretto255LowLevel() {
|
|||||||
fun randomScalar(): Scalar = Scalar(randomEncodedScalar())
|
fun randomScalar(): Scalar = Scalar(randomEncodedScalar())
|
||||||
|
|
||||||
fun invert(scalar: Scalar): Scalar =
|
fun invert(scalar: Scalar): Scalar =
|
||||||
Scalar(invert(scalar.encoded))
|
Scalar(invertScalar(scalar.encoded))
|
||||||
|
|
||||||
fun negate(scalar: Scalar): Scalar =
|
fun negate(scalar: Scalar): Scalar =
|
||||||
Scalar(negate(scalar.encoded))
|
Scalar(negateScalar(scalar.encoded))
|
||||||
|
|
||||||
fun complement(scalar: Scalar): Scalar =
|
fun complement(scalar: Scalar): Scalar =
|
||||||
Scalar(complement(scalar.encoded))
|
Scalar(complementScalar(scalar.encoded))
|
||||||
|
|
||||||
fun add(x: Scalar, y: Scalar): Scalar =
|
fun add(x: Scalar, y: Scalar): Scalar =
|
||||||
Scalar(addScalars(x.encoded, y.encoded))
|
Scalar(addScalars(x.encoded, y.encoded))
|
||||||
@ -67,7 +67,7 @@ object Ristretto255 : Ristretto255LowLevel() {
|
|||||||
Scalar(multiplyScalars(x.encoded, y.encoded))
|
Scalar(multiplyScalars(x.encoded, y.encoded))
|
||||||
|
|
||||||
fun reduce(scalar: Scalar): Scalar =
|
fun reduce(scalar: Scalar): Scalar =
|
||||||
Scalar(reduce(scalar.encoded))
|
Scalar(reduceScalar(scalar.encoded))
|
||||||
|
|
||||||
fun scalarMultiplication(p: Point, n: Scalar): Point =
|
fun scalarMultiplication(p: Point, n: Scalar): Point =
|
||||||
Point(scalarMultiplication(n.encoded, p.encoded))
|
Point(scalarMultiplication(n.encoded, p.encoded))
|
||||||
@ -162,7 +162,7 @@ object Ristretto255 : Ristretto255LowLevel() {
|
|||||||
val encoded = LibsodiumUtil.fromHex(hex.padEnd(2 * crypto_core_ristretto255_NONREDUCEDSCALARBYTES, '0'))
|
val encoded = LibsodiumUtil.fromHex(hex.padEnd(2 * crypto_core_ristretto255_NONREDUCEDSCALARBYTES, '0'))
|
||||||
// Scalars are encoded in little-endian order, so the end can be padded with zeroes up to the size of a
|
// Scalars are encoded in little-endian order, so the end can be padded with zeroes up to the size of a
|
||||||
// non-reduced scalar. After decoding, it is reduced, to obtain a scalar in the canonical range
|
// non-reduced scalar. After decoding, it is reduced, to obtain a scalar in the canonical range
|
||||||
return Scalar(reduce(encoded))
|
return Scalar(reduceScalar(encoded))
|
||||||
} else {
|
} else {
|
||||||
val encoded = LibsodiumUtil.fromHex(hex.padEnd(2 * crypto_core_ristretto255_SCALARBYTES, '0'))
|
val encoded = LibsodiumUtil.fromHex(hex.padEnd(2 * crypto_core_ristretto255_SCALARBYTES, '0'))
|
||||||
// Scalars are encoded in little-endian order, so the end can be padded with zeroes up to the size of a
|
// Scalars are encoded in little-endian order, so the end can be padded with zeroes up to the size of a
|
||||||
|
@ -413,4 +413,65 @@ external object JsSodiumInterface {
|
|||||||
|
|
||||||
//
|
//
|
||||||
// ---- Ristretto255 end ----
|
// ---- Ristretto255 end ----
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// ---- Ed25519 ----
|
||||||
|
|
||||||
|
@JsName("crypto_core_ed25519_is_valid_point")
|
||||||
|
fun crypto_core_ed25519_is_valid_point(p: Uint8Array): Boolean
|
||||||
|
|
||||||
|
@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_uniform")
|
||||||
|
fun crypto_core_ed25519_from_uniform(r: Uint8Array): Uint8Array
|
||||||
|
|
||||||
|
@JsName("crypto_core_ed25519_add")
|
||||||
|
fun crypto_core_ed25519_add(p: Uint8Array, q: Uint8Array): Uint8Array
|
||||||
|
|
||||||
|
@JsName("crypto_core_ed25519_sub")
|
||||||
|
fun crypto_core_ed25519_sub(p: Uint8Array, q: Uint8Array): Uint8Array
|
||||||
|
|
||||||
|
@JsName("crypto_core_ed25519_scalar_random")
|
||||||
|
fun crypto_core_ed25519_scalar_random(): Uint8Array
|
||||||
|
|
||||||
|
@JsName("crypto_core_ed25519_scalar_reduce")
|
||||||
|
fun crypto_core_ed25519_scalar_reduce(s: Uint8Array): Uint8Array
|
||||||
|
|
||||||
|
@JsName("crypto_core_ed25519_scalar_invert")
|
||||||
|
fun crypto_core_ed25519_scalar_invert(s: Uint8Array): Uint8Array
|
||||||
|
|
||||||
|
@JsName("crypto_core_ed25519_scalar_negate")
|
||||||
|
fun crypto_core_ed25519_scalar_negate(s: Uint8Array): Uint8Array
|
||||||
|
|
||||||
|
@JsName("crypto_core_ed25519_scalar_complement")
|
||||||
|
fun crypto_core_ed25519_scalar_complement(s: Uint8Array): Uint8Array
|
||||||
|
|
||||||
|
@JsName("crypto_core_ed25519_scalar_add")
|
||||||
|
fun crypto_core_ed25519_scalar_add(x: Uint8Array, y: Uint8Array): Uint8Array
|
||||||
|
|
||||||
|
@JsName("crypto_core_ed25519_scalar_sub")
|
||||||
|
fun crypto_core_ed25519_scalar_sub(x: Uint8Array, y: Uint8Array): Uint8Array
|
||||||
|
|
||||||
|
@JsName("crypto_core_ed25519_scalar_mul")
|
||||||
|
fun crypto_core_ed25519_scalar_mul(x: Uint8Array, y: Uint8Array): Uint8Array
|
||||||
|
|
||||||
|
@JsName("crypto_scalarmult_ed25519")
|
||||||
|
fun crypto_scalarmult_ed25519(n: Uint8Array, p: Uint8Array): Uint8Array
|
||||||
|
|
||||||
|
@JsName("crypto_scalarmult_ed25519_noclamp")
|
||||||
|
fun crypto_scalarmult_ed25519_noclamp(n: Uint8Array, p: Uint8Array): Uint8Array
|
||||||
|
|
||||||
|
@JsName("crypto_scalarmult_ed25519_base")
|
||||||
|
fun crypto_scalarmult_ed25519_base(n: Uint8Array): Uint8Array
|
||||||
|
|
||||||
|
@JsName("crypto_scalarmult_ed25519_base_noclamp")
|
||||||
|
fun crypto_scalarmult_ed25519_base_noclamp(n: Uint8Array): Uint8Array
|
||||||
|
|
||||||
|
//
|
||||||
|
// ---- Ed25519 end ----
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,112 @@
|
|||||||
|
package com.ionspin.kotlin.crypto.ed25519
|
||||||
|
|
||||||
|
import com.ionspin.kotlin.crypto.getSodium
|
||||||
|
import ext.libsodium.com.ionspin.kotlin.crypto.toUByteArray
|
||||||
|
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())
|
||||||
|
|
||||||
|
actual fun addPoints(p: UByteArray, q: UByteArray): UByteArray {
|
||||||
|
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())
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
actual fun encodedPointFromHash(hash: UByteArray): UByteArray {
|
||||||
|
val result = getSodium().crypto_core_ed25519_from_hash(hash.toUint8Array())
|
||||||
|
|
||||||
|
return result.toUByteArray()
|
||||||
|
}
|
||||||
|
|
||||||
|
actual fun encodedPointFromUniform(uniform: UByteArray): UByteArray {
|
||||||
|
val result = getSodium().crypto_core_ed25519_from_uniform(hash.toUint8Array())
|
||||||
|
|
||||||
|
return result.toUByteArray()
|
||||||
|
}
|
||||||
|
|
||||||
|
actual fun randomEncodedPoint(): UByteArray {
|
||||||
|
val result = getSodium().crypto_core_ed25519_random()
|
||||||
|
|
||||||
|
return result.toUByteArray()
|
||||||
|
}
|
||||||
|
|
||||||
|
actual fun randomEncodedScalar(): UByteArray {
|
||||||
|
val result = getSodium().crypto_core_ed25519_scalar_random()
|
||||||
|
|
||||||
|
return result.toUByteArray()
|
||||||
|
}
|
||||||
|
|
||||||
|
actual fun invertScalar(scalar: UByteArray): UByteArray {
|
||||||
|
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())
|
||||||
|
|
||||||
|
return result.toUByteArray()
|
||||||
|
}
|
||||||
|
|
||||||
|
actual fun complementScalar(scalar: UByteArray): UByteArray {
|
||||||
|
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())
|
||||||
|
|
||||||
|
return result.toUByteArray()
|
||||||
|
}
|
||||||
|
|
||||||
|
actual fun subtractScalars(x: UByteArray, y: UByteArray): UByteArray {
|
||||||
|
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())
|
||||||
|
|
||||||
|
return result.toUByteArray()
|
||||||
|
}
|
||||||
|
|
||||||
|
actual fun reduceScalar(scalar: UByteArray): UByteArray {
|
||||||
|
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())
|
||||||
|
|
||||||
|
return result.toUByteArray()
|
||||||
|
}
|
||||||
|
|
||||||
|
actual fun scalarMultiplicationNoClamp(n: UByteArray, p: UByteArray): UByteArray {
|
||||||
|
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())
|
||||||
|
|
||||||
|
return result.toUByteArray()
|
||||||
|
}
|
||||||
|
|
||||||
|
actual fun scalarMultiplicationBaseNoClamp(n: UByteArray): UByteArray {
|
||||||
|
val result = getSodium().crypto_scalarmult_ed25519_base_noclamp(n.toUint8Array())
|
||||||
|
|
||||||
|
return result.toUByteArray()
|
||||||
|
}
|
||||||
|
}
|
@ -38,19 +38,19 @@ actual abstract class Ristretto255LowLevel actual constructor() {
|
|||||||
return result.toUByteArray()
|
return result.toUByteArray()
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun invert(scalar: UByteArray): UByteArray {
|
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()
|
return result.toUByteArray()
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun negate(scalar: UByteArray): UByteArray {
|
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()
|
return result.toUByteArray()
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun complement(scalar: UByteArray): UByteArray {
|
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()
|
return result.toUByteArray()
|
||||||
@ -74,7 +74,7 @@ actual abstract class Ristretto255LowLevel actual constructor() {
|
|||||||
return result.toUByteArray()
|
return result.toUByteArray()
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun reduce(scalar: UByteArray): UByteArray {
|
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()
|
return result.toUByteArray()
|
||||||
|
@ -1329,4 +1329,46 @@ interface JnaLibsodiumInterface : Library {
|
|||||||
|
|
||||||
//
|
//
|
||||||
// // ---- Ristretto255 end ----
|
// // ---- Ristretto255 end ----
|
||||||
|
|
||||||
|
//
|
||||||
|
// // ---- Ed25519 ----
|
||||||
|
|
||||||
|
fun crypto_core_ed25519_is_valid_point(p: ByteArray): Int
|
||||||
|
|
||||||
|
fun crypto_core_ed25519_random(p: ByteArray)
|
||||||
|
|
||||||
|
fun crypto_core_ed25519_from_hash(p: ByteArray, r: ByteArray): Int
|
||||||
|
|
||||||
|
fun crypto_core_ed25519_from_uniform(p: ByteArray, r: ByteArray): Int
|
||||||
|
|
||||||
|
fun crypto_core_ed25519_add(r: ByteArray, p: ByteArray, q: ByteArray): Int
|
||||||
|
|
||||||
|
fun crypto_core_ed25519_sub(r: ByteArray, p: ByteArray, q: ByteArray): Int
|
||||||
|
|
||||||
|
fun crypto_core_ed25519_scalar_random(r: ByteArray)
|
||||||
|
|
||||||
|
fun crypto_core_ed25519_scalar_reduce(r: ByteArray, s: ByteArray)
|
||||||
|
|
||||||
|
fun crypto_core_ed25519_scalar_invert(recip: ByteArray, s: ByteArray): Int
|
||||||
|
|
||||||
|
fun crypto_core_ed25519_scalar_negate(neg: ByteArray, s: ByteArray)
|
||||||
|
|
||||||
|
fun crypto_core_ed25519_scalar_complement(comp: ByteArray, s: ByteArray)
|
||||||
|
|
||||||
|
fun crypto_core_ed25519_scalar_add(z: ByteArray, x: ByteArray, y: ByteArray)
|
||||||
|
|
||||||
|
fun crypto_core_ed25519_scalar_sub(z: ByteArray, x: ByteArray, y: ByteArray)
|
||||||
|
|
||||||
|
fun crypto_core_ed25519_scalar_mul(z: ByteArray, x: ByteArray, y: ByteArray)
|
||||||
|
|
||||||
|
fun crypto_scalarmult_ed25519(q: ByteArray, n: ByteArray, p: ByteArray): Int
|
||||||
|
|
||||||
|
fun crypto_scalarmult_ed25519_noclamp(q: ByteArray, n: ByteArray, p: ByteArray): Int
|
||||||
|
|
||||||
|
fun crypto_scalarmult_ed25519_base(q: ByteArray, n: ByteArray): Int
|
||||||
|
|
||||||
|
fun crypto_scalarmult_ed25519_base_noclamp(q: ByteArray, n: ByteArray): Int
|
||||||
|
|
||||||
|
//
|
||||||
|
// // ---- Ed25519 end ----
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,145 @@
|
|||||||
|
package com.ionspin.kotlin.crypto.ed25519
|
||||||
|
|
||||||
|
import com.ionspin.kotlin.crypto.GeneralLibsodiumException.Companion.ensureLibsodiumSuccess
|
||||||
|
import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodiumJna
|
||||||
|
import kotlin.UByteArray
|
||||||
|
|
||||||
|
actual abstract class Ed25519LowLevel actual constructor() {
|
||||||
|
actual fun isValidPoint(encoded: UByteArray): Boolean =
|
||||||
|
sodiumJna.crypto_core_ed25519_is_valid_point(encoded.asByteArray()) == 1
|
||||||
|
|
||||||
|
actual fun addPoints(p: UByteArray, q: UByteArray): UByteArray {
|
||||||
|
val result = UByteArray(crypto_core_ed25519_BYTES)
|
||||||
|
|
||||||
|
sodiumJna.crypto_core_ed25519_add(result.asByteArray(), p.asByteArray(), q.asByteArray())
|
||||||
|
.ensureLibsodiumSuccess()
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
actual fun subtractPoints(p: UByteArray, q: UByteArray): UByteArray {
|
||||||
|
val result = UByteArray(crypto_core_ed25519_BYTES)
|
||||||
|
|
||||||
|
sodiumJna.crypto_core_ed25519_sub(result.asByteArray(), p.asByteArray(), q.asByteArray())
|
||||||
|
.ensureLibsodiumSuccess()
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
actual fun encodedPointFromHash(hash: UByteArray): UByteArray {
|
||||||
|
val result = UByteArray(crypto_core_ed25519_BYTES)
|
||||||
|
|
||||||
|
sodiumJna.crypto_core_ed25519_from_hash(result.asByteArray(), hash.asByteArray())
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
actual fun encodedPointFromUniform(uniform: UByteArray): UByteArray {
|
||||||
|
val result = UByteArray(crypto_core_ed25519_BYTES)
|
||||||
|
|
||||||
|
sodiumJna.crypto_core_ed25519_from_uniform(result.asByteArray(), uniform.asByteArray())
|
||||||
|
.ensureLibsodiumSuccess()
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
actual fun randomEncodedPoint(): UByteArray = UByteArray(crypto_core_ed25519_BYTES).also {
|
||||||
|
sodiumJna.crypto_core_ed25519_random(it.asByteArray())
|
||||||
|
}
|
||||||
|
|
||||||
|
actual fun randomEncodedScalar(): UByteArray = UByteArray(crypto_core_ed25519_SCALARBYTES).also {
|
||||||
|
sodiumJna.crypto_core_ed25519_scalar_random(it.asByteArray())
|
||||||
|
}
|
||||||
|
|
||||||
|
actual fun invertScalar(scalar: UByteArray): UByteArray {
|
||||||
|
val result = UByteArray(crypto_core_ed25519_SCALARBYTES)
|
||||||
|
|
||||||
|
sodiumJna.crypto_core_ed25519_scalar_invert(result.asByteArray(), scalar.asByteArray()).ensureLibsodiumSuccess()
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
actual fun negateScalar(scalar: UByteArray): UByteArray {
|
||||||
|
val result = UByteArray(crypto_core_ed25519_SCALARBYTES)
|
||||||
|
|
||||||
|
sodiumJna.crypto_core_ed25519_scalar_negate(result.asByteArray(), scalar.asByteArray())
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
actual fun complementScalar(scalar: UByteArray): UByteArray {
|
||||||
|
val result = UByteArray(crypto_core_ed25519_SCALARBYTES)
|
||||||
|
|
||||||
|
sodiumJna.crypto_core_ed25519_scalar_complement(result.asByteArray(), scalar.asByteArray())
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
actual fun addScalars(x: UByteArray, y: UByteArray): UByteArray {
|
||||||
|
val result = UByteArray(crypto_core_ed25519_SCALARBYTES)
|
||||||
|
|
||||||
|
sodiumJna.crypto_core_ed25519_scalar_add(result.asByteArray(), x.asByteArray(), y.asByteArray())
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
actual fun subtractScalars(x: UByteArray, y: UByteArray): UByteArray {
|
||||||
|
val result = UByteArray(crypto_core_ed25519_SCALARBYTES)
|
||||||
|
|
||||||
|
sodiumJna.crypto_core_ed25519_scalar_sub(result.asByteArray(), x.asByteArray(), y.asByteArray())
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
actual fun multiplyScalars(x: UByteArray, y: UByteArray): UByteArray {
|
||||||
|
val result = UByteArray(crypto_core_ed25519_SCALARBYTES)
|
||||||
|
|
||||||
|
sodiumJna.crypto_core_ed25519_scalar_mul(result.asByteArray(), x.asByteArray(), y.asByteArray())
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
actual fun reduceScalar(scalar: UByteArray): UByteArray {
|
||||||
|
val result = UByteArray(crypto_core_ed25519_SCALARBYTES)
|
||||||
|
|
||||||
|
sodiumJna.crypto_core_ed25519_scalar_reduce(result.asByteArray(), scalar.asByteArray())
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
actual fun scalarMultiplication(n: UByteArray, p: UByteArray): UByteArray {
|
||||||
|
val result = UByteArray(crypto_core_ed25519_BYTES)
|
||||||
|
|
||||||
|
sodiumJna.crypto_scalarmult_ed25519(result.asByteArray(), n.asByteArray(), p.asByteArray())
|
||||||
|
.ensureLibsodiumSuccess()
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
actual fun scalarMultiplicationNoClamp(n: UByteArray, p: UByteArray): UByteArray {
|
||||||
|
val result = UByteArray(crypto_core_ed25519_BYTES)
|
||||||
|
|
||||||
|
sodiumJna.crypto_scalarmult_ed25519_noclamp(result.asByteArray(), n.asByteArray(), p.asByteArray())
|
||||||
|
.ensureLibsodiumSuccess()
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
actual fun scalarMultiplicationBase(n: UByteArray): UByteArray {
|
||||||
|
val result = UByteArray(crypto_core_ed25519_BYTES)
|
||||||
|
|
||||||
|
sodiumJna.crypto_scalarmult_ed25519_base(result.asByteArray(), n.asByteArray())
|
||||||
|
.ensureLibsodiumSuccess()
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
actual fun scalarMultiplicationBaseNoClamp(n: UByteArray): UByteArray {
|
||||||
|
val result = UByteArray(crypto_core_ed25519_BYTES)
|
||||||
|
|
||||||
|
sodiumJna.crypto_scalarmult_ed25519_base_noclamp(result.asByteArray(), n.asByteArray())
|
||||||
|
.ensureLibsodiumSuccess()
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
@ -42,7 +42,7 @@ actual abstract class Ristretto255LowLevel actual constructor() {
|
|||||||
sodiumJna.crypto_core_ristretto255_scalar_random(it.asByteArray())
|
sodiumJna.crypto_core_ristretto255_scalar_random(it.asByteArray())
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun invert(scalar: UByteArray): UByteArray {
|
actual fun invertScalar(scalar: UByteArray): UByteArray {
|
||||||
val result = UByteArray(crypto_core_ristretto255_SCALARBYTES)
|
val result = UByteArray(crypto_core_ristretto255_SCALARBYTES)
|
||||||
|
|
||||||
sodiumJna.crypto_core_ristretto255_scalar_invert(result.asByteArray(), scalar.asByteArray()).ensureLibsodiumSuccess()
|
sodiumJna.crypto_core_ristretto255_scalar_invert(result.asByteArray(), scalar.asByteArray()).ensureLibsodiumSuccess()
|
||||||
@ -50,7 +50,7 @@ actual abstract class Ristretto255LowLevel actual constructor() {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun negate(scalar: UByteArray): UByteArray {
|
actual fun negateScalar(scalar: UByteArray): UByteArray {
|
||||||
val result = UByteArray(crypto_core_ristretto255_SCALARBYTES)
|
val result = UByteArray(crypto_core_ristretto255_SCALARBYTES)
|
||||||
|
|
||||||
sodiumJna.crypto_core_ristretto255_scalar_negate(result.asByteArray(), scalar.asByteArray())
|
sodiumJna.crypto_core_ristretto255_scalar_negate(result.asByteArray(), scalar.asByteArray())
|
||||||
@ -58,7 +58,7 @@ actual abstract class Ristretto255LowLevel actual constructor() {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun complement(scalar: UByteArray): UByteArray {
|
actual fun complementScalar(scalar: UByteArray): UByteArray {
|
||||||
val result = UByteArray(crypto_core_ristretto255_SCALARBYTES)
|
val result = UByteArray(crypto_core_ristretto255_SCALARBYTES)
|
||||||
|
|
||||||
sodiumJna.crypto_core_ristretto255_scalar_complement(result.asByteArray(), scalar.asByteArray())
|
sodiumJna.crypto_core_ristretto255_scalar_complement(result.asByteArray(), scalar.asByteArray())
|
||||||
@ -90,7 +90,7 @@ actual abstract class Ristretto255LowLevel actual constructor() {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun reduce(scalar: UByteArray): UByteArray {
|
actual fun reduceScalar(scalar: UByteArray): UByteArray {
|
||||||
val result = UByteArray(crypto_core_ristretto255_SCALARBYTES)
|
val result = UByteArray(crypto_core_ristretto255_SCALARBYTES)
|
||||||
|
|
||||||
sodiumJna.crypto_core_ristretto255_scalar_reduce(result.asByteArray(), scalar.asByteArray())
|
sodiumJna.crypto_core_ristretto255_scalar_reduce(result.asByteArray(), scalar.asByteArray())
|
||||||
@ -102,6 +102,7 @@ actual abstract class Ristretto255LowLevel actual constructor() {
|
|||||||
val result = UByteArray(crypto_core_ristretto255_BYTES)
|
val result = UByteArray(crypto_core_ristretto255_BYTES)
|
||||||
|
|
||||||
sodiumJna.crypto_scalarmult_ristretto255(result.asByteArray(), n.asByteArray(), p.asByteArray())
|
sodiumJna.crypto_scalarmult_ristretto255(result.asByteArray(), n.asByteArray(), p.asByteArray())
|
||||||
|
.ensureLibsodiumSuccess()
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
@ -110,6 +111,7 @@ actual abstract class Ristretto255LowLevel actual constructor() {
|
|||||||
val result = UByteArray(crypto_core_ristretto255_BYTES)
|
val result = UByteArray(crypto_core_ristretto255_BYTES)
|
||||||
|
|
||||||
sodiumJna.crypto_scalarmult_ristretto255_base(result.asByteArray(), n.asByteArray())
|
sodiumJna.crypto_scalarmult_ristretto255_base(result.asByteArray(), n.asByteArray())
|
||||||
|
.ensureLibsodiumSuccess()
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,243 @@
|
|||||||
|
package com.ionspin.kotlin.crypto.ed25519
|
||||||
|
|
||||||
|
import com.ionspin.kotlin.crypto.GeneralLibsodiumException.Companion.ensureLibsodiumSuccess
|
||||||
|
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_uniform
|
||||||
|
import libsodium.crypto_core_ed25519_is_valid_point
|
||||||
|
import libsodium.crypto_core_ed25519_random
|
||||||
|
import libsodium.crypto_core_ed25519_scalar_add
|
||||||
|
import libsodium.crypto_core_ed25519_scalar_complement
|
||||||
|
import libsodium.crypto_core_ed25519_scalar_invert
|
||||||
|
import libsodium.crypto_core_ed25519_scalar_mul
|
||||||
|
import libsodium.crypto_core_ed25519_scalar_negate
|
||||||
|
import libsodium.crypto_core_ed25519_scalar_random
|
||||||
|
import libsodium.crypto_core_ed25519_scalar_reduce
|
||||||
|
import libsodium.crypto_core_ed25519_scalar_sub
|
||||||
|
import libsodium.crypto_core_ed25519_sub
|
||||||
|
import libsodium.crypto_scalarmult_ed25519
|
||||||
|
import libsodium.crypto_scalarmult_ed25519_base
|
||||||
|
import libsodium.crypto_scalarmult_ed25519_base_noclamp
|
||||||
|
import libsodium.crypto_scalarmult_ed25519_noclamp
|
||||||
|
|
||||||
|
|
||||||
|
actual abstract class Ed25519LowLevel actual constructor() {
|
||||||
|
actual fun isValidPoint(encoded: UByteArray): Boolean {
|
||||||
|
return encoded.usePinned { crypto_core_ed25519_is_valid_point(it.toPtr()) == 1 }
|
||||||
|
}
|
||||||
|
|
||||||
|
actual fun addPoints(p: UByteArray, q: UByteArray): UByteArray {
|
||||||
|
val result = UByteArray(crypto_core_ed25519_BYTES)
|
||||||
|
|
||||||
|
result.usePinned { resultPinned ->
|
||||||
|
p.usePinned { pPinned ->
|
||||||
|
q.usePinned { qPinned ->
|
||||||
|
crypto_core_ed25519_add(resultPinned.toPtr(), pPinned.toPtr(), qPinned.toPtr())
|
||||||
|
.ensureLibsodiumSuccess()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
actual fun subtractPoints(p: UByteArray, q: UByteArray): UByteArray {
|
||||||
|
val result = UByteArray(crypto_core_ed25519_BYTES)
|
||||||
|
|
||||||
|
result.usePinned { resultPinned ->
|
||||||
|
p.usePinned { pPinned ->
|
||||||
|
q.usePinned { qPinned ->
|
||||||
|
crypto_core_ed25519_sub(resultPinned.toPtr(), pPinned.toPtr(), qPinned.toPtr())
|
||||||
|
.ensureLibsodiumSuccess()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
actual fun encodedPointFromHash(hash: UByteArray): UByteArray {
|
||||||
|
val result = UByteArray(crypto_core_ed25519_BYTES)
|
||||||
|
|
||||||
|
result.usePinned { resultPinned ->
|
||||||
|
hash.usePinned { hashPinned ->
|
||||||
|
crypto_core_ed25519_from_hash(resultPinned.toPtr(), hashPinned.toPtr())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
actual fun encodedPointFromUniform(uniform: UByteArray): UByteArray {
|
||||||
|
val result = UByteArray(crypto_core_ed25519_BYTES)
|
||||||
|
|
||||||
|
result.usePinned { resultPinned ->
|
||||||
|
uniform.usePinned { uniformPinned ->
|
||||||
|
crypto_core_ed25519_from_uniform(resultPinned.toPtr(), uniformPinned.toPtr())
|
||||||
|
.ensureLibsodiumSuccess()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
actual fun randomEncodedPoint(): UByteArray = UByteArray(crypto_core_ed25519_BYTES).apply {
|
||||||
|
usePinned { crypto_core_ed25519_random(it.toPtr()) }
|
||||||
|
}
|
||||||
|
|
||||||
|
actual fun randomEncodedScalar(): UByteArray = UByteArray(crypto_core_ed25519_SCALARBYTES).apply {
|
||||||
|
usePinned { crypto_core_ed25519_scalar_random(it.toPtr()) }
|
||||||
|
}
|
||||||
|
|
||||||
|
actual fun invertScalar(scalar: UByteArray): UByteArray {
|
||||||
|
val result = UByteArray(crypto_core_ed25519_SCALARBYTES)
|
||||||
|
|
||||||
|
result.usePinned { resultPinned ->
|
||||||
|
scalar.usePinned { scalarPinned ->
|
||||||
|
crypto_core_ed25519_scalar_invert(resultPinned.toPtr(), scalarPinned.toPtr()).ensureLibsodiumSuccess()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
actual fun negateScalar(scalar: UByteArray): UByteArray {
|
||||||
|
val result = UByteArray(crypto_core_ed25519_SCALARBYTES)
|
||||||
|
|
||||||
|
result.usePinned { resultPinned ->
|
||||||
|
scalar.usePinned { scalarPinned ->
|
||||||
|
crypto_core_ed25519_scalar_negate(resultPinned.toPtr(), scalarPinned.toPtr())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
actual fun complementScalar(scalar: UByteArray): UByteArray {
|
||||||
|
val result = UByteArray(crypto_core_ed25519_SCALARBYTES)
|
||||||
|
|
||||||
|
result.usePinned { resultPinned ->
|
||||||
|
scalar.usePinned { scalarPinned ->
|
||||||
|
crypto_core_ed25519_scalar_complement(resultPinned.toPtr(), scalarPinned.toPtr())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
actual fun addScalars(x: UByteArray, y: UByteArray): UByteArray {
|
||||||
|
val result = UByteArray(crypto_core_ed25519_SCALARBYTES)
|
||||||
|
|
||||||
|
result.usePinned { resultPinned ->
|
||||||
|
x.usePinned { xPinned ->
|
||||||
|
y.usePinned { yPinned ->
|
||||||
|
crypto_core_ed25519_scalar_add(resultPinned.toPtr(), xPinned.toPtr(), yPinned.toPtr())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
actual fun subtractScalars(x: UByteArray, y: UByteArray): UByteArray {
|
||||||
|
val result = UByteArray(crypto_core_ed25519_SCALARBYTES)
|
||||||
|
|
||||||
|
result.usePinned { resultPinned ->
|
||||||
|
x.usePinned { xPinned ->
|
||||||
|
y.usePinned { yPinned ->
|
||||||
|
crypto_core_ed25519_scalar_sub(resultPinned.toPtr(), xPinned.toPtr(), yPinned.toPtr())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
actual fun multiplyScalars(x: UByteArray, y: UByteArray): UByteArray {
|
||||||
|
val result = UByteArray(crypto_core_ed25519_SCALARBYTES)
|
||||||
|
|
||||||
|
result.usePinned { resultPinned ->
|
||||||
|
x.usePinned { xPinned ->
|
||||||
|
y.usePinned { yPinned ->
|
||||||
|
crypto_core_ed25519_scalar_mul(resultPinned.toPtr(), xPinned.toPtr(), yPinned.toPtr())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
actual fun reduceScalar(scalar: UByteArray): UByteArray {
|
||||||
|
val result = UByteArray(crypto_core_ed25519_SCALARBYTES)
|
||||||
|
|
||||||
|
result.usePinned { resultPinned ->
|
||||||
|
scalar.usePinned { scalarPinned ->
|
||||||
|
crypto_core_ed25519_scalar_reduce(resultPinned.toPtr(), scalarPinned.toPtr())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
actual fun scalarMultiplication(n: UByteArray, p: UByteArray): UByteArray {
|
||||||
|
val result = UByteArray(crypto_core_ed25519_BYTES)
|
||||||
|
|
||||||
|
result.usePinned { resultPinned ->
|
||||||
|
n.usePinned { nPinned ->
|
||||||
|
p.usePinned { pPinned ->
|
||||||
|
crypto_scalarmult_ed25519(resultPinned.toPtr(), nPinned.toPtr(), pPinned.toPtr())
|
||||||
|
.ensureLibsodiumSuccess()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
actual fun scalarMultiplicationNoClamp(n: UByteArray, p: UByteArray): UByteArray {
|
||||||
|
val result = UByteArray(crypto_core_ed25519_BYTES)
|
||||||
|
|
||||||
|
result.usePinned { resultPinned ->
|
||||||
|
n.usePinned { nPinned ->
|
||||||
|
p.usePinned { pPinned ->
|
||||||
|
crypto_scalarmult_ed25519_noclamp(resultPinned.toPtr(), nPinned.toPtr(), pPinned.toPtr())
|
||||||
|
.ensureLibsodiumSuccess()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
actual fun scalarMultiplicationBase(n: UByteArray): UByteArray {
|
||||||
|
val result = UByteArray(crypto_core_ed25519_BYTES)
|
||||||
|
|
||||||
|
result.usePinned { resultPinned ->
|
||||||
|
n.usePinned { nPinned ->
|
||||||
|
crypto_scalarmult_ed25519_base(resultPinned.toPtr(), nPinned.toPtr())
|
||||||
|
.ensureLibsodiumSuccess()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
actual fun scalarMultiplicationBaseNoClamp(n: UByteArray): UByteArray {
|
||||||
|
val result = UByteArray(crypto_core_ed25519_BYTES)
|
||||||
|
|
||||||
|
result.usePinned { resultPinned ->
|
||||||
|
n.usePinned { nPinned ->
|
||||||
|
crypto_scalarmult_ed25519_base_noclamp(resultPinned.toPtr(), nPinned.toPtr())
|
||||||
|
.ensureLibsodiumSuccess()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
package com.ionspin.kotlin.crypto.ristretto255
|
package com.ionspin.kotlin.crypto.ristretto255
|
||||||
|
|
||||||
|
import com.ionspin.kotlin.crypto.GeneralLibsodiumException.Companion.ensureLibsodiumSuccess
|
||||||
import com.ionspin.kotlin.crypto.util.toPtr
|
import com.ionspin.kotlin.crypto.util.toPtr
|
||||||
import kotlinx.cinterop.usePinned
|
import kotlinx.cinterop.usePinned
|
||||||
import libsodium.crypto_core_ristretto255_add
|
import libsodium.crypto_core_ristretto255_add
|
||||||
@ -74,7 +75,7 @@ actual abstract class Ristretto255LowLevel actual constructor() {
|
|||||||
usePinned { crypto_core_ristretto255_scalar_random(it.toPtr()) }
|
usePinned { crypto_core_ristretto255_scalar_random(it.toPtr()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun invert(scalar: UByteArray): UByteArray {
|
actual fun invertScalar(scalar: UByteArray): UByteArray {
|
||||||
val result = UByteArray(crypto_core_ristretto255_SCALARBYTES)
|
val result = UByteArray(crypto_core_ristretto255_SCALARBYTES)
|
||||||
|
|
||||||
result.usePinned { resultPinned ->
|
result.usePinned { resultPinned ->
|
||||||
@ -87,7 +88,7 @@ actual abstract class Ristretto255LowLevel actual constructor() {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun negate(scalar: UByteArray): UByteArray {
|
actual fun negateScalar(scalar: UByteArray): UByteArray {
|
||||||
val result = UByteArray(crypto_core_ristretto255_SCALARBYTES)
|
val result = UByteArray(crypto_core_ristretto255_SCALARBYTES)
|
||||||
|
|
||||||
result.usePinned { resultPinned ->
|
result.usePinned { resultPinned ->
|
||||||
@ -100,7 +101,7 @@ actual abstract class Ristretto255LowLevel actual constructor() {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun complement(scalar: UByteArray): UByteArray {
|
actual fun complementScalar(scalar: UByteArray): UByteArray {
|
||||||
val result = UByteArray(crypto_core_ristretto255_SCALARBYTES)
|
val result = UByteArray(crypto_core_ristretto255_SCALARBYTES)
|
||||||
|
|
||||||
result.usePinned { resultPinned ->
|
result.usePinned { resultPinned ->
|
||||||
@ -154,7 +155,7 @@ actual abstract class Ristretto255LowLevel actual constructor() {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun reduce(scalar: UByteArray): UByteArray {
|
actual fun reduceScalar(scalar: UByteArray): UByteArray {
|
||||||
val result = UByteArray(crypto_core_ristretto255_SCALARBYTES)
|
val result = UByteArray(crypto_core_ristretto255_SCALARBYTES)
|
||||||
|
|
||||||
result.usePinned { resultPinned ->
|
result.usePinned { resultPinned ->
|
||||||
@ -173,6 +174,7 @@ actual abstract class Ristretto255LowLevel actual constructor() {
|
|||||||
n.usePinned { nPinned ->
|
n.usePinned { nPinned ->
|
||||||
p.usePinned { pPinned ->
|
p.usePinned { pPinned ->
|
||||||
crypto_scalarmult_ristretto255(resultPinned.toPtr(), nPinned.toPtr(), pPinned.toPtr())
|
crypto_scalarmult_ristretto255(resultPinned.toPtr(), nPinned.toPtr(), pPinned.toPtr())
|
||||||
|
.ensureLibsodiumSuccess()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -187,6 +189,7 @@ actual abstract class Ristretto255LowLevel actual constructor() {
|
|||||||
result.usePinned { resultPinned ->
|
result.usePinned { resultPinned ->
|
||||||
n.usePinned { nPinned ->
|
n.usePinned { nPinned ->
|
||||||
crypto_scalarmult_ristretto255_base(resultPinned.toPtr(), nPinned.toPtr())
|
crypto_scalarmult_ristretto255_base(resultPinned.toPtr(), nPinned.toPtr())
|
||||||
|
.ensureLibsodiumSuccess()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user