Remove unintentional formatting changes and add .editorconfig
This commit is contained in:
parent
989d671c41
commit
2887ae2535
9
.editorconfig
Normal file
9
.editorconfig
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
# EditorConfig is awesome: https://editorconfig.org
|
||||||
|
|
||||||
|
# top-most EditorConfig file
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[*.{kt,kts}]
|
||||||
|
indent_size = 4
|
||||||
|
indent_style = space
|
||||||
|
max_line_length = 120
|
@ -18,174 +18,174 @@ const val crypto_scalarmult_ed25519_BYTES = 32U
|
|||||||
const val crypto_scalarmult_ed25519_SCALARBYTES = 32U
|
const val crypto_scalarmult_ed25519_SCALARBYTES = 32U
|
||||||
|
|
||||||
expect abstract class Ed25519LowLevel() {
|
expect abstract class Ed25519LowLevel() {
|
||||||
fun isValidPoint(encoded: UByteArray): Boolean
|
fun isValidPoint(encoded: UByteArray): Boolean
|
||||||
fun addPoints(p: UByteArray, q: UByteArray): UByteArray
|
fun addPoints(p: UByteArray, q: UByteArray): UByteArray
|
||||||
fun subtractPoints(p: UByteArray, q: UByteArray): UByteArray
|
fun subtractPoints(p: UByteArray, q: UByteArray): UByteArray
|
||||||
fun encodedPointFromUniform(uniform: UByteArray): UByteArray
|
fun encodedPointFromUniform(uniform: UByteArray): UByteArray
|
||||||
fun randomEncodedPoint(): UByteArray
|
fun randomEncodedPoint(): UByteArray
|
||||||
fun randomEncodedScalar(): UByteArray
|
fun randomEncodedScalar(): UByteArray
|
||||||
fun invertScalar(scalar: UByteArray): UByteArray
|
fun invertScalar(scalar: UByteArray): UByteArray
|
||||||
fun negateScalar(scalar: UByteArray): UByteArray
|
fun negateScalar(scalar: UByteArray): UByteArray
|
||||||
fun complementScalar(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 reduceScalar(scalar: UByteArray): UByteArray
|
fun reduceScalar(scalar: UByteArray): UByteArray
|
||||||
fun scalarMultiplication(n: UByteArray, p: UByteArray): UByteArray
|
fun scalarMultiplication(n: UByteArray, p: UByteArray): UByteArray
|
||||||
fun scalarMultiplicationNoClamp(n: UByteArray, p: UByteArray): UByteArray
|
fun scalarMultiplicationNoClamp(n: UByteArray, p: UByteArray): UByteArray
|
||||||
fun scalarMultiplicationBase(n: UByteArray): UByteArray
|
fun scalarMultiplicationBase(n: UByteArray): UByteArray
|
||||||
fun scalarMultiplicationBaseNoClamp(n: UByteArray): UByteArray
|
fun scalarMultiplicationBaseNoClamp(n: UByteArray): UByteArray
|
||||||
}
|
}
|
||||||
|
|
||||||
object Ed25519 : Ed25519LowLevel() {
|
object Ed25519 : Ed25519LowLevel() {
|
||||||
fun add(p: Point, q: Point): Point =
|
fun add(p: Point, q: Point): Point =
|
||||||
Point(addPoints(p.encoded, q.encoded))
|
Point(addPoints(p.encoded, q.encoded))
|
||||||
|
|
||||||
fun subtract(p: Point, q: Point): Point =
|
fun subtract(p: Point, q: Point): Point =
|
||||||
Point(subtractPoints(p.encoded, q.encoded))
|
Point(subtractPoints(p.encoded, q.encoded))
|
||||||
|
|
||||||
fun pointFromUniform(uniform: UByteArray): Point = Point(encodedPointFromUniform(uniform))
|
fun pointFromUniform(uniform: UByteArray): Point = Point(encodedPointFromUniform(uniform))
|
||||||
|
|
||||||
fun randomPoint(): Point = Point(randomEncodedPoint())
|
fun randomPoint(): Point = Point(randomEncodedPoint())
|
||||||
|
|
||||||
fun randomScalar(): Scalar = Scalar(randomEncodedScalar())
|
fun randomScalar(): Scalar = Scalar(randomEncodedScalar())
|
||||||
|
|
||||||
fun invert(scalar: Scalar): Scalar =
|
fun invert(scalar: Scalar): Scalar =
|
||||||
Scalar(invertScalar(scalar.encoded))
|
Scalar(invertScalar(scalar.encoded))
|
||||||
|
|
||||||
fun negate(scalar: Scalar): Scalar =
|
fun negate(scalar: Scalar): Scalar =
|
||||||
Scalar(negateScalar(scalar.encoded))
|
Scalar(negateScalar(scalar.encoded))
|
||||||
|
|
||||||
fun complement(scalar: Scalar): Scalar =
|
fun complement(scalar: Scalar): Scalar =
|
||||||
Scalar(complementScalar(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))
|
||||||
|
|
||||||
fun subtract(x: Scalar, y: Scalar): Scalar =
|
fun subtract(x: Scalar, y: Scalar): Scalar =
|
||||||
Scalar(subtractScalars(x.encoded, y.encoded))
|
Scalar(subtractScalars(x.encoded, y.encoded))
|
||||||
|
|
||||||
fun multiply(x: Scalar, y: Scalar): Scalar =
|
fun multiply(x: Scalar, y: Scalar): Scalar =
|
||||||
Scalar(multiplyScalars(x.encoded, y.encoded))
|
Scalar(multiplyScalars(x.encoded, y.encoded))
|
||||||
|
|
||||||
fun reduce(scalar: Scalar): Scalar =
|
fun reduce(scalar: Scalar): Scalar =
|
||||||
Scalar(reduceScalar(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))
|
||||||
|
|
||||||
fun scalarMultiplicationNoClamp(p: Point, n: Scalar): Point =
|
fun scalarMultiplicationNoClamp(p: Point, n: Scalar): Point =
|
||||||
Point(scalarMultiplicationNoClamp(n.encoded, p.encoded))
|
Point(scalarMultiplicationNoClamp(n.encoded, p.encoded))
|
||||||
|
|
||||||
fun scalarMultiplicationBase(n: Scalar): Point =
|
fun scalarMultiplicationBase(n: Scalar): Point =
|
||||||
Point(scalarMultiplicationBase(n.encoded))
|
Point(scalarMultiplicationBase(n.encoded))
|
||||||
|
|
||||||
fun scalarMultiplicationBaseNoClamp(n: Scalar): Point =
|
fun scalarMultiplicationBaseNoClamp(n: Scalar): Point =
|
||||||
Point(scalarMultiplicationBaseNoClamp(n.encoded))
|
Point(scalarMultiplicationBaseNoClamp(n.encoded))
|
||||||
|
|
||||||
data class Point(val encoded: UByteArray) {
|
data class Point(val encoded: UByteArray) {
|
||||||
operator fun plus(q: Point): Point = add(this, q)
|
operator fun plus(q: Point): Point = add(this, q)
|
||||||
operator fun minus(q: Point): Point = subtract(this, q)
|
operator fun minus(q: Point): Point = subtract(this, q)
|
||||||
|
|
||||||
operator fun times(n: Scalar): Point = scalarMultiplication(this, n)
|
operator fun times(n: Scalar): Point = scalarMultiplication(this, n)
|
||||||
fun times(n: Scalar, clamp: Boolean): Point =
|
fun times(n: Scalar, clamp: Boolean): Point =
|
||||||
if (clamp) scalarMultiplication(this, n) else scalarMultiplicationNoClamp(this, n)
|
if (clamp) scalarMultiplication(this, n) else scalarMultiplicationNoClamp(this, n)
|
||||||
|
|
||||||
fun toHex(): String = LibsodiumUtil.toHex(encoded)
|
fun toHex(): String = LibsodiumUtil.toHex(encoded)
|
||||||
|
|
||||||
override fun equals(other: Any?): Boolean = (other as? Point)?.encoded?.contentEquals(encoded) == true
|
override fun equals(other: Any?): Boolean = (other as? Point)?.encoded?.contentEquals(encoded) == true
|
||||||
override fun hashCode(): Int = encoded.contentHashCode()
|
override fun hashCode(): Int = encoded.contentHashCode()
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val IDENTITY: Point = Point(UByteArray(crypto_core_ed25519_BYTES))
|
val IDENTITY: Point = Point(UByteArray(crypto_core_ed25519_BYTES))
|
||||||
val BASE: Point = scalarMultiplicationBaseNoClamp(Scalar.ONE)
|
val BASE: Point = scalarMultiplicationBaseNoClamp(Scalar.ONE)
|
||||||
|
|
||||||
fun fromUniform(uniform: UByteArray): Point = pointFromUniform(uniform)
|
fun fromUniform(uniform: UByteArray): Point = pointFromUniform(uniform)
|
||||||
|
|
||||||
fun random(): Point = randomPoint()
|
fun random(): Point = randomPoint()
|
||||||
|
|
||||||
fun multiplyBase(n: Scalar): Point = scalarMultiplicationBase(n)
|
fun multiplyBase(n: Scalar): Point = scalarMultiplicationBase(n)
|
||||||
|
|
||||||
fun multiplyBaseNoClamp(n: Scalar): Point = scalarMultiplicationBaseNoClamp(n)
|
fun multiplyBaseNoClamp(n: Scalar): Point = scalarMultiplicationBaseNoClamp(n)
|
||||||
|
|
||||||
fun fromHex(hex: String): Point = Point(LibsodiumUtil.fromHex(hex))
|
fun fromHex(hex: String): Point = Point(LibsodiumUtil.fromHex(hex))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
data class Scalar(val encoded: UByteArray) {
|
data class Scalar(val encoded: UByteArray) {
|
||||||
operator fun plus(y: Scalar): Scalar = add(this, y)
|
operator fun plus(y: Scalar): Scalar = add(this, y)
|
||||||
operator fun plus(y: UInt): Scalar = this + fromUInt(y)
|
operator fun plus(y: UInt): Scalar = this + fromUInt(y)
|
||||||
operator fun plus(y: ULong): Scalar = this + fromULong(y)
|
operator fun plus(y: ULong): Scalar = this + fromULong(y)
|
||||||
|
|
||||||
operator fun minus(y: Scalar): Scalar = subtract(this, y)
|
operator fun minus(y: Scalar): Scalar = subtract(this, y)
|
||||||
operator fun minus(y: UInt): Scalar = this - fromUInt(y)
|
operator fun minus(y: UInt): Scalar = this - fromUInt(y)
|
||||||
operator fun minus(y: ULong): Scalar = this - fromULong(y)
|
operator fun minus(y: ULong): Scalar = this - fromULong(y)
|
||||||
|
|
||||||
operator fun times(y: Scalar): Scalar = multiply(this, y)
|
operator fun times(y: Scalar): Scalar = multiply(this, y)
|
||||||
operator fun times(y: UInt): Scalar = this * fromUInt(y)
|
operator fun times(y: UInt): Scalar = this * fromUInt(y)
|
||||||
operator fun times(y: ULong): Scalar = this * fromULong(y)
|
operator fun times(y: ULong): Scalar = this * fromULong(y)
|
||||||
|
|
||||||
operator fun div(y: Scalar): Scalar = multiply(this, invert(y))
|
operator fun div(y: Scalar): Scalar = multiply(this, invert(y))
|
||||||
operator fun div(y: UInt): Scalar = this / fromUInt(y)
|
operator fun div(y: UInt): Scalar = this / fromUInt(y)
|
||||||
operator fun div(y: ULong): Scalar = this / fromULong(y)
|
operator fun div(y: ULong): Scalar = this / fromULong(y)
|
||||||
|
|
||||||
operator fun unaryMinus(): Scalar = negate(this)
|
operator fun unaryMinus(): Scalar = negate(this)
|
||||||
|
|
||||||
operator fun times(p: Point): Point = scalarMultiplication(p, this)
|
operator fun times(p: Point): Point = scalarMultiplication(p, this)
|
||||||
fun times(p: Point, clamp: Boolean): Point =
|
fun times(p: Point, clamp: Boolean): Point =
|
||||||
if (clamp) scalarMultiplication(p, this) else scalarMultiplicationNoClamp(p, this)
|
if (clamp) scalarMultiplication(p, this) else scalarMultiplicationNoClamp(p, this)
|
||||||
|
|
||||||
fun reduce(): Scalar = reduce(this)
|
fun reduce(): Scalar = reduce(this)
|
||||||
fun invert(): Scalar = invert(this)
|
fun invert(): Scalar = invert(this)
|
||||||
fun complement(): Scalar = complement(this)
|
fun complement(): Scalar = complement(this)
|
||||||
|
|
||||||
fun multiplyWithBase(): Point = scalarMultiplicationBase(this)
|
fun multiplyWithBase(): Point = scalarMultiplicationBase(this)
|
||||||
|
|
||||||
fun multiplyWithBaseNoClamp(): Point = scalarMultiplicationBaseNoClamp(this)
|
fun multiplyWithBaseNoClamp(): Point = scalarMultiplicationBaseNoClamp(this)
|
||||||
|
|
||||||
fun toHex(): String = LibsodiumUtil.toHex(encoded)
|
fun toHex(): String = LibsodiumUtil.toHex(encoded)
|
||||||
|
|
||||||
override fun equals(other: Any?): Boolean = (other as? Scalar)?.encoded?.contentEquals(encoded) == true
|
override fun equals(other: Any?): Boolean = (other as? Scalar)?.encoded?.contentEquals(encoded) == true
|
||||||
override fun hashCode(): Int = encoded.contentHashCode()
|
override fun hashCode(): Int = encoded.contentHashCode()
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val ZERO = fromUInt(0U)
|
val ZERO = fromUInt(0U)
|
||||||
val ONE = fromUInt(1U)
|
val ONE = fromUInt(1U)
|
||||||
val TWO = fromUInt(2U)
|
val TWO = fromUInt(2U)
|
||||||
|
|
||||||
fun random(): Scalar = randomScalar()
|
fun random(): Scalar = randomScalar()
|
||||||
|
|
||||||
fun fromUInt(i: UInt): Scalar = fromULong(i.toULong())
|
fun fromUInt(i: UInt): Scalar = fromULong(i.toULong())
|
||||||
|
|
||||||
fun fromULong(l: ULong): Scalar {
|
fun fromULong(l: ULong): Scalar {
|
||||||
val encoded = UByteArray(crypto_core_ed25519_SCALARBYTES)
|
val encoded = UByteArray(crypto_core_ed25519_SCALARBYTES)
|
||||||
var rem = l
|
var rem = l
|
||||||
|
|
||||||
for (i in 0..7) {
|
for (i in 0..7) {
|
||||||
encoded[i] = (rem and 0xffU).toUByte()
|
encoded[i] = (rem and 0xffU).toUByte()
|
||||||
rem = rem shr 8
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
@ -17,158 +17,159 @@ const val crypto_scalarmult_ristretto255_BYTES = 32U
|
|||||||
const val crypto_scalarmult_ristretto255_SCALARBYTES = 32U
|
const val crypto_scalarmult_ristretto255_SCALARBYTES = 32U
|
||||||
|
|
||||||
expect abstract class Ristretto255LowLevel() {
|
expect abstract class Ristretto255LowLevel() {
|
||||||
fun isValidPoint(encoded: UByteArray): Boolean
|
fun isValidPoint(encoded: UByteArray): Boolean
|
||||||
fun addPoints(p: UByteArray, q: UByteArray): UByteArray
|
fun addPoints(p: UByteArray, q: UByteArray): UByteArray
|
||||||
fun subtractPoints(p: UByteArray, q: UByteArray): UByteArray
|
fun subtractPoints(p: UByteArray, q: UByteArray): UByteArray
|
||||||
fun encodedPointFromHash(hash: UByteArray): UByteArray
|
fun encodedPointFromHash(hash: UByteArray): UByteArray
|
||||||
fun randomEncodedPoint(): UByteArray
|
fun randomEncodedPoint(): UByteArray
|
||||||
fun randomEncodedScalar(): UByteArray
|
fun randomEncodedScalar(): UByteArray
|
||||||
fun invertScalar(scalar: UByteArray): UByteArray
|
fun invertScalar(scalar: UByteArray): UByteArray
|
||||||
fun negateScalar(scalar: UByteArray): UByteArray
|
fun negateScalar(scalar: UByteArray): UByteArray
|
||||||
fun complementScalar(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 reduceScalar(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
|
||||||
}
|
}
|
||||||
|
|
||||||
object Ristretto255 : Ristretto255LowLevel() {
|
object Ristretto255 : Ristretto255LowLevel() {
|
||||||
fun add(p: Point, q: Point): Point =
|
fun add(p: Point, q: Point): Point =
|
||||||
Point(addPoints(p.encoded, q.encoded))
|
Point(addPoints(p.encoded, q.encoded))
|
||||||
|
|
||||||
fun subtract(p: Point, q: Point): Point =
|
fun subtract(p: Point, q: Point): Point =
|
||||||
Point(subtractPoints(p.encoded, q.encoded))
|
Point(subtractPoints(p.encoded, q.encoded))
|
||||||
|
|
||||||
fun pointFromHash(hash: UByteArray): Point = Point(encodedPointFromHash(hash))
|
fun pointFromHash(hash: UByteArray): Point = Point(encodedPointFromHash(hash))
|
||||||
|
|
||||||
fun randomPoint(): Point = Point(randomEncodedPoint())
|
fun randomPoint(): Point = Point(randomEncodedPoint())
|
||||||
|
|
||||||
fun randomScalar(): Scalar = Scalar(randomEncodedScalar())
|
fun randomScalar(): Scalar = Scalar(randomEncodedScalar())
|
||||||
|
|
||||||
fun invert(scalar: Scalar): Scalar =
|
fun invert(scalar: Scalar): Scalar =
|
||||||
Scalar(invertScalar(scalar.encoded))
|
Scalar(invertScalar(scalar.encoded))
|
||||||
|
|
||||||
fun negate(scalar: Scalar): Scalar =
|
fun negate(scalar: Scalar): Scalar =
|
||||||
Scalar(negateScalar(scalar.encoded))
|
Scalar(negateScalar(scalar.encoded))
|
||||||
|
|
||||||
fun complement(scalar: Scalar): Scalar =
|
fun complement(scalar: Scalar): Scalar =
|
||||||
Scalar(complementScalar(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))
|
||||||
|
|
||||||
fun subtract(x: Scalar, y: Scalar): Scalar =
|
fun subtract(x: Scalar, y: Scalar): Scalar =
|
||||||
Scalar(subtractScalars(x.encoded, y.encoded))
|
Scalar(subtractScalars(x.encoded, y.encoded))
|
||||||
|
|
||||||
fun multiply(x: Scalar, y: Scalar): Scalar =
|
fun multiply(x: Scalar, y: Scalar): Scalar =
|
||||||
Scalar(multiplyScalars(x.encoded, y.encoded))
|
Scalar(multiplyScalars(x.encoded, y.encoded))
|
||||||
|
|
||||||
fun reduce(scalar: Scalar): Scalar =
|
fun reduce(scalar: Scalar): Scalar =
|
||||||
Scalar(reduceScalar(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))
|
||||||
|
|
||||||
fun scalarMultiplicationBase(n: Scalar): Point =
|
fun scalarMultiplicationBase(n: Scalar): Point =
|
||||||
Point(scalarMultiplicationBase(n.encoded))
|
Point(scalarMultiplicationBase(n.encoded))
|
||||||
|
|
||||||
data class Point(val encoded: UByteArray) {
|
data class Point(val encoded: UByteArray) {
|
||||||
operator fun plus(q: Point): Point = add(this, q)
|
operator fun plus(q: Point): Point = add(this, q)
|
||||||
operator fun minus(q: Point): Point = subtract(this, q)
|
operator fun minus(q: Point): Point = subtract(this, q)
|
||||||
|
|
||||||
operator fun times(n: Scalar): Point = scalarMultiplication(this, n)
|
operator fun times(n: Scalar): Point = scalarMultiplication(this, n)
|
||||||
|
|
||||||
fun toHex(): String = LibsodiumUtil.toHex(encoded)
|
fun toHex(): String = LibsodiumUtil.toHex(encoded)
|
||||||
|
|
||||||
override fun equals(other: Any?): Boolean = (other as? Point)?.encoded?.contentEquals(encoded) == true
|
override fun equals(other: Any?): Boolean = (other as? Point)?.encoded?.contentEquals(encoded) == true
|
||||||
override fun hashCode(): Int = encoded.contentHashCode()
|
override fun hashCode(): Int = encoded.contentHashCode()
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val IDENTITY: Point = Point(UByteArray(crypto_core_ristretto255_BYTES))
|
val IDENTITY: Point = Point(UByteArray(crypto_core_ristretto255_BYTES))
|
||||||
val BASE: Point = scalarMultiplicationBase(Scalar.ONE)
|
val BASE: Point = scalarMultiplicationBase(Scalar.ONE)
|
||||||
|
|
||||||
fun fromHash(hash: UByteArray): Point = pointFromHash(hash)
|
fun fromHash(hash: UByteArray): Point = pointFromHash(hash)
|
||||||
|
|
||||||
fun random(): Point = randomPoint()
|
fun random(): Point = randomPoint()
|
||||||
|
|
||||||
fun multiplyBase(n: Scalar): Point = scalarMultiplicationBase(n)
|
fun multiplyBase(n: Scalar): Point = scalarMultiplicationBase(n)
|
||||||
|
|
||||||
fun fromHex(hex: String): Point = Point(LibsodiumUtil.fromHex(hex))
|
fun fromHex(hex: String): Point = Point(LibsodiumUtil.fromHex(hex))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
data class Scalar(val encoded: UByteArray) {
|
data class Scalar(val encoded: UByteArray) {
|
||||||
operator fun plus(y: Scalar): Scalar = add(this, y)
|
operator fun plus(y: Scalar): Scalar = add(this, y)
|
||||||
operator fun plus(y: UInt): Scalar = this + fromUInt(y)
|
operator fun plus(y: UInt): Scalar = this + fromUInt(y)
|
||||||
operator fun plus(y: ULong): Scalar = this + fromULong(y)
|
operator fun plus(y: ULong): Scalar = this + fromULong(y)
|
||||||
|
|
||||||
operator fun minus(y: Scalar): Scalar = subtract(this, y)
|
operator fun minus(y: Scalar): Scalar = subtract(this, y)
|
||||||
operator fun minus(y: UInt): Scalar = this - fromUInt(y)
|
operator fun minus(y: UInt): Scalar = this - fromUInt(y)
|
||||||
operator fun minus(y: ULong): Scalar = this - fromULong(y)
|
operator fun minus(y: ULong): Scalar = this - fromULong(y)
|
||||||
|
|
||||||
operator fun times(y: Scalar): Scalar = multiply(this, y)
|
operator fun times(y: Scalar): Scalar = multiply(this, y)
|
||||||
operator fun times(y: UInt): Scalar = this * fromUInt(y)
|
operator fun times(y: UInt): Scalar = this * fromUInt(y)
|
||||||
operator fun times(y: ULong): Scalar = this * fromULong(y)
|
operator fun times(y: ULong): Scalar = this * fromULong(y)
|
||||||
|
|
||||||
operator fun div(y: Scalar): Scalar = multiply(this, invert(y))
|
operator fun div(y: Scalar): Scalar = multiply(this, invert(y))
|
||||||
operator fun div(y: UInt): Scalar = this / fromUInt(y)
|
operator fun div(y: UInt): Scalar = this / fromUInt(y)
|
||||||
operator fun div(y: ULong): Scalar = this / fromULong(y)
|
operator fun div(y: ULong): Scalar = this / fromULong(y)
|
||||||
|
|
||||||
operator fun unaryMinus(): Scalar = negate(this)
|
operator fun unaryMinus(): Scalar = negate(this)
|
||||||
|
|
||||||
operator fun times(p: Point): Point = scalarMultiplication(p, this)
|
operator fun times(p: Point): Point = scalarMultiplication(p, this)
|
||||||
|
|
||||||
fun reduce(): Scalar = reduce(this)
|
fun reduce(): Scalar = reduce(this)
|
||||||
fun invert(): Scalar = invert(this)
|
fun invert(): Scalar = invert(this)
|
||||||
fun complement(): Scalar = complement(this)
|
fun complement(): Scalar = complement(this)
|
||||||
|
|
||||||
fun multiplyWithBase(): Point = scalarMultiplicationBase(this)
|
fun multiplyWithBase(): Point = scalarMultiplicationBase(this)
|
||||||
|
|
||||||
fun toHex(): String = LibsodiumUtil.toHex(encoded)
|
fun toHex(): String = LibsodiumUtil.toHex(encoded)
|
||||||
|
|
||||||
override fun equals(other: Any?): Boolean = (other as? Scalar)?.encoded?.contentEquals(encoded) == true
|
override fun equals(other: Any?): Boolean = (other as? Scalar)?.encoded?.contentEquals(encoded) == true
|
||||||
override fun hashCode(): Int = encoded.contentHashCode()
|
override fun hashCode(): Int = encoded.contentHashCode()
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val ZERO = fromUInt(0U)
|
val ZERO = fromUInt(0U)
|
||||||
val ONE = fromUInt(1U)
|
val ONE = fromUInt(1U)
|
||||||
val TWO = fromUInt(2U)
|
val TWO = fromUInt(2U)
|
||||||
|
|
||||||
fun random(): Scalar = randomScalar()
|
fun random(): Scalar = randomScalar()
|
||||||
|
|
||||||
fun fromUInt(i: UInt): Scalar = fromULong(i.toULong())
|
fun fromUInt(i: UInt): Scalar = fromULong(i.toULong())
|
||||||
|
|
||||||
fun fromULong(l: ULong): Scalar {
|
fun fromULong(l: ULong): Scalar {
|
||||||
val encoded = UByteArray(crypto_core_ristretto255_SCALARBYTES)
|
val encoded = UByteArray(crypto_core_ristretto255_SCALARBYTES)
|
||||||
var rem = l
|
var rem = l
|
||||||
|
|
||||||
for (i in 0..7) {
|
for (i in 0..7) {
|
||||||
encoded[i] = (rem and 0xffU).toUByte()
|
encoded[i] = (rem and 0xffU).toUByte()
|
||||||
rem = rem shr 8
|
rem = rem shr 8
|
||||||
|
}
|
||||||
|
|
||||||
|
return Scalar(encoded)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun fromHex(hex: String): Scalar {
|
||||||
|
require(hex.length <= 2 * crypto_core_ristretto255_NONREDUCEDSCALARBYTES) {
|
||||||
|
"Scalars must be at most $crypto_core_ristretto255_NONREDUCEDSCALARBYTES bytes long"
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hex.length > 2 * crypto_core_ristretto255_SCALARBYTES) {
|
||||||
|
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
|
||||||
|
// 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_ristretto255_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)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Scalar(encoded)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun fromHex(hex: String): Scalar {
|
|
||||||
require(hex.length <= 2 * crypto_core_ristretto255_NONREDUCEDSCALARBYTES) {
|
|
||||||
"Scalars must be at most $crypto_core_ristretto255_NONREDUCEDSCALARBYTES bytes long"
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hex.length > 2 * crypto_core_ristretto255_SCALARBYTES) {
|
|
||||||
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
|
|
||||||
// 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_ristretto255_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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
@ -10,244 +10,244 @@ import kotlin.test.assertNotEquals
|
|||||||
import kotlin.test.assertTrue
|
import kotlin.test.assertTrue
|
||||||
|
|
||||||
class Ed25519Test {
|
class Ed25519Test {
|
||||||
// Test vectors from https://github.com/jedisct1/libsodium/blob/master/test/default/core_ed25519.c
|
// Test vectors from https://github.com/jedisct1/libsodium/blob/master/test/default/core_ed25519.c
|
||||||
val badEncodings = arrayOf(
|
val badEncodings = arrayOf(
|
||||||
"0000000000000000000000000000000000000000000000000000000000000000",
|
"0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
"0100000000000000000000000000000000000000000000000000000000000000",
|
"0100000000000000000000000000000000000000000000000000000000000000",
|
||||||
"0200000000000000000000000000000000000000000000000000000000000000",
|
"0200000000000000000000000000000000000000000000000000000000000000",
|
||||||
// Non canonical encodings
|
// Non canonical encodings
|
||||||
"f6ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f",
|
"f6ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f",
|
||||||
"f5ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f",
|
"f5ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f",
|
||||||
)
|
)
|
||||||
|
|
||||||
// Test vectors generated with sodium.js
|
// Test vectors generated with sodium.js
|
||||||
private val fromHashTestVectors = arrayOf(
|
private val fromHashTestVectors = arrayOf(
|
||||||
"The sodium crypto library compiled to WebAssembly and pure JavaScript" to "50127230808e661643a11badce3c7220ab8de25f890528694f5155ab9c5d5339",
|
"The sodium crypto library compiled to WebAssembly and pure JavaScript" to "50127230808e661643a11badce3c7220ab8de25f890528694f5155ab9c5d5339",
|
||||||
"using Emscripten, with automatically generated wrappers to" to "546d28c823c00b7d1c355c2f3ed6faaed2b7f406b45568c83f14b00ad88c212d",
|
"using Emscripten, with automatically generated wrappers to" to "546d28c823c00b7d1c355c2f3ed6faaed2b7f406b45568c83f14b00ad88c212d",
|
||||||
"make it easy to use in web applications." to "69f1db12b628f6a0573c3ca440dbfe23c161d0a832cf4ca263ed33d15f337780",
|
"make it easy to use in web applications." to "69f1db12b628f6a0573c3ca440dbfe23c161d0a832cf4ca263ed33d15f337780",
|
||||||
"The complete library weighs 188 KB" to "9ad2302066752dccc14e26d7da4bb7a839c211a7e46f558ff106c632106d8f71",
|
"The complete library weighs 188 KB" to "9ad2302066752dccc14e26d7da4bb7a839c211a7e46f558ff106c632106d8f71",
|
||||||
"(minified, gzipped, includes pure JS + WebAssembly versions)" to "07787c86d65d8157b0e7bbf634c46e638f7dc88c560f60dfd1f5e85de64d681c",
|
"(minified, gzipped, includes pure JS + WebAssembly versions)" to "07787c86d65d8157b0e7bbf634c46e638f7dc88c560f60dfd1f5e85de64d681c",
|
||||||
"and can run in a web browser as well as server-side." to "c33fedca4b8e6fdd7ecc4109ec624f81900d8c207e1497297f4ca87c154c0640",
|
"and can run in a web browser as well as server-side." to "c33fedca4b8e6fdd7ecc4109ec624f81900d8c207e1497297f4ca87c154c0640",
|
||||||
)
|
)
|
||||||
|
|
||||||
// Test vectors generated with sodium.js
|
// Test vectors generated with sodium.js
|
||||||
private val fromUniformTestVectors = arrayOf(
|
private val fromUniformTestVectors = arrayOf(
|
||||||
"d5d31a04bf9cd6b4f3f014ab57f95d439a0bd741e71f1ecb580143235545255e" to "cb9fff40134270e80e0dcfcdc66aa4ebf02cd27c9d9d26adfdf78d0012ad1b62",
|
"d5d31a04bf9cd6b4f3f014ab57f95d439a0bd741e71f1ecb580143235545255e" to "cb9fff40134270e80e0dcfcdc66aa4ebf02cd27c9d9d26adfdf78d0012ad1b62",
|
||||||
"9d2e8fc82097672be7b3eb9b9ac74d0cd22087ce04a202a51e88702dceab88a1" to "6b1f76c95d2a201a25b77e73de875637e250acb8e22c44230b2c21bb5a45bb15",
|
"9d2e8fc82097672be7b3eb9b9ac74d0cd22087ce04a202a51e88702dceab88a1" to "6b1f76c95d2a201a25b77e73de875637e250acb8e22c44230b2c21bb5a45bb15",
|
||||||
"7863e96b9a73ffb45df22e2692f395d24b5d7acf745c5fa536818fd00e3ba6f6" to "43be765b38f32d815203e1657c261545366f15b24af2a97694b9320b4a36c407",
|
"7863e96b9a73ffb45df22e2692f395d24b5d7acf745c5fa536818fd00e3ba6f6" to "43be765b38f32d815203e1657c261545366f15b24af2a97694b9320b4a36c407",
|
||||||
"1dfd309d25f6a2c6e0358cddf8dcf8c0fd018ccc7eb799d71fa829640cb5adb3" to "4c6b7015631f4063d85f3b195c7dfcb699a242b3449dc9b4abce8948df88a28e",
|
"1dfd309d25f6a2c6e0358cddf8dcf8c0fd018ccc7eb799d71fa829640cb5adb3" to "4c6b7015631f4063d85f3b195c7dfcb699a242b3449dc9b4abce8948df88a28e",
|
||||||
"40bc69ec71804975dfcbd90b18ca5d9d0117b2e15cacf61e21960b33742a9d55" to "722b608070036ad2e82927338c5edca18f2d0e6f8ed393321ed3704269af1f29",
|
"40bc69ec71804975dfcbd90b18ca5d9d0117b2e15cacf61e21960b33742a9d55" to "722b608070036ad2e82927338c5edca18f2d0e6f8ed393321ed3704269af1f29",
|
||||||
"06c705d68c6224de01437208d7af2b3d933c1822abbe8f551b584cba073dc645" to "bb713b72bf705cc5a3daf299b787d28d47fdb39dc98a13082657b4137081624f",
|
"06c705d68c6224de01437208d7af2b3d933c1822abbe8f551b584cba073dc645" to "bb713b72bf705cc5a3daf299b787d28d47fdb39dc98a13082657b4137081624f",
|
||||||
"e4307d89b2e904063a6a16c9cf09b4225e0b5f4dd2367f08b11bf7787fa626d3" to "f10dea3347ab6792fac62ee6825dad3e4915f15287506db8067ecdbf00f0f30a",
|
"e4307d89b2e904063a6a16c9cf09b4225e0b5f4dd2367f08b11bf7787fa626d3" to "f10dea3347ab6792fac62ee6825dad3e4915f15287506db8067ecdbf00f0f30a",
|
||||||
"6f61fe548ff2cd7bc64d1d3cf4a707a8efba8247e906042d76e98b730f5d1d4d" to "5c43c14cb548b09ac8180c627bcf76bd7720aca21ef72cc13c5584e34ec23ff6",
|
"6f61fe548ff2cd7bc64d1d3cf4a707a8efba8247e906042d76e98b730f5d1d4d" to "5c43c14cb548b09ac8180c627bcf76bd7720aca21ef72cc13c5584e34ec23ff6",
|
||||||
)
|
)
|
||||||
|
|
||||||
// Test vectors generated with sodium.js
|
// Test vectors generated with sodium.js
|
||||||
private val basePointSmallMultiplesNoClamp = arrayOf(
|
private val basePointSmallMultiplesNoClamp = arrayOf(
|
||||||
// This is the basepoint
|
// This is the basepoint
|
||||||
"5866666666666666666666666666666666666666666666666666666666666666",
|
"5866666666666666666666666666666666666666666666666666666666666666",
|
||||||
// These are small multiples of the basepoint
|
// These are small multiples of the basepoint
|
||||||
"c9a3f86aae465f0e56513864510f3997561fa2c9e85ea21dc2292309f3cd6022",
|
"c9a3f86aae465f0e56513864510f3997561fa2c9e85ea21dc2292309f3cd6022",
|
||||||
"d4b4f5784868c3020403246717ec169ff79e26608ea126a1ab69ee77d1b16712",
|
"d4b4f5784868c3020403246717ec169ff79e26608ea126a1ab69ee77d1b16712",
|
||||||
"2f1132ca61ab38dff00f2fea3228f24c6c71d58085b80e47e19515cb27e8d047",
|
"2f1132ca61ab38dff00f2fea3228f24c6c71d58085b80e47e19515cb27e8d047",
|
||||||
"edc876d6831fd2105d0b4389ca2e283166469289146e2ce06faefe98b22548df",
|
"edc876d6831fd2105d0b4389ca2e283166469289146e2ce06faefe98b22548df",
|
||||||
"f47e49f9d07ad2c1606b4d94067c41f9777d4ffda709b71da1d88628fce34d85",
|
"f47e49f9d07ad2c1606b4d94067c41f9777d4ffda709b71da1d88628fce34d85",
|
||||||
"b862409fb5c4c4123df2abf7462b88f041ad36dd6864ce872fd5472be363c5b1",
|
"b862409fb5c4c4123df2abf7462b88f041ad36dd6864ce872fd5472be363c5b1",
|
||||||
"b4b937fca95b2f1e93e41e62fc3c78818ff38a66096fad6e7973e5c90006d321",
|
"b4b937fca95b2f1e93e41e62fc3c78818ff38a66096fad6e7973e5c90006d321",
|
||||||
"c0f1225584444ec730446e231390781ffdd2f256e9fcbeb2f40dddc2c2233d7f",
|
"c0f1225584444ec730446e231390781ffdd2f256e9fcbeb2f40dddc2c2233d7f",
|
||||||
"2c7be86ab07488ba43e8e03d85a67625cfbf98c8544de4c877241b7aaafc7fe3",
|
"2c7be86ab07488ba43e8e03d85a67625cfbf98c8544de4c877241b7aaafc7fe3",
|
||||||
"1337036ac32d8f30d4589c3c1c595812ce0fff40e37c6f5a97ab213f318290ad",
|
"1337036ac32d8f30d4589c3c1c595812ce0fff40e37c6f5a97ab213f318290ad",
|
||||||
"f9e42d2edc81d23367967352b47e4856b82578634e6c1de72280ce8b60ce70c0",
|
"f9e42d2edc81d23367967352b47e4856b82578634e6c1de72280ce8b60ce70c0",
|
||||||
"801f40eaaee1ef8723279a28b2cf4037b889dad222604678748b53ed0db0db92",
|
"801f40eaaee1ef8723279a28b2cf4037b889dad222604678748b53ed0db0db92",
|
||||||
"39289c8998fd69835c26b619e89848a7bf02b7cb7ad1ba1581cbc4506f2550ce",
|
"39289c8998fd69835c26b619e89848a7bf02b7cb7ad1ba1581cbc4506f2550ce",
|
||||||
"df5c2eadc44c6d94a19a9aa118afe5ac3193d26401f76251f522ff042dfbcb92",
|
"df5c2eadc44c6d94a19a9aa118afe5ac3193d26401f76251f522ff042dfbcb92",
|
||||||
"eb2767c137ab7ad8279c078eff116ab0786ead3a2e0f989f72c37f82f2969670",
|
"eb2767c137ab7ad8279c078eff116ab0786ead3a2e0f989f72c37f82f2969670",
|
||||||
)
|
)
|
||||||
|
|
||||||
// Test vectors generated with sodium.js
|
// Test vectors generated with sodium.js
|
||||||
// Because of clamping, the lowest three bits of the scalar are cleared to make it a multiple of the cofactor (8)
|
// Because of clamping, the lowest three bits of the scalar are cleared to make it a multiple of the cofactor (8)
|
||||||
// This makes two scalars yield the same result if they only differ in the lowest three bits. Because of this, for
|
// This makes two scalars yield the same result if they only differ in the lowest three bits. Because of this, for
|
||||||
// these test vectors, the scalars used to obtain them are set to s = i * 4 + 1 where i is the index
|
// these test vectors, the scalars used to obtain them are set to s = i * 4 + 1 where i is the index
|
||||||
val basePointSmallMultiplesClamped = arrayOf(
|
val basePointSmallMultiplesClamped = arrayOf(
|
||||||
"693e47972caf527c7883ad1b39822f026f47db2ab0e1919955b8993aa04411d1",
|
"693e47972caf527c7883ad1b39822f026f47db2ab0e1919955b8993aa04411d1",
|
||||||
"693e47972caf527c7883ad1b39822f026f47db2ab0e1919955b8993aa04411d1",
|
"693e47972caf527c7883ad1b39822f026f47db2ab0e1919955b8993aa04411d1",
|
||||||
"c9877dfd1ccda6393a15aed8aba06798456798355f2a9da4e182fecd40290157",
|
"c9877dfd1ccda6393a15aed8aba06798456798355f2a9da4e182fecd40290157",
|
||||||
"c9877dfd1ccda6393a15aed8aba06798456798355f2a9da4e182fecd40290157",
|
"c9877dfd1ccda6393a15aed8aba06798456798355f2a9da4e182fecd40290157",
|
||||||
"33598cc739b5da481888220cc8d584ba6c385a4c489cb6305446fd78d591bd96",
|
"33598cc739b5da481888220cc8d584ba6c385a4c489cb6305446fd78d591bd96",
|
||||||
"33598cc739b5da481888220cc8d584ba6c385a4c489cb6305446fd78d591bd96",
|
"33598cc739b5da481888220cc8d584ba6c385a4c489cb6305446fd78d591bd96",
|
||||||
"b46a44945eaff85c6de56812f8b035f01f6680a6f37f74bc6aa992bd0ef2d32a",
|
"b46a44945eaff85c6de56812f8b035f01f6680a6f37f74bc6aa992bd0ef2d32a",
|
||||||
"b46a44945eaff85c6de56812f8b035f01f6680a6f37f74bc6aa992bd0ef2d32a",
|
"b46a44945eaff85c6de56812f8b035f01f6680a6f37f74bc6aa992bd0ef2d32a",
|
||||||
"31b532ff5943a5c73690714ceb6414b99d50b0daee2b2d994ea78adf7ac28f4f",
|
"31b532ff5943a5c73690714ceb6414b99d50b0daee2b2d994ea78adf7ac28f4f",
|
||||||
"31b532ff5943a5c73690714ceb6414b99d50b0daee2b2d994ea78adf7ac28f4f",
|
"31b532ff5943a5c73690714ceb6414b99d50b0daee2b2d994ea78adf7ac28f4f",
|
||||||
"140fcdae065d38753b1b563c61ab588da04e7b822a5575483d123fb96f30868d",
|
"140fcdae065d38753b1b563c61ab588da04e7b822a5575483d123fb96f30868d",
|
||||||
"140fcdae065d38753b1b563c61ab588da04e7b822a5575483d123fb96f30868d",
|
"140fcdae065d38753b1b563c61ab588da04e7b822a5575483d123fb96f30868d",
|
||||||
"cb920ec5b5ebcce941d7e84c9ade21d4628c2b020b3c32f7e1b07fbb825c145d",
|
"cb920ec5b5ebcce941d7e84c9ade21d4628c2b020b3c32f7e1b07fbb825c145d",
|
||||||
"cb920ec5b5ebcce941d7e84c9ade21d4628c2b020b3c32f7e1b07fbb825c145d",
|
"cb920ec5b5ebcce941d7e84c9ade21d4628c2b020b3c32f7e1b07fbb825c145d",
|
||||||
"d479546534fa8a146475623ca938efe42c6d561732088f8c3fd687ffff15210b",
|
"d479546534fa8a146475623ca938efe42c6d561732088f8c3fd687ffff15210b",
|
||||||
"d479546534fa8a146475623ca938efe42c6d561732088f8c3fd687ffff15210b",
|
"d479546534fa8a146475623ca938efe42c6d561732088f8c3fd687ffff15210b",
|
||||||
)
|
)
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testRandomPoint() = runTest {
|
fun testRandomPoint() = runTest {
|
||||||
LibsodiumInitializer.initializeWithCallback {
|
LibsodiumInitializer.initializeWithCallback {
|
||||||
val p = Ed25519.Point.random()
|
val p = Ed25519.Point.random()
|
||||||
val q = Ed25519.Point.random()
|
val q = Ed25519.Point.random()
|
||||||
val r = Ed25519.Point.random()
|
val r = Ed25519.Point.random()
|
||||||
|
|
||||||
assertNotEquals(p, q)
|
assertNotEquals(p, q)
|
||||||
assertNotEquals(q, r)
|
assertNotEquals(q, r)
|
||||||
assertNotEquals(r, p)
|
assertNotEquals(r, p)
|
||||||
|
|
||||||
assertTrue { Ed25519.isValidPoint(p.encoded) }
|
assertTrue { Ed25519.isValidPoint(p.encoded) }
|
||||||
assertTrue { Ed25519.isValidPoint(q.encoded) }
|
assertTrue { Ed25519.isValidPoint(q.encoded) }
|
||||||
assertTrue { Ed25519.isValidPoint(r.encoded) }
|
assertTrue { Ed25519.isValidPoint(r.encoded) }
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun testPointHexConversion() = runTest {
|
|
||||||
LibsodiumInitializer.initializeWithCallback {
|
|
||||||
repeat(10) {
|
|
||||||
val p = Ed25519.Point.random()
|
|
||||||
|
|
||||||
assertEquals(p, Ed25519.Point.fromHex(p.toHex()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun testIsValidPoint() = runTest {
|
|
||||||
LibsodiumInitializer.initializeWithCallback {
|
|
||||||
for (hexEncoded in badEncodings) {
|
|
||||||
assertFalse { Ed25519.isValidPoint(LibsodiumUtil.fromHex(hexEncoded)) }
|
|
||||||
}
|
|
||||||
|
|
||||||
for (hexEncoded in basePointSmallMultiplesNoClamp) {
|
|
||||||
assertTrue { Ed25519.isValidPoint(LibsodiumUtil.fromHex(hexEncoded)) }
|
|
||||||
}
|
|
||||||
|
|
||||||
for (hexEncoded in basePointSmallMultiplesClamped) {
|
|
||||||
assertTrue { Ed25519.isValidPoint(LibsodiumUtil.fromHex(hexEncoded)) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun testPointArithmeticNoClamp() = runTest {
|
|
||||||
LibsodiumInitializer.initializeWithCallback {
|
|
||||||
for (i in basePointSmallMultiplesNoClamp.indices) {
|
|
||||||
val p = Ed25519.Point.fromHex(basePointSmallMultiplesNoClamp[i])
|
|
||||||
val b = Ed25519.Point.BASE
|
|
||||||
val n = Ed25519.Scalar.fromUInt(i.toUInt() + 1U)
|
|
||||||
|
|
||||||
assertEquals(p, Ed25519.scalarMultiplicationBaseNoClamp(n))
|
|
||||||
assertEquals(p, Ed25519.scalarMultiplicationNoClamp(b, n))
|
|
||||||
assertEquals(p, n.multiplyWithBaseNoClamp())
|
|
||||||
|
|
||||||
for (j in 0..<i) {
|
|
||||||
val q = Ed25519.Point.fromHex(basePointSmallMultiplesNoClamp[j])
|
|
||||||
val m = Ed25519.Scalar.fromUInt(i.toUInt() - j.toUInt())
|
|
||||||
|
|
||||||
assertEquals(p, q + b.times(m, clamp = false))
|
|
||||||
assertEquals(p, b.times(m, clamp = false) + q)
|
|
||||||
assertEquals(q, p - b.times(m, clamp = false))
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (j in i + 1..<basePointSmallMultiplesNoClamp.size) {
|
@Test
|
||||||
val q = Ed25519.Point.fromHex(basePointSmallMultiplesNoClamp[j])
|
fun testPointHexConversion() = runTest {
|
||||||
val m = Ed25519.Scalar.fromUInt(j.toUInt() - i.toUInt())
|
LibsodiumInitializer.initializeWithCallback {
|
||||||
|
repeat(10) {
|
||||||
|
val p = Ed25519.Point.random()
|
||||||
|
|
||||||
assertEquals(q, p + b.times(m, clamp = false))
|
assertEquals(p, Ed25519.Point.fromHex(p.toHex()))
|
||||||
assertEquals(q, b.times(m, clamp = false) + p)
|
}
|
||||||
assertEquals(p, q - b.times(m, clamp = false))
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testPointArithmeticClamped() = runTest {
|
fun testIsValidPoint() = runTest {
|
||||||
LibsodiumInitializer.initializeWithCallback {
|
LibsodiumInitializer.initializeWithCallback {
|
||||||
for (i in basePointSmallMultiplesNoClamp.indices) {
|
for (hexEncoded in badEncodings) {
|
||||||
println("i: $i")
|
assertFalse { Ed25519.isValidPoint(LibsodiumUtil.fromHex(hexEncoded)) }
|
||||||
val p = Ed25519.Point.fromHex(basePointSmallMultiplesClamped[i])
|
}
|
||||||
val b = Ed25519.Point.BASE
|
|
||||||
val n = Ed25519.Scalar.fromUInt(i.toUInt() * 4U + 1U)
|
|
||||||
|
|
||||||
assertEquals(p, Ed25519.scalarMultiplicationBase(n))
|
for (hexEncoded in basePointSmallMultiplesNoClamp) {
|
||||||
assertEquals(p, Ed25519.scalarMultiplication(b, n))
|
assertTrue { Ed25519.isValidPoint(LibsodiumUtil.fromHex(hexEncoded)) }
|
||||||
assertEquals(p, n.multiplyWithBase())
|
}
|
||||||
}
|
|
||||||
|
for (hexEncoded in basePointSmallMultiplesClamped) {
|
||||||
|
assertTrue { Ed25519.isValidPoint(LibsodiumUtil.fromHex(hexEncoded)) }
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testPointFromUniform() = runTest {
|
fun testPointArithmeticNoClamp() = runTest {
|
||||||
LibsodiumInitializer.initializeWithCallback {
|
LibsodiumInitializer.initializeWithCallback {
|
||||||
for ((input, output) in fromUniformTestVectors) {
|
for (i in basePointSmallMultiplesNoClamp.indices) {
|
||||||
val outPoint = Ed25519.Point.fromHex(output)
|
val p = Ed25519.Point.fromHex(basePointSmallMultiplesNoClamp[i])
|
||||||
val uniform = LibsodiumUtil.fromHex(input)
|
val b = Ed25519.Point.BASE
|
||||||
|
val n = Ed25519.Scalar.fromUInt(i.toUInt() + 1U)
|
||||||
|
|
||||||
assertEquals(outPoint, Ed25519.Point.fromUniform(uniform))
|
assertEquals(p, Ed25519.scalarMultiplicationBaseNoClamp(n))
|
||||||
}
|
assertEquals(p, Ed25519.scalarMultiplicationNoClamp(b, n))
|
||||||
|
assertEquals(p, n.multiplyWithBaseNoClamp())
|
||||||
|
|
||||||
|
for (j in 0..<i) {
|
||||||
|
val q = Ed25519.Point.fromHex(basePointSmallMultiplesNoClamp[j])
|
||||||
|
val m = Ed25519.Scalar.fromUInt(i.toUInt() - j.toUInt())
|
||||||
|
|
||||||
|
assertEquals(p, q + b.times(m, clamp = false))
|
||||||
|
assertEquals(p, b.times(m, clamp = false) + q)
|
||||||
|
assertEquals(q, p - b.times(m, clamp = false))
|
||||||
|
}
|
||||||
|
|
||||||
|
for (j in i + 1..<basePointSmallMultiplesNoClamp.size) {
|
||||||
|
val q = Ed25519.Point.fromHex(basePointSmallMultiplesNoClamp[j])
|
||||||
|
val m = Ed25519.Scalar.fromUInt(j.toUInt() - i.toUInt())
|
||||||
|
|
||||||
|
assertEquals(q, p + b.times(m, clamp = false))
|
||||||
|
assertEquals(q, b.times(m, clamp = false) + p)
|
||||||
|
assertEquals(p, q - b.times(m, clamp = false))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testRandomScalar() = runTest {
|
fun testPointArithmeticClamped() = runTest {
|
||||||
LibsodiumInitializer.initializeWithCallback {
|
LibsodiumInitializer.initializeWithCallback {
|
||||||
val x = Ed25519.Scalar.random()
|
for (i in basePointSmallMultiplesNoClamp.indices) {
|
||||||
val y = Ed25519.Scalar.random()
|
println("i: $i")
|
||||||
val z = Ed25519.Scalar.random()
|
val p = Ed25519.Point.fromHex(basePointSmallMultiplesClamped[i])
|
||||||
|
val b = Ed25519.Point.BASE
|
||||||
|
val n = Ed25519.Scalar.fromUInt(i.toUInt() * 4U + 1U)
|
||||||
|
|
||||||
assertNotEquals(x, y)
|
assertEquals(p, Ed25519.scalarMultiplicationBase(n))
|
||||||
assertNotEquals(y, z)
|
assertEquals(p, Ed25519.scalarMultiplication(b, n))
|
||||||
assertNotEquals(z, x)
|
assertEquals(p, n.multiplyWithBase())
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testScalarHexConversion() = runTest {
|
fun testPointFromUniform() = runTest {
|
||||||
LibsodiumInitializer.initializeWithCallback {
|
LibsodiumInitializer.initializeWithCallback {
|
||||||
repeat(10) {
|
for ((input, output) in fromUniformTestVectors) {
|
||||||
val p = Ed25519.Scalar.random()
|
val outPoint = Ed25519.Point.fromHex(output)
|
||||||
|
val uniform = LibsodiumUtil.fromHex(input)
|
||||||
|
|
||||||
assertEquals(p, Ed25519.Scalar.fromHex(p.toHex()))
|
assertEquals(outPoint, Ed25519.Point.fromUniform(uniform))
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testScalarArithmetic() = runTest {
|
fun testRandomScalar() = runTest {
|
||||||
LibsodiumInitializer.initializeWithCallback {
|
LibsodiumInitializer.initializeWithCallback {
|
||||||
repeat(10) {
|
val x = Ed25519.Scalar.random()
|
||||||
val x = Ed25519.Scalar.random()
|
val y = Ed25519.Scalar.random()
|
||||||
val y = Ed25519.Scalar.random()
|
val z = Ed25519.Scalar.random()
|
||||||
|
|
||||||
val xInv = x.invert()
|
assertNotEquals(x, y)
|
||||||
val xComp = x.complement()
|
assertNotEquals(y, z)
|
||||||
val xNeg = -x
|
assertNotEquals(z, x)
|
||||||
|
}
|
||||||
assertEquals(Ed25519.Scalar.ZERO, x + xNeg)
|
}
|
||||||
assertEquals(Ed25519.Scalar.ZERO, xNeg + x)
|
|
||||||
assertEquals(Ed25519.Scalar.ZERO, x - x)
|
@Test
|
||||||
|
fun testScalarHexConversion() = runTest {
|
||||||
assertEquals(x, x + Ed25519.Scalar.ZERO)
|
LibsodiumInitializer.initializeWithCallback {
|
||||||
assertEquals(x, Ed25519.Scalar.ZERO + x)
|
repeat(10) {
|
||||||
|
val p = Ed25519.Scalar.random()
|
||||||
assertEquals(Ed25519.Scalar.ONE, x + xComp)
|
|
||||||
assertEquals(Ed25519.Scalar.ONE, xComp + x)
|
assertEquals(p, Ed25519.Scalar.fromHex(p.toHex()))
|
||||||
|
}
|
||||||
assertEquals(Ed25519.Scalar.ONE, x * xInv)
|
}
|
||||||
assertEquals(Ed25519.Scalar.ONE, xInv * x)
|
}
|
||||||
assertEquals(Ed25519.Scalar.ONE, x / x)
|
|
||||||
|
@Test
|
||||||
assertEquals(x, x * Ed25519.Scalar.ONE)
|
fun testScalarArithmetic() = runTest {
|
||||||
assertEquals(x, Ed25519.Scalar.ONE * x)
|
LibsodiumInitializer.initializeWithCallback {
|
||||||
|
repeat(10) {
|
||||||
assertEquals(y - x, y + xNeg)
|
val x = Ed25519.Scalar.random()
|
||||||
assertEquals(y / x, y * xInv)
|
val y = Ed25519.Scalar.random()
|
||||||
}
|
|
||||||
|
val xInv = x.invert()
|
||||||
|
val xComp = x.complement()
|
||||||
|
val xNeg = -x
|
||||||
|
|
||||||
|
assertEquals(Ed25519.Scalar.ZERO, x + xNeg)
|
||||||
|
assertEquals(Ed25519.Scalar.ZERO, xNeg + x)
|
||||||
|
assertEquals(Ed25519.Scalar.ZERO, x - x)
|
||||||
|
|
||||||
|
assertEquals(x, x + Ed25519.Scalar.ZERO)
|
||||||
|
assertEquals(x, Ed25519.Scalar.ZERO + x)
|
||||||
|
|
||||||
|
assertEquals(Ed25519.Scalar.ONE, x + xComp)
|
||||||
|
assertEquals(Ed25519.Scalar.ONE, xComp + x)
|
||||||
|
|
||||||
|
assertEquals(Ed25519.Scalar.ONE, x * xInv)
|
||||||
|
assertEquals(Ed25519.Scalar.ONE, xInv * x)
|
||||||
|
assertEquals(Ed25519.Scalar.ONE, x / x)
|
||||||
|
|
||||||
|
assertEquals(x, x * Ed25519.Scalar.ONE)
|
||||||
|
assertEquals(x, Ed25519.Scalar.ONE * x)
|
||||||
|
|
||||||
|
assertEquals(y - x, y + xNeg)
|
||||||
|
assertEquals(y / x, y * xInv)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
@ -12,217 +12,217 @@ import kotlin.test.assertNotEquals
|
|||||||
import kotlin.test.assertTrue
|
import kotlin.test.assertTrue
|
||||||
|
|
||||||
class Ristretto255Test {
|
class Ristretto255Test {
|
||||||
// Test vectors from https://ristretto.group/test_vectors/ristretto255.html
|
// Test vectors from https://ristretto.group/test_vectors/ristretto255.html
|
||||||
val badEncodings = arrayOf(
|
val badEncodings = arrayOf(
|
||||||
// These are all bad because they're non-canonical field encodings.
|
// These are all bad because they're non-canonical field encodings.
|
||||||
"00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
"00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
||||||
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f",
|
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f",
|
||||||
"f3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f",
|
"f3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f",
|
||||||
"edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f",
|
"edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f",
|
||||||
// These are all bad because they're negative field elements.
|
// These are all bad because they're negative field elements.
|
||||||
"0100000000000000000000000000000000000000000000000000000000000000",
|
"0100000000000000000000000000000000000000000000000000000000000000",
|
||||||
"01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f",
|
"01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f",
|
||||||
"ed57ffd8c914fb201471d1c3d245ce3c746fcbe63a3679d51b6a516ebebe0e20",
|
"ed57ffd8c914fb201471d1c3d245ce3c746fcbe63a3679d51b6a516ebebe0e20",
|
||||||
"c34c4e1826e5d403b78e246e88aa051c36ccf0aafebffe137d148a2bf9104562",
|
"c34c4e1826e5d403b78e246e88aa051c36ccf0aafebffe137d148a2bf9104562",
|
||||||
"c940e5a4404157cfb1628b108db051a8d439e1a421394ec4ebccb9ec92a8ac78",
|
"c940e5a4404157cfb1628b108db051a8d439e1a421394ec4ebccb9ec92a8ac78",
|
||||||
"47cfc5497c53dc8e61c91d17fd626ffb1c49e2bca94eed052281b510b1117a24",
|
"47cfc5497c53dc8e61c91d17fd626ffb1c49e2bca94eed052281b510b1117a24",
|
||||||
"f1c6165d33367351b0da8f6e4511010c68174a03b6581212c71c0e1d026c3c72",
|
"f1c6165d33367351b0da8f6e4511010c68174a03b6581212c71c0e1d026c3c72",
|
||||||
"87260f7a2f12495118360f02c26a470f450dadf34a413d21042b43b9d93e1309",
|
"87260f7a2f12495118360f02c26a470f450dadf34a413d21042b43b9d93e1309",
|
||||||
// These are all bad because they give a non-square x^2.
|
// These are all bad because they give a non-square x^2.
|
||||||
"26948d35ca62e643e26a83177332e6b6afeb9d08e4268b650f1f5bbd8d81d371",
|
"26948d35ca62e643e26a83177332e6b6afeb9d08e4268b650f1f5bbd8d81d371",
|
||||||
"4eac077a713c57b4f4397629a4145982c661f48044dd3f96427d40b147d9742f",
|
"4eac077a713c57b4f4397629a4145982c661f48044dd3f96427d40b147d9742f",
|
||||||
"de6a7b00deadc788eb6b6c8d20c0ae96c2f2019078fa604fee5b87d6e989ad7b",
|
"de6a7b00deadc788eb6b6c8d20c0ae96c2f2019078fa604fee5b87d6e989ad7b",
|
||||||
"bcab477be20861e01e4a0e295284146a510150d9817763caf1a6f4b422d67042",
|
"bcab477be20861e01e4a0e295284146a510150d9817763caf1a6f4b422d67042",
|
||||||
"2a292df7e32cababbd9de088d1d1abec9fc0440f637ed2fba145094dc14bea08",
|
"2a292df7e32cababbd9de088d1d1abec9fc0440f637ed2fba145094dc14bea08",
|
||||||
"f4a9e534fc0d216c44b218fa0c42d99635a0127ee2e53c712f70609649fdff22",
|
"f4a9e534fc0d216c44b218fa0c42d99635a0127ee2e53c712f70609649fdff22",
|
||||||
"8268436f8c4126196cf64b3c7ddbda90746a378625f9813dd9b8457077256731",
|
"8268436f8c4126196cf64b3c7ddbda90746a378625f9813dd9b8457077256731",
|
||||||
"2810e5cbc2cc4d4eece54f61c6f69758e289aa7ab440b3cbeaa21995c2f4232b",
|
"2810e5cbc2cc4d4eece54f61c6f69758e289aa7ab440b3cbeaa21995c2f4232b",
|
||||||
// These are all bad because they give a negative xy value.
|
// These are all bad because they give a negative xy value.
|
||||||
"3eb858e78f5a7254d8c9731174a94f76755fd3941c0ac93735c07ba14579630e",
|
"3eb858e78f5a7254d8c9731174a94f76755fd3941c0ac93735c07ba14579630e",
|
||||||
"a45fdc55c76448c049a1ab33f17023edfb2be3581e9c7aade8a6125215e04220",
|
"a45fdc55c76448c049a1ab33f17023edfb2be3581e9c7aade8a6125215e04220",
|
||||||
"d483fe813c6ba647ebbfd3ec41adca1c6130c2beeee9d9bf065c8d151c5f396e",
|
"d483fe813c6ba647ebbfd3ec41adca1c6130c2beeee9d9bf065c8d151c5f396e",
|
||||||
"8a2e1d30050198c65a54483123960ccc38aef6848e1ec8f5f780e8523769ba32",
|
"8a2e1d30050198c65a54483123960ccc38aef6848e1ec8f5f780e8523769ba32",
|
||||||
"32888462f8b486c68ad7dd9610be5192bbeaf3b443951ac1a8118419d9fa097b",
|
"32888462f8b486c68ad7dd9610be5192bbeaf3b443951ac1a8118419d9fa097b",
|
||||||
"227142501b9d4355ccba290404bde41575b037693cef1f438c47f8fbf35d1165",
|
"227142501b9d4355ccba290404bde41575b037693cef1f438c47f8fbf35d1165",
|
||||||
"5c37cc491da847cfeb9281d407efc41e15144c876e0170b499a96a22ed31e01e",
|
"5c37cc491da847cfeb9281d407efc41e15144c876e0170b499a96a22ed31e01e",
|
||||||
"445425117cb8c90edcbc7c1cc0e74f747f2c1efa5630a967c64f287792a48a4b",
|
"445425117cb8c90edcbc7c1cc0e74f747f2c1efa5630a967c64f287792a48a4b",
|
||||||
// This is s = -1, which causes y = 0.
|
// This is s = -1, which causes y = 0.
|
||||||
"ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f"
|
"ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Test vectors from https://ristretto.group/test_vectors/ristretto255.html
|
// Test vectors from https://ristretto.group/test_vectors/ristretto255.html
|
||||||
val fromHashTestVectors = arrayOf(
|
val fromHashTestVectors = arrayOf(
|
||||||
"Ristretto is traditionally a short shot of espresso coffee" to "3066f82a1a747d45120d1740f14358531a8f04bbffe6a819f86dfe50f44a0a46",
|
"Ristretto is traditionally a short shot of espresso coffee" to "3066f82a1a747d45120d1740f14358531a8f04bbffe6a819f86dfe50f44a0a46",
|
||||||
"made with the normal amount of ground coffee but extracted with" to "f26e5b6f7d362d2d2a94c5d0e7602cb4773c95a2e5c31a64f133189fa76ed61b",
|
"made with the normal amount of ground coffee but extracted with" to "f26e5b6f7d362d2d2a94c5d0e7602cb4773c95a2e5c31a64f133189fa76ed61b",
|
||||||
"about half the amount of water in the same amount of time" to "006ccd2a9e6867e6a2c5cea83d3302cc9de128dd2a9a57dd8ee7b9d7ffe02826",
|
"about half the amount of water in the same amount of time" to "006ccd2a9e6867e6a2c5cea83d3302cc9de128dd2a9a57dd8ee7b9d7ffe02826",
|
||||||
"by using a finer grind." to "f8f0c87cf237953c5890aec3998169005dae3eca1fbb04548c635953c817f92a",
|
"by using a finer grind." to "f8f0c87cf237953c5890aec3998169005dae3eca1fbb04548c635953c817f92a",
|
||||||
"This produces a concentrated shot of coffee per volume." to "ae81e7dedf20a497e10c304a765c1767a42d6e06029758d2d7e8ef7cc4c41179",
|
"This produces a concentrated shot of coffee per volume." to "ae81e7dedf20a497e10c304a765c1767a42d6e06029758d2d7e8ef7cc4c41179",
|
||||||
"Just pulling a normal shot short will produce a weaker shot" to "e2705652ff9f5e44d3e841bf1c251cf7dddb77d140870d1ab2ed64f1a9ce8628",
|
"Just pulling a normal shot short will produce a weaker shot" to "e2705652ff9f5e44d3e841bf1c251cf7dddb77d140870d1ab2ed64f1a9ce8628",
|
||||||
"and is not a Ristretto as some believe." to "80bd07262511cdde4863f8a7434cef696750681cb9510eea557088f76d9e5065",
|
"and is not a Ristretto as some believe." to "80bd07262511cdde4863f8a7434cef696750681cb9510eea557088f76d9e5065",
|
||||||
)
|
)
|
||||||
|
|
||||||
// Test vectors from https://ristretto.group/test_vectors/ristretto255.html
|
// Test vectors from https://ristretto.group/test_vectors/ristretto255.html
|
||||||
val basePointSmallMultiples = arrayOf(
|
val basePointSmallMultiples = arrayOf(
|
||||||
// This is the basepoint
|
// This is the basepoint
|
||||||
"e2f2ae0a6abc4e71a884a961c500515f58e30b6aa582dd8db6a65945e08d2d76",
|
"e2f2ae0a6abc4e71a884a961c500515f58e30b6aa582dd8db6a65945e08d2d76",
|
||||||
// These are small multiples of the basepoint
|
// These are small multiples of the basepoint
|
||||||
"6a493210f7499cd17fecb510ae0cea23a110e8d5b901f8acadd3095c73a3b919",
|
"6a493210f7499cd17fecb510ae0cea23a110e8d5b901f8acadd3095c73a3b919",
|
||||||
"94741f5d5d52755ece4f23f044ee27d5d1ea1e2bd196b462166b16152a9d0259",
|
"94741f5d5d52755ece4f23f044ee27d5d1ea1e2bd196b462166b16152a9d0259",
|
||||||
"da80862773358b466ffadfe0b3293ab3d9fd53c5ea6c955358f568322daf6a57",
|
"da80862773358b466ffadfe0b3293ab3d9fd53c5ea6c955358f568322daf6a57",
|
||||||
"e882b131016b52c1d3337080187cf768423efccbb517bb495ab812c4160ff44e",
|
"e882b131016b52c1d3337080187cf768423efccbb517bb495ab812c4160ff44e",
|
||||||
"f64746d3c92b13050ed8d80236a7f0007c3b3f962f5ba793d19a601ebb1df403",
|
"f64746d3c92b13050ed8d80236a7f0007c3b3f962f5ba793d19a601ebb1df403",
|
||||||
"44f53520926ec81fbd5a387845beb7df85a96a24ece18738bdcfa6a7822a176d",
|
"44f53520926ec81fbd5a387845beb7df85a96a24ece18738bdcfa6a7822a176d",
|
||||||
"903293d8f2287ebe10e2374dc1a53e0bc887e592699f02d077d5263cdd55601c",
|
"903293d8f2287ebe10e2374dc1a53e0bc887e592699f02d077d5263cdd55601c",
|
||||||
"02622ace8f7303a31cafc63f8fc48fdc16e1c8c8d234b2f0d6685282a9076031",
|
"02622ace8f7303a31cafc63f8fc48fdc16e1c8c8d234b2f0d6685282a9076031",
|
||||||
"20706fd788b2720a1ed2a5dad4952b01f413bcf0e7564de8cdc816689e2db95f",
|
"20706fd788b2720a1ed2a5dad4952b01f413bcf0e7564de8cdc816689e2db95f",
|
||||||
"bce83f8ba5dd2fa572864c24ba1810f9522bc6004afe95877ac73241cafdab42",
|
"bce83f8ba5dd2fa572864c24ba1810f9522bc6004afe95877ac73241cafdab42",
|
||||||
"e4549ee16b9aa03099ca208c67adafcafa4c3f3e4e5303de6026e3ca8ff84460",
|
"e4549ee16b9aa03099ca208c67adafcafa4c3f3e4e5303de6026e3ca8ff84460",
|
||||||
"aa52e000df2e16f55fb1032fc33bc42742dad6bd5a8fc0be0167436c5948501f",
|
"aa52e000df2e16f55fb1032fc33bc42742dad6bd5a8fc0be0167436c5948501f",
|
||||||
"46376b80f409b29dc2b5f6f0c52591990896e5716f41477cd30085ab7f10301e",
|
"46376b80f409b29dc2b5f6f0c52591990896e5716f41477cd30085ab7f10301e",
|
||||||
"e0c418f7c8d9c4cdd7395b93ea124f3ad99021bb681dfc3302a9d99a2e53e64e",
|
"e0c418f7c8d9c4cdd7395b93ea124f3ad99021bb681dfc3302a9d99a2e53e64e",
|
||||||
)
|
)
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testRandomPoint() = runTest {
|
fun testRandomPoint() = runTest {
|
||||||
LibsodiumInitializer.initializeWithCallback {
|
LibsodiumInitializer.initializeWithCallback {
|
||||||
val p = Ristretto255.Point.random()
|
val p = Ristretto255.Point.random()
|
||||||
val q = Ristretto255.Point.random()
|
val q = Ristretto255.Point.random()
|
||||||
val r = Ristretto255.Point.random()
|
val r = Ristretto255.Point.random()
|
||||||
|
|
||||||
assertNotEquals(p, q)
|
assertNotEquals(p, q)
|
||||||
assertNotEquals(q, r)
|
assertNotEquals(q, r)
|
||||||
assertNotEquals(r, p)
|
assertNotEquals(r, p)
|
||||||
|
|
||||||
assertTrue { Ristretto255.isValidPoint(p.encoded) }
|
assertTrue { Ristretto255.isValidPoint(p.encoded) }
|
||||||
assertTrue { Ristretto255.isValidPoint(q.encoded) }
|
assertTrue { Ristretto255.isValidPoint(q.encoded) }
|
||||||
assertTrue { Ristretto255.isValidPoint(r.encoded) }
|
assertTrue { Ristretto255.isValidPoint(r.encoded) }
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun testPointHexConversion() = runTest {
|
|
||||||
LibsodiumInitializer.initializeWithCallback {
|
|
||||||
repeat(10) {
|
|
||||||
val p = Ristretto255.Point.random()
|
|
||||||
|
|
||||||
assertEquals(p, Ristretto255.Point.fromHex(p.toHex()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun testIsValidPoint() = runTest {
|
|
||||||
LibsodiumInitializer.initializeWithCallback {
|
|
||||||
for (hexEncoded in badEncodings) {
|
|
||||||
assertFalse { Ristretto255.isValidPoint(LibsodiumUtil.fromHex(hexEncoded)) }
|
|
||||||
}
|
|
||||||
|
|
||||||
for (hexEncoded in basePointSmallMultiples) {
|
|
||||||
assertTrue { Ristretto255.isValidPoint(LibsodiumUtil.fromHex(hexEncoded)) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun testPointArithmetic() = runTest {
|
|
||||||
LibsodiumInitializer.initializeWithCallback {
|
|
||||||
for (i in basePointSmallMultiples.indices) {
|
|
||||||
val p = Ristretto255.Point.fromHex(basePointSmallMultiples[i])
|
|
||||||
val b = Ristretto255.Point.BASE
|
|
||||||
val n = Ristretto255.Scalar.fromUInt(i.toUInt() + 1U)
|
|
||||||
|
|
||||||
assertEquals(p, Ristretto255.scalarMultiplicationBase(n))
|
|
||||||
assertEquals(p, Ristretto255.scalarMultiplication(b, n))
|
|
||||||
assertEquals(p, n.multiplyWithBase())
|
|
||||||
|
|
||||||
for (j in 0..<i) {
|
|
||||||
val q = Ristretto255.Point.fromHex(basePointSmallMultiples[j])
|
|
||||||
val m = Ristretto255.Scalar.fromUInt(i.toUInt() - j.toUInt())
|
|
||||||
|
|
||||||
assertEquals(p, q + b * m)
|
|
||||||
assertEquals(p, b * m + q)
|
|
||||||
assertEquals(q, p - b * m)
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (j in i + 1..<basePointSmallMultiples.size) {
|
@Test
|
||||||
val q = Ristretto255.Point.fromHex(basePointSmallMultiples[j])
|
fun testPointHexConversion() = runTest {
|
||||||
val m = Ristretto255.Scalar.fromUInt(j.toUInt() - i.toUInt())
|
LibsodiumInitializer.initializeWithCallback {
|
||||||
|
repeat(10) {
|
||||||
|
val p = Ristretto255.Point.random()
|
||||||
|
|
||||||
assertEquals(q, p + b * m)
|
assertEquals(p, Ristretto255.Point.fromHex(p.toHex()))
|
||||||
assertEquals(q, b * m + p)
|
}
|
||||||
assertEquals(p, q - b * m)
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testPointFromHash() = runTest {
|
fun testIsValidPoint() = runTest {
|
||||||
LibsodiumInitializer.initializeWithCallback {
|
LibsodiumInitializer.initializeWithCallback {
|
||||||
for ((input, output) in fromHashTestVectors) {
|
for (hexEncoded in badEncodings) {
|
||||||
val outPoint = Ristretto255.Point.fromHex(output)
|
assertFalse { Ristretto255.isValidPoint(LibsodiumUtil.fromHex(hexEncoded)) }
|
||||||
val hash = Hash.sha512(input.encodeToUByteArray())
|
}
|
||||||
|
|
||||||
assertEquals(outPoint, Ristretto255.Point.fromHash(hash))
|
for (hexEncoded in basePointSmallMultiples) {
|
||||||
}
|
assertTrue { Ristretto255.isValidPoint(LibsodiumUtil.fromHex(hexEncoded)) }
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testRandomScalar() = runTest {
|
fun testPointArithmetic() = runTest {
|
||||||
LibsodiumInitializer.initializeWithCallback {
|
LibsodiumInitializer.initializeWithCallback {
|
||||||
val x = Ristretto255.Scalar.random()
|
for (i in basePointSmallMultiples.indices) {
|
||||||
val y = Ristretto255.Scalar.random()
|
val p = Ristretto255.Point.fromHex(basePointSmallMultiples[i])
|
||||||
val z = Ristretto255.Scalar.random()
|
val b = Ristretto255.Point.BASE
|
||||||
|
val n = Ristretto255.Scalar.fromUInt(i.toUInt() + 1U)
|
||||||
|
|
||||||
assertNotEquals(x, y)
|
assertEquals(p, Ristretto255.scalarMultiplicationBase(n))
|
||||||
assertNotEquals(y, z)
|
assertEquals(p, Ristretto255.scalarMultiplication(b, n))
|
||||||
assertNotEquals(z, x)
|
assertEquals(p, n.multiplyWithBase())
|
||||||
|
|
||||||
|
for (j in 0..<i) {
|
||||||
|
val q = Ristretto255.Point.fromHex(basePointSmallMultiples[j])
|
||||||
|
val m = Ristretto255.Scalar.fromUInt(i.toUInt() - j.toUInt())
|
||||||
|
|
||||||
|
assertEquals(p, q + b * m)
|
||||||
|
assertEquals(p, b * m + q)
|
||||||
|
assertEquals(q, p - b * m)
|
||||||
|
}
|
||||||
|
|
||||||
|
for (j in i + 1..<basePointSmallMultiples.size) {
|
||||||
|
val q = Ristretto255.Point.fromHex(basePointSmallMultiples[j])
|
||||||
|
val m = Ristretto255.Scalar.fromUInt(j.toUInt() - i.toUInt())
|
||||||
|
|
||||||
|
assertEquals(q, p + b * m)
|
||||||
|
assertEquals(q, b * m + p)
|
||||||
|
assertEquals(p, q - b * m)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testScalarHexConversion() = runTest {
|
fun testPointFromHash() = runTest {
|
||||||
LibsodiumInitializer.initializeWithCallback {
|
LibsodiumInitializer.initializeWithCallback {
|
||||||
repeat(10) {
|
for ((input, output) in fromHashTestVectors) {
|
||||||
val p = Ristretto255.Scalar.random()
|
val outPoint = Ristretto255.Point.fromHex(output)
|
||||||
|
val hash = Hash.sha512(input.encodeToUByteArray())
|
||||||
|
|
||||||
assertEquals(p, Ristretto255.Scalar.fromHex(p.toHex()))
|
assertEquals(outPoint, Ristretto255.Point.fromHash(hash))
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testScalarArithmetic() = runTest {
|
fun testRandomScalar() = runTest {
|
||||||
LibsodiumInitializer.initializeWithCallback {
|
LibsodiumInitializer.initializeWithCallback {
|
||||||
repeat(10) {
|
val x = Ristretto255.Scalar.random()
|
||||||
val x = Ristretto255.Scalar.random()
|
val y = Ristretto255.Scalar.random()
|
||||||
val y = Ristretto255.Scalar.random()
|
val z = Ristretto255.Scalar.random()
|
||||||
|
|
||||||
val xInv = x.invert()
|
assertNotEquals(x, y)
|
||||||
val xComp = x.complement()
|
assertNotEquals(y, z)
|
||||||
val xNeg = -x
|
assertNotEquals(z, x)
|
||||||
|
}
|
||||||
assertEquals(Ristretto255.Scalar.ZERO, x + xNeg)
|
}
|
||||||
assertEquals(Ristretto255.Scalar.ZERO, xNeg + x)
|
|
||||||
assertEquals(Ristretto255.Scalar.ZERO, x - x)
|
@Test
|
||||||
|
fun testScalarHexConversion() = runTest {
|
||||||
assertEquals(x, x + Ristretto255.Scalar.ZERO)
|
LibsodiumInitializer.initializeWithCallback {
|
||||||
assertEquals(x, Ristretto255.Scalar.ZERO + x)
|
repeat(10) {
|
||||||
|
val p = Ristretto255.Scalar.random()
|
||||||
assertEquals(Ristretto255.Scalar.ONE, x + xComp)
|
|
||||||
assertEquals(Ristretto255.Scalar.ONE, xComp + x)
|
assertEquals(p, Ristretto255.Scalar.fromHex(p.toHex()))
|
||||||
|
}
|
||||||
assertEquals(Ristretto255.Scalar.ONE, x * xInv)
|
}
|
||||||
assertEquals(Ristretto255.Scalar.ONE, xInv * x)
|
}
|
||||||
assertEquals(Ristretto255.Scalar.ONE, x / x)
|
|
||||||
|
@Test
|
||||||
assertEquals(x, x * Ristretto255.Scalar.ONE)
|
fun testScalarArithmetic() = runTest {
|
||||||
assertEquals(x, Ristretto255.Scalar.ONE * x)
|
LibsodiumInitializer.initializeWithCallback {
|
||||||
|
repeat(10) {
|
||||||
assertEquals(y - x, y + xNeg)
|
val x = Ristretto255.Scalar.random()
|
||||||
assertEquals(y / x, y * xInv)
|
val y = Ristretto255.Scalar.random()
|
||||||
}
|
|
||||||
|
val xInv = x.invert()
|
||||||
|
val xComp = x.complement()
|
||||||
|
val xNeg = -x
|
||||||
|
|
||||||
|
assertEquals(Ristretto255.Scalar.ZERO, x + xNeg)
|
||||||
|
assertEquals(Ristretto255.Scalar.ZERO, xNeg + x)
|
||||||
|
assertEquals(Ristretto255.Scalar.ZERO, x - x)
|
||||||
|
|
||||||
|
assertEquals(x, x + Ristretto255.Scalar.ZERO)
|
||||||
|
assertEquals(x, Ristretto255.Scalar.ZERO + x)
|
||||||
|
|
||||||
|
assertEquals(Ristretto255.Scalar.ONE, x + xComp)
|
||||||
|
assertEquals(Ristretto255.Scalar.ONE, xComp + x)
|
||||||
|
|
||||||
|
assertEquals(Ristretto255.Scalar.ONE, x * xInv)
|
||||||
|
assertEquals(Ristretto255.Scalar.ONE, xInv * x)
|
||||||
|
assertEquals(Ristretto255.Scalar.ONE, x / x)
|
||||||
|
|
||||||
|
assertEquals(x, x * Ristretto255.Scalar.ONE)
|
||||||
|
assertEquals(x, Ristretto255.Scalar.ONE * x)
|
||||||
|
|
||||||
|
assertEquals(y - x, y + xNeg)
|
||||||
|
assertEquals(y / x, y * xInv)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
@ -5,102 +5,102 @@ import ext.libsodium.com.ionspin.kotlin.crypto.toUByteArray
|
|||||||
import ext.libsodium.com.ionspin.kotlin.crypto.toUInt8Array
|
import ext.libsodium.com.ionspin.kotlin.crypto.toUInt8Array
|
||||||
|
|
||||||
actual abstract class Ed25519LowLevel actual constructor() {
|
actual abstract class Ed25519LowLevel actual constructor() {
|
||||||
actual fun isValidPoint(encoded: UByteArray): Boolean =
|
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 {
|
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()
|
return result.toUByteArray()
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun subtractPoints(p: UByteArray, q: UByteArray): UByteArray {
|
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.toUByteArray()
|
return result.toUByteArray()
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun encodedPointFromUniform(uniform: UByteArray): UByteArray {
|
actual fun encodedPointFromUniform(uniform: UByteArray): UByteArray {
|
||||||
val result = getSodium().crypto_core_ed25519_from_uniform(uniform.toUInt8Array())
|
val result = getSodium().crypto_core_ed25519_from_uniform(uniform.toUInt8Array())
|
||||||
|
|
||||||
return result.toUByteArray()
|
return result.toUByteArray()
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun randomEncodedPoint(): UByteArray {
|
actual fun randomEncodedPoint(): UByteArray {
|
||||||
val result = getSodium().crypto_core_ed25519_random()
|
val result = getSodium().crypto_core_ed25519_random()
|
||||||
|
|
||||||
return result.toUByteArray()
|
return result.toUByteArray()
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun randomEncodedScalar(): UByteArray {
|
actual fun randomEncodedScalar(): UByteArray {
|
||||||
val result = getSodium().crypto_core_ed25519_scalar_random()
|
val result = getSodium().crypto_core_ed25519_scalar_random()
|
||||||
|
|
||||||
return result.toUByteArray()
|
return result.toUByteArray()
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun invertScalar(scalar: UByteArray): UByteArray {
|
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()
|
return result.toUByteArray()
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun negateScalar(scalar: UByteArray): UByteArray {
|
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()
|
return result.toUByteArray()
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun complementScalar(scalar: UByteArray): UByteArray {
|
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()
|
return result.toUByteArray()
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun addScalars(x: UByteArray, y: UByteArray): UByteArray {
|
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()
|
return result.toUByteArray()
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun subtractScalars(x: UByteArray, y: UByteArray): UByteArray {
|
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()
|
return result.toUByteArray()
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun multiplyScalars(x: UByteArray, y: UByteArray): UByteArray {
|
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()
|
return result.toUByteArray()
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun reduceScalar(scalar: UByteArray): UByteArray {
|
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()
|
return result.toUByteArray()
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun scalarMultiplication(n: UByteArray, p: UByteArray): UByteArray {
|
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()
|
return result.toUByteArray()
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun scalarMultiplicationNoClamp(n: UByteArray, p: UByteArray): UByteArray {
|
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()
|
return result.toUByteArray()
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun scalarMultiplicationBase(n: UByteArray): UByteArray {
|
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()
|
return result.toUByteArray()
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun scalarMultiplicationBaseNoClamp(n: UByteArray): UByteArray {
|
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()
|
return result.toUByteArray()
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -5,90 +5,90 @@ import ext.libsodium.com.ionspin.kotlin.crypto.toUByteArray
|
|||||||
import ext.libsodium.com.ionspin.kotlin.crypto.toUInt8Array
|
import ext.libsodium.com.ionspin.kotlin.crypto.toUInt8Array
|
||||||
|
|
||||||
actual abstract class Ristretto255LowLevel actual constructor() {
|
actual abstract class Ristretto255LowLevel actual constructor() {
|
||||||
actual fun isValidPoint(encoded: UByteArray): Boolean =
|
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 {
|
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()
|
return result.toUByteArray()
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun subtractPoints(p: UByteArray, q: UByteArray): UByteArray {
|
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.toUByteArray()
|
return result.toUByteArray()
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun encodedPointFromHash(hash: UByteArray): UByteArray {
|
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()
|
return result.toUByteArray()
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun randomEncodedPoint(): UByteArray {
|
actual fun randomEncodedPoint(): UByteArray {
|
||||||
val result = getSodium().crypto_core_ristretto255_random()
|
val result = getSodium().crypto_core_ristretto255_random()
|
||||||
|
|
||||||
return result.toUByteArray()
|
return result.toUByteArray()
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun randomEncodedScalar(): UByteArray {
|
actual fun randomEncodedScalar(): UByteArray {
|
||||||
val result = getSodium().crypto_core_ristretto255_scalar_random()
|
val result = getSodium().crypto_core_ristretto255_scalar_random()
|
||||||
|
|
||||||
return result.toUByteArray()
|
return result.toUByteArray()
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun invertScalar(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 negateScalar(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 complementScalar(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()
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun addScalars(x: UByteArray, y: UByteArray): UByteArray {
|
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()
|
return result.toUByteArray()
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun subtractScalars(x: UByteArray, y: UByteArray): UByteArray {
|
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()
|
return result.toUByteArray()
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun multiplyScalars(x: UByteArray, y: UByteArray): UByteArray {
|
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()
|
return result.toUByteArray()
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun reduceScalar(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()
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun scalarMultiplication(n: UByteArray, p: UByteArray): UByteArray {
|
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()
|
return result.toUByteArray()
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun scalarMultiplicationBase(n: UByteArray): UByteArray {
|
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()
|
return result.toUByteArray()
|
||||||
}
|
}
|
||||||
}
|
}
|
File diff suppressed because it is too large
Load Diff
@ -4,133 +4,133 @@ import com.ionspin.kotlin.crypto.GeneralLibsodiumException.Companion.ensureLibso
|
|||||||
import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodiumJna
|
import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodiumJna
|
||||||
|
|
||||||
actual abstract class Ed25519LowLevel actual constructor() {
|
actual abstract class Ed25519LowLevel actual constructor() {
|
||||||
actual fun isValidPoint(encoded: UByteArray): Boolean =
|
actual fun isValidPoint(encoded: UByteArray): Boolean =
|
||||||
sodiumJna.crypto_core_ed25519_is_valid_point(encoded.asByteArray()) == 1
|
sodiumJna.crypto_core_ed25519_is_valid_point(encoded.asByteArray()) == 1
|
||||||
|
|
||||||
actual fun addPoints(p: UByteArray, q: UByteArray): UByteArray {
|
actual fun addPoints(p: UByteArray, q: UByteArray): UByteArray {
|
||||||
val result = UByteArray(crypto_core_ed25519_BYTES)
|
val result = UByteArray(crypto_core_ed25519_BYTES)
|
||||||
|
|
||||||
sodiumJna.crypto_core_ed25519_add(result.asByteArray(), p.asByteArray(), q.asByteArray())
|
sodiumJna.crypto_core_ed25519_add(result.asByteArray(), p.asByteArray(), q.asByteArray())
|
||||||
.ensureLibsodiumSuccess()
|
.ensureLibsodiumSuccess()
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun subtractPoints(p: UByteArray, q: UByteArray): UByteArray {
|
actual fun subtractPoints(p: UByteArray, q: UByteArray): UByteArray {
|
||||||
val result = UByteArray(crypto_core_ed25519_BYTES)
|
val result = UByteArray(crypto_core_ed25519_BYTES)
|
||||||
|
|
||||||
sodiumJna.crypto_core_ed25519_sub(result.asByteArray(), p.asByteArray(), q.asByteArray())
|
sodiumJna.crypto_core_ed25519_sub(result.asByteArray(), p.asByteArray(), q.asByteArray())
|
||||||
.ensureLibsodiumSuccess()
|
.ensureLibsodiumSuccess()
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun encodedPointFromUniform(uniform: UByteArray): UByteArray {
|
actual fun encodedPointFromUniform(uniform: UByteArray): UByteArray {
|
||||||
val result = UByteArray(crypto_core_ed25519_BYTES)
|
val result = UByteArray(crypto_core_ed25519_BYTES)
|
||||||
|
|
||||||
sodiumJna.crypto_core_ed25519_from_uniform(result.asByteArray(), uniform.asByteArray())
|
sodiumJna.crypto_core_ed25519_from_uniform(result.asByteArray(), uniform.asByteArray())
|
||||||
.ensureLibsodiumSuccess()
|
.ensureLibsodiumSuccess()
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun randomEncodedPoint(): UByteArray = UByteArray(crypto_core_ed25519_BYTES).also {
|
actual fun randomEncodedPoint(): UByteArray = UByteArray(crypto_core_ed25519_BYTES).also {
|
||||||
sodiumJna.crypto_core_ed25519_random(it.asByteArray())
|
sodiumJna.crypto_core_ed25519_random(it.asByteArray())
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun randomEncodedScalar(): UByteArray = UByteArray(crypto_core_ed25519_SCALARBYTES).also {
|
actual fun randomEncodedScalar(): UByteArray = UByteArray(crypto_core_ed25519_SCALARBYTES).also {
|
||||||
sodiumJna.crypto_core_ed25519_scalar_random(it.asByteArray())
|
sodiumJna.crypto_core_ed25519_scalar_random(it.asByteArray())
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun invertScalar(scalar: UByteArray): UByteArray {
|
actual fun invertScalar(scalar: UByteArray): UByteArray {
|
||||||
val result = UByteArray(crypto_core_ed25519_SCALARBYTES)
|
val result = UByteArray(crypto_core_ed25519_SCALARBYTES)
|
||||||
|
|
||||||
sodiumJna.crypto_core_ed25519_scalar_invert(result.asByteArray(), scalar.asByteArray()).ensureLibsodiumSuccess()
|
sodiumJna.crypto_core_ed25519_scalar_invert(result.asByteArray(), scalar.asByteArray()).ensureLibsodiumSuccess()
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun negateScalar(scalar: UByteArray): UByteArray {
|
actual fun negateScalar(scalar: UByteArray): UByteArray {
|
||||||
val result = UByteArray(crypto_core_ed25519_SCALARBYTES)
|
val result = UByteArray(crypto_core_ed25519_SCALARBYTES)
|
||||||
|
|
||||||
sodiumJna.crypto_core_ed25519_scalar_negate(result.asByteArray(), scalar.asByteArray())
|
sodiumJna.crypto_core_ed25519_scalar_negate(result.asByteArray(), scalar.asByteArray())
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun complementScalar(scalar: UByteArray): UByteArray {
|
actual fun complementScalar(scalar: UByteArray): UByteArray {
|
||||||
val result = UByteArray(crypto_core_ed25519_SCALARBYTES)
|
val result = UByteArray(crypto_core_ed25519_SCALARBYTES)
|
||||||
|
|
||||||
sodiumJna.crypto_core_ed25519_scalar_complement(result.asByteArray(), scalar.asByteArray())
|
sodiumJna.crypto_core_ed25519_scalar_complement(result.asByteArray(), scalar.asByteArray())
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun addScalars(x: UByteArray, y: UByteArray): UByteArray {
|
actual fun addScalars(x: UByteArray, y: UByteArray): UByteArray {
|
||||||
val result = UByteArray(crypto_core_ed25519_SCALARBYTES)
|
val result = UByteArray(crypto_core_ed25519_SCALARBYTES)
|
||||||
|
|
||||||
sodiumJna.crypto_core_ed25519_scalar_add(result.asByteArray(), x.asByteArray(), y.asByteArray())
|
sodiumJna.crypto_core_ed25519_scalar_add(result.asByteArray(), x.asByteArray(), y.asByteArray())
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun subtractScalars(x: UByteArray, y: UByteArray): UByteArray {
|
actual fun subtractScalars(x: UByteArray, y: UByteArray): UByteArray {
|
||||||
val result = UByteArray(crypto_core_ed25519_SCALARBYTES)
|
val result = UByteArray(crypto_core_ed25519_SCALARBYTES)
|
||||||
|
|
||||||
sodiumJna.crypto_core_ed25519_scalar_sub(result.asByteArray(), x.asByteArray(), y.asByteArray())
|
sodiumJna.crypto_core_ed25519_scalar_sub(result.asByteArray(), x.asByteArray(), y.asByteArray())
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun multiplyScalars(x: UByteArray, y: UByteArray): UByteArray {
|
actual fun multiplyScalars(x: UByteArray, y: UByteArray): UByteArray {
|
||||||
val result = UByteArray(crypto_core_ed25519_SCALARBYTES)
|
val result = UByteArray(crypto_core_ed25519_SCALARBYTES)
|
||||||
|
|
||||||
sodiumJna.crypto_core_ed25519_scalar_mul(result.asByteArray(), x.asByteArray(), y.asByteArray())
|
sodiumJna.crypto_core_ed25519_scalar_mul(result.asByteArray(), x.asByteArray(), y.asByteArray())
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun reduceScalar(scalar: UByteArray): UByteArray {
|
actual fun reduceScalar(scalar: UByteArray): UByteArray {
|
||||||
val result = UByteArray(crypto_core_ed25519_SCALARBYTES)
|
val result = UByteArray(crypto_core_ed25519_SCALARBYTES)
|
||||||
|
|
||||||
sodiumJna.crypto_core_ed25519_scalar_reduce(result.asByteArray(), scalar.asByteArray())
|
sodiumJna.crypto_core_ed25519_scalar_reduce(result.asByteArray(), scalar.asByteArray())
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun scalarMultiplication(n: UByteArray, p: UByteArray): UByteArray {
|
actual fun scalarMultiplication(n: UByteArray, p: UByteArray): UByteArray {
|
||||||
val result = UByteArray(crypto_core_ed25519_BYTES)
|
val result = UByteArray(crypto_core_ed25519_BYTES)
|
||||||
|
|
||||||
sodiumJna.crypto_scalarmult_ed25519(result.asByteArray(), n.asByteArray(), p.asByteArray())
|
sodiumJna.crypto_scalarmult_ed25519(result.asByteArray(), n.asByteArray(), p.asByteArray())
|
||||||
.ensureLibsodiumSuccess()
|
.ensureLibsodiumSuccess()
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun scalarMultiplicationNoClamp(n: UByteArray, p: UByteArray): UByteArray {
|
actual fun scalarMultiplicationNoClamp(n: UByteArray, p: UByteArray): UByteArray {
|
||||||
val result = UByteArray(crypto_core_ed25519_BYTES)
|
val result = UByteArray(crypto_core_ed25519_BYTES)
|
||||||
|
|
||||||
sodiumJna.crypto_scalarmult_ed25519_noclamp(result.asByteArray(), n.asByteArray(), p.asByteArray())
|
sodiumJna.crypto_scalarmult_ed25519_noclamp(result.asByteArray(), n.asByteArray(), p.asByteArray())
|
||||||
.ensureLibsodiumSuccess()
|
.ensureLibsodiumSuccess()
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun scalarMultiplicationBase(n: UByteArray): UByteArray {
|
actual fun scalarMultiplicationBase(n: UByteArray): UByteArray {
|
||||||
val result = UByteArray(crypto_core_ed25519_BYTES)
|
val result = UByteArray(crypto_core_ed25519_BYTES)
|
||||||
|
|
||||||
sodiumJna.crypto_scalarmult_ed25519_base(result.asByteArray(), n.asByteArray())
|
sodiumJna.crypto_scalarmult_ed25519_base(result.asByteArray(), n.asByteArray())
|
||||||
.ensureLibsodiumSuccess()
|
.ensureLibsodiumSuccess()
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun scalarMultiplicationBaseNoClamp(n: UByteArray): UByteArray {
|
actual fun scalarMultiplicationBaseNoClamp(n: UByteArray): UByteArray {
|
||||||
val result = UByteArray(crypto_core_ed25519_BYTES)
|
val result = UByteArray(crypto_core_ed25519_BYTES)
|
||||||
|
|
||||||
sodiumJna.crypto_scalarmult_ed25519_base_noclamp(result.asByteArray(), n.asByteArray())
|
sodiumJna.crypto_scalarmult_ed25519_base_noclamp(result.asByteArray(), n.asByteArray())
|
||||||
.ensureLibsodiumSuccess()
|
.ensureLibsodiumSuccess()
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -4,114 +4,115 @@ import com.ionspin.kotlin.crypto.GeneralLibsodiumException.Companion.ensureLibso
|
|||||||
import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodiumJna
|
import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodiumJna
|
||||||
|
|
||||||
actual abstract class Ristretto255LowLevel actual constructor() {
|
actual abstract class Ristretto255LowLevel actual constructor() {
|
||||||
actual fun isValidPoint(encoded: UByteArray): Boolean =
|
actual fun isValidPoint(encoded: UByteArray): Boolean =
|
||||||
sodiumJna.crypto_core_ristretto255_is_valid_point(encoded.asByteArray()) == 1
|
sodiumJna.crypto_core_ristretto255_is_valid_point(encoded.asByteArray()) == 1
|
||||||
|
|
||||||
actual fun addPoints(p: UByteArray, q: UByteArray): UByteArray {
|
actual fun addPoints(p: UByteArray, q: UByteArray): UByteArray {
|
||||||
val result = UByteArray(crypto_core_ristretto255_BYTES)
|
val result = UByteArray(crypto_core_ristretto255_BYTES)
|
||||||
|
|
||||||
sodiumJna.crypto_core_ristretto255_add(result.asByteArray(), p.asByteArray(), q.asByteArray())
|
sodiumJna.crypto_core_ristretto255_add(result.asByteArray(), p.asByteArray(), q.asByteArray())
|
||||||
.ensureLibsodiumSuccess()
|
.ensureLibsodiumSuccess()
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun subtractPoints(p: UByteArray, q: UByteArray): UByteArray {
|
actual fun subtractPoints(p: UByteArray, q: UByteArray): UByteArray {
|
||||||
val result = UByteArray(crypto_core_ristretto255_BYTES)
|
val result = UByteArray(crypto_core_ristretto255_BYTES)
|
||||||
|
|
||||||
sodiumJna.crypto_core_ristretto255_sub(result.asByteArray(), p.asByteArray(), q.asByteArray())
|
sodiumJna.crypto_core_ristretto255_sub(result.asByteArray(), p.asByteArray(), q.asByteArray())
|
||||||
.ensureLibsodiumSuccess()
|
.ensureLibsodiumSuccess()
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun encodedPointFromHash(hash: UByteArray): UByteArray {
|
actual fun encodedPointFromHash(hash: UByteArray): UByteArray {
|
||||||
val result = UByteArray(crypto_core_ristretto255_BYTES)
|
val result = UByteArray(crypto_core_ristretto255_BYTES)
|
||||||
|
|
||||||
sodiumJna.crypto_core_ristretto255_from_hash(result.asByteArray(), hash.asByteArray())
|
sodiumJna.crypto_core_ristretto255_from_hash(result.asByteArray(), hash.asByteArray())
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun randomEncodedPoint(): UByteArray = UByteArray(crypto_core_ristretto255_BYTES).also {
|
actual fun randomEncodedPoint(): UByteArray = UByteArray(crypto_core_ristretto255_BYTES).also {
|
||||||
sodiumJna.crypto_core_ristretto255_random(it.asByteArray())
|
sodiumJna.crypto_core_ristretto255_random(it.asByteArray())
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun randomEncodedScalar(): UByteArray = UByteArray(crypto_core_ristretto255_SCALARBYTES).also {
|
actual fun randomEncodedScalar(): UByteArray = UByteArray(crypto_core_ristretto255_SCALARBYTES).also {
|
||||||
sodiumJna.crypto_core_ristretto255_scalar_random(it.asByteArray())
|
sodiumJna.crypto_core_ristretto255_scalar_random(it.asByteArray())
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun invertScalar(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()
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun negateScalar(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())
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun complementScalar(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())
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun addScalars(x: UByteArray, y: UByteArray): UByteArray {
|
actual fun addScalars(x: UByteArray, y: UByteArray): UByteArray {
|
||||||
val result = UByteArray(crypto_core_ristretto255_SCALARBYTES)
|
val result = UByteArray(crypto_core_ristretto255_SCALARBYTES)
|
||||||
|
|
||||||
sodiumJna.crypto_core_ristretto255_scalar_add(result.asByteArray(), x.asByteArray(), y.asByteArray())
|
sodiumJna.crypto_core_ristretto255_scalar_add(result.asByteArray(), x.asByteArray(), y.asByteArray())
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun subtractScalars(x: UByteArray, y: UByteArray): UByteArray {
|
actual fun subtractScalars(x: UByteArray, y: UByteArray): UByteArray {
|
||||||
val result = UByteArray(crypto_core_ristretto255_SCALARBYTES)
|
val result = UByteArray(crypto_core_ristretto255_SCALARBYTES)
|
||||||
|
|
||||||
sodiumJna.crypto_core_ristretto255_scalar_sub(result.asByteArray(), x.asByteArray(), y.asByteArray())
|
sodiumJna.crypto_core_ristretto255_scalar_sub(result.asByteArray(), x.asByteArray(), y.asByteArray())
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun multiplyScalars(x: UByteArray, y: UByteArray): UByteArray {
|
actual fun multiplyScalars(x: UByteArray, y: UByteArray): UByteArray {
|
||||||
val result = UByteArray(crypto_core_ristretto255_SCALARBYTES)
|
val result = UByteArray(crypto_core_ristretto255_SCALARBYTES)
|
||||||
|
|
||||||
sodiumJna.crypto_core_ristretto255_scalar_mul(result.asByteArray(), x.asByteArray(), y.asByteArray())
|
sodiumJna.crypto_core_ristretto255_scalar_mul(result.asByteArray(), x.asByteArray(), y.asByteArray())
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun reduceScalar(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())
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun scalarMultiplication(n: UByteArray, p: UByteArray): UByteArray {
|
actual fun scalarMultiplication(n: UByteArray, p: UByteArray): UByteArray {
|
||||||
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()
|
.ensureLibsodiumSuccess()
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun scalarMultiplicationBase(n: UByteArray): UByteArray {
|
actual fun scalarMultiplicationBase(n: UByteArray): UByteArray {
|
||||||
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()
|
.ensureLibsodiumSuccess()
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -23,208 +23,208 @@ import libsodium.crypto_scalarmult_ed25519_noclamp
|
|||||||
|
|
||||||
|
|
||||||
actual abstract class Ed25519LowLevel actual constructor() {
|
actual abstract class Ed25519LowLevel actual constructor() {
|
||||||
actual fun isValidPoint(encoded: UByteArray): Boolean {
|
actual fun isValidPoint(encoded: UByteArray): Boolean {
|
||||||
return encoded.usePinned { crypto_core_ed25519_is_valid_point(it.toPtr()) == 1 }
|
return encoded.usePinned { crypto_core_ed25519_is_valid_point(it.toPtr()) == 1 }
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun addPoints(p: UByteArray, q: UByteArray): UByteArray {
|
actual fun addPoints(p: UByteArray, q: UByteArray): UByteArray {
|
||||||
val result = UByteArray(crypto_core_ed25519_BYTES)
|
val result = UByteArray(crypto_core_ed25519_BYTES)
|
||||||
|
|
||||||
result.usePinned { resultPinned ->
|
result.usePinned { resultPinned ->
|
||||||
p.usePinned { pPinned ->
|
p.usePinned { pPinned ->
|
||||||
q.usePinned { qPinned ->
|
q.usePinned { qPinned ->
|
||||||
crypto_core_ed25519_add(resultPinned.toPtr(), pPinned.toPtr(), qPinned.toPtr())
|
crypto_core_ed25519_add(resultPinned.toPtr(), pPinned.toPtr(), qPinned.toPtr())
|
||||||
.ensureLibsodiumSuccess()
|
.ensureLibsodiumSuccess()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
actual fun subtractPoints(p: UByteArray, q: UByteArray): UByteArray {
|
||||||
}
|
val result = UByteArray(crypto_core_ed25519_BYTES)
|
||||||
|
|
||||||
actual fun subtractPoints(p: UByteArray, q: UByteArray): UByteArray {
|
result.usePinned { resultPinned ->
|
||||||
val result = UByteArray(crypto_core_ed25519_BYTES)
|
p.usePinned { pPinned ->
|
||||||
|
q.usePinned { qPinned ->
|
||||||
result.usePinned { resultPinned ->
|
crypto_core_ed25519_sub(resultPinned.toPtr(), pPinned.toPtr(), qPinned.toPtr())
|
||||||
p.usePinned { pPinned ->
|
.ensureLibsodiumSuccess()
|
||||||
q.usePinned { qPinned ->
|
}
|
||||||
crypto_core_ed25519_sub(resultPinned.toPtr(), pPinned.toPtr(), qPinned.toPtr())
|
}
|
||||||
.ensureLibsodiumSuccess()
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
actual fun encodedPointFromUniform(uniform: UByteArray): UByteArray {
|
||||||
}
|
val result = UByteArray(crypto_core_ed25519_BYTES)
|
||||||
|
|
||||||
actual fun encodedPointFromUniform(uniform: UByteArray): UByteArray {
|
result.usePinned { resultPinned ->
|
||||||
val result = UByteArray(crypto_core_ed25519_BYTES)
|
uniform.usePinned { uniformPinned ->
|
||||||
|
crypto_core_ed25519_from_uniform(resultPinned.toPtr(), uniformPinned.toPtr())
|
||||||
result.usePinned { resultPinned ->
|
.ensureLibsodiumSuccess()
|
||||||
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
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
actual fun randomEncodedPoint(): UByteArray = UByteArray(crypto_core_ed25519_BYTES).apply {
|
||||||
}
|
usePinned { crypto_core_ed25519_random(it.toPtr()) }
|
||||||
|
}
|
||||||
|
|
||||||
actual fun subtractScalars(x: UByteArray, y: UByteArray): UByteArray {
|
actual fun randomEncodedScalar(): UByteArray = UByteArray(crypto_core_ed25519_SCALARBYTES).apply {
|
||||||
val result = UByteArray(crypto_core_ed25519_SCALARBYTES)
|
usePinned { crypto_core_ed25519_scalar_random(it.toPtr()) }
|
||||||
|
}
|
||||||
|
|
||||||
result.usePinned { resultPinned ->
|
actual fun invertScalar(scalar: UByteArray): UByteArray {
|
||||||
x.usePinned { xPinned ->
|
val result = UByteArray(crypto_core_ed25519_SCALARBYTES)
|
||||||
y.usePinned { yPinned ->
|
|
||||||
crypto_core_ed25519_scalar_sub(resultPinned.toPtr(), xPinned.toPtr(), yPinned.toPtr())
|
result.usePinned { resultPinned ->
|
||||||
|
scalar.usePinned { scalarPinned ->
|
||||||
|
crypto_core_ed25519_scalar_invert(resultPinned.toPtr(), scalarPinned.toPtr()).ensureLibsodiumSuccess()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
actual fun negateScalar(scalar: UByteArray): UByteArray {
|
||||||
}
|
val result = UByteArray(crypto_core_ed25519_SCALARBYTES)
|
||||||
|
|
||||||
actual fun multiplyScalars(x: UByteArray, y: UByteArray): UByteArray {
|
result.usePinned { resultPinned ->
|
||||||
val result = UByteArray(crypto_core_ed25519_SCALARBYTES)
|
scalar.usePinned { scalarPinned ->
|
||||||
|
crypto_core_ed25519_scalar_negate(resultPinned.toPtr(), scalarPinned.toPtr())
|
||||||
result.usePinned { resultPinned ->
|
}
|
||||||
x.usePinned { xPinned ->
|
|
||||||
y.usePinned { yPinned ->
|
|
||||||
crypto_core_ed25519_scalar_mul(resultPinned.toPtr(), xPinned.toPtr(), yPinned.toPtr())
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
actual fun complementScalar(scalar: UByteArray): UByteArray {
|
||||||
}
|
val result = UByteArray(crypto_core_ed25519_SCALARBYTES)
|
||||||
|
|
||||||
actual fun reduceScalar(scalar: UByteArray): UByteArray {
|
result.usePinned { resultPinned ->
|
||||||
val result = UByteArray(crypto_core_ed25519_SCALARBYTES)
|
scalar.usePinned { scalarPinned ->
|
||||||
|
crypto_core_ed25519_scalar_complement(resultPinned.toPtr(), scalarPinned.toPtr())
|
||||||
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 addScalars(x: UByteArray, y: UByteArray): UByteArray {
|
||||||
|
val result = UByteArray(crypto_core_ed25519_SCALARBYTES)
|
||||||
|
|
||||||
return result
|
result.usePinned { resultPinned ->
|
||||||
}
|
x.usePinned { xPinned ->
|
||||||
|
y.usePinned { yPinned ->
|
||||||
actual fun scalarMultiplicationNoClamp(n: UByteArray, p: UByteArray): UByteArray {
|
crypto_core_ed25519_scalar_add(resultPinned.toPtr(), xPinned.toPtr(), yPinned.toPtr())
|
||||||
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 subtractScalars(x: UByteArray, y: UByteArray): UByteArray {
|
||||||
|
val result = UByteArray(crypto_core_ed25519_SCALARBYTES)
|
||||||
|
|
||||||
return result
|
result.usePinned { resultPinned ->
|
||||||
}
|
x.usePinned { xPinned ->
|
||||||
|
y.usePinned { yPinned ->
|
||||||
|
crypto_core_ed25519_scalar_sub(resultPinned.toPtr(), xPinned.toPtr(), yPinned.toPtr())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
actual fun scalarMultiplicationBase(n: UByteArray): UByteArray {
|
return result
|
||||||
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 multiplyScalars(x: UByteArray, y: UByteArray): UByteArray {
|
||||||
}
|
val result = UByteArray(crypto_core_ed25519_SCALARBYTES)
|
||||||
|
|
||||||
actual fun scalarMultiplicationBaseNoClamp(n: UByteArray): UByteArray {
|
result.usePinned { resultPinned ->
|
||||||
val result = UByteArray(crypto_core_ed25519_BYTES)
|
x.usePinned { xPinned ->
|
||||||
|
y.usePinned { yPinned ->
|
||||||
|
crypto_core_ed25519_scalar_mul(resultPinned.toPtr(), xPinned.toPtr(), yPinned.toPtr())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
result.usePinned { resultPinned ->
|
return result
|
||||||
n.usePinned { nPinned ->
|
|
||||||
crypto_scalarmult_ed25519_base_noclamp(resultPinned.toPtr(), nPinned.toPtr())
|
|
||||||
.ensureLibsodiumSuccess()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
|
}
|
||||||
}
|
}
|
@ -21,178 +21,181 @@ import libsodium.crypto_scalarmult_ristretto255_base
|
|||||||
|
|
||||||
|
|
||||||
actual abstract class Ristretto255LowLevel actual constructor() {
|
actual abstract class Ristretto255LowLevel actual constructor() {
|
||||||
actual fun isValidPoint(encoded: UByteArray): Boolean {
|
actual fun isValidPoint(encoded: UByteArray): Boolean {
|
||||||
return encoded.usePinned { crypto_core_ristretto255_is_valid_point(it.toPtr()) == 1 }
|
return encoded.usePinned { crypto_core_ristretto255_is_valid_point(it.toPtr()) == 1 }
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun addPoints(p: UByteArray, q: UByteArray): UByteArray {
|
actual fun addPoints(p: UByteArray, q: UByteArray): UByteArray {
|
||||||
val result = UByteArray(crypto_core_ristretto255_BYTES)
|
val result = UByteArray(crypto_core_ristretto255_BYTES)
|
||||||
|
|
||||||
result.usePinned { resultPinned ->
|
result.usePinned { resultPinned ->
|
||||||
p.usePinned { pPinned ->
|
p.usePinned { pPinned ->
|
||||||
q.usePinned { qPinned ->
|
q.usePinned { qPinned ->
|
||||||
crypto_core_ristretto255_add(resultPinned.toPtr(), pPinned.toPtr(), qPinned.toPtr())
|
crypto_core_ristretto255_add(resultPinned.toPtr(), pPinned.toPtr(), qPinned.toPtr())
|
||||||
.ensureLibsodiumSuccess()
|
.ensureLibsodiumSuccess()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
actual fun subtractPoints(p: UByteArray, q: UByteArray): UByteArray {
|
||||||
}
|
val result = UByteArray(crypto_core_ristretto255_BYTES)
|
||||||
|
|
||||||
actual fun subtractPoints(p: UByteArray, q: UByteArray): UByteArray {
|
result.usePinned { resultPinned ->
|
||||||
val result = UByteArray(crypto_core_ristretto255_BYTES)
|
p.usePinned { pPinned ->
|
||||||
|
q.usePinned { qPinned ->
|
||||||
result.usePinned { resultPinned ->
|
crypto_core_ristretto255_sub(resultPinned.toPtr(), pPinned.toPtr(), qPinned.toPtr())
|
||||||
p.usePinned { pPinned ->
|
.ensureLibsodiumSuccess()
|
||||||
q.usePinned { qPinned ->
|
}
|
||||||
crypto_core_ristretto255_sub(resultPinned.toPtr(), pPinned.toPtr(), qPinned.toPtr())
|
}
|
||||||
.ensureLibsodiumSuccess()
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
actual fun encodedPointFromHash(hash: UByteArray): UByteArray {
|
||||||
}
|
val result = UByteArray(crypto_core_ristretto255_BYTES)
|
||||||
|
|
||||||
actual fun encodedPointFromHash(hash: UByteArray): UByteArray {
|
result.usePinned { resultPinned ->
|
||||||
val result = UByteArray(crypto_core_ristretto255_BYTES)
|
hash.usePinned { hashPinned ->
|
||||||
|
crypto_core_ristretto255_from_hash(resultPinned.toPtr(), hashPinned.toPtr())
|
||||||
result.usePinned { resultPinned ->
|
}
|
||||||
hash.usePinned { hashPinned ->
|
|
||||||
crypto_core_ristretto255_from_hash(resultPinned.toPtr(), hashPinned.toPtr())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
actual fun randomEncodedPoint(): UByteArray = UByteArray(crypto_core_ristretto255_BYTES).apply {
|
|
||||||
usePinned { crypto_core_ristretto255_random(it.toPtr()) }
|
|
||||||
}
|
|
||||||
|
|
||||||
actual fun randomEncodedScalar(): UByteArray = UByteArray(crypto_core_ristretto255_SCALARBYTES).apply {
|
|
||||||
usePinned { crypto_core_ristretto255_scalar_random(it.toPtr()) }
|
|
||||||
}
|
|
||||||
|
|
||||||
actual fun invertScalar(scalar: UByteArray): UByteArray {
|
|
||||||
val result = UByteArray(crypto_core_ristretto255_SCALARBYTES)
|
|
||||||
|
|
||||||
result.usePinned { resultPinned ->
|
|
||||||
scalar.usePinned { scalarPinned ->
|
|
||||||
crypto_core_ristretto255_scalar_invert(resultPinned.toPtr(), scalarPinned.toPtr()).ensureLibsodiumSuccess()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
actual fun negateScalar(scalar: UByteArray): UByteArray {
|
|
||||||
val result = UByteArray(crypto_core_ristretto255_SCALARBYTES)
|
|
||||||
|
|
||||||
result.usePinned { resultPinned ->
|
|
||||||
scalar.usePinned { scalarPinned ->
|
|
||||||
crypto_core_ristretto255_scalar_negate(resultPinned.toPtr(), scalarPinned.toPtr())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
actual fun complementScalar(scalar: UByteArray): UByteArray {
|
|
||||||
val result = UByteArray(crypto_core_ristretto255_SCALARBYTES)
|
|
||||||
|
|
||||||
result.usePinned { resultPinned ->
|
|
||||||
scalar.usePinned { scalarPinned ->
|
|
||||||
crypto_core_ristretto255_scalar_complement(resultPinned.toPtr(), scalarPinned.toPtr())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
actual fun addScalars(x: UByteArray, y: UByteArray): UByteArray {
|
|
||||||
val result = UByteArray(crypto_core_ristretto255_SCALARBYTES)
|
|
||||||
|
|
||||||
result.usePinned { resultPinned ->
|
|
||||||
x.usePinned { xPinned ->
|
|
||||||
y.usePinned { yPinned ->
|
|
||||||
crypto_core_ristretto255_scalar_add(resultPinned.toPtr(), xPinned.toPtr(), yPinned.toPtr())
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
actual fun randomEncodedPoint(): UByteArray = UByteArray(crypto_core_ristretto255_BYTES).apply {
|
||||||
}
|
usePinned { crypto_core_ristretto255_random(it.toPtr()) }
|
||||||
|
}
|
||||||
|
|
||||||
actual fun subtractScalars(x: UByteArray, y: UByteArray): UByteArray {
|
actual fun randomEncodedScalar(): UByteArray = UByteArray(crypto_core_ristretto255_SCALARBYTES).apply {
|
||||||
val result = UByteArray(crypto_core_ristretto255_SCALARBYTES)
|
usePinned { crypto_core_ristretto255_scalar_random(it.toPtr()) }
|
||||||
|
}
|
||||||
|
|
||||||
result.usePinned { resultPinned ->
|
actual fun invertScalar(scalar: UByteArray): UByteArray {
|
||||||
x.usePinned { xPinned ->
|
val result = UByteArray(crypto_core_ristretto255_SCALARBYTES)
|
||||||
y.usePinned { yPinned ->
|
|
||||||
crypto_core_ristretto255_scalar_sub(resultPinned.toPtr(), xPinned.toPtr(), yPinned.toPtr())
|
result.usePinned { resultPinned ->
|
||||||
|
scalar.usePinned { scalarPinned ->
|
||||||
|
crypto_core_ristretto255_scalar_invert(
|
||||||
|
resultPinned.toPtr(),
|
||||||
|
scalarPinned.toPtr()
|
||||||
|
).ensureLibsodiumSuccess()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
actual fun negateScalar(scalar: UByteArray): UByteArray {
|
||||||
}
|
val result = UByteArray(crypto_core_ristretto255_SCALARBYTES)
|
||||||
|
|
||||||
actual fun multiplyScalars(x: UByteArray, y: UByteArray): UByteArray {
|
result.usePinned { resultPinned ->
|
||||||
val result = UByteArray(crypto_core_ristretto255_SCALARBYTES)
|
scalar.usePinned { scalarPinned ->
|
||||||
|
crypto_core_ristretto255_scalar_negate(resultPinned.toPtr(), scalarPinned.toPtr())
|
||||||
result.usePinned { resultPinned ->
|
}
|
||||||
x.usePinned { xPinned ->
|
|
||||||
y.usePinned { yPinned ->
|
|
||||||
crypto_core_ristretto255_scalar_mul(resultPinned.toPtr(), xPinned.toPtr(), yPinned.toPtr())
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
actual fun complementScalar(scalar: UByteArray): UByteArray {
|
||||||
}
|
val result = UByteArray(crypto_core_ristretto255_SCALARBYTES)
|
||||||
|
|
||||||
actual fun reduceScalar(scalar: UByteArray): UByteArray {
|
result.usePinned { resultPinned ->
|
||||||
val result = UByteArray(crypto_core_ristretto255_SCALARBYTES)
|
scalar.usePinned { scalarPinned ->
|
||||||
|
crypto_core_ristretto255_scalar_complement(resultPinned.toPtr(), scalarPinned.toPtr())
|
||||||
result.usePinned { resultPinned ->
|
}
|
||||||
scalar.usePinned { scalarPinned ->
|
|
||||||
crypto_core_ristretto255_scalar_reduce(resultPinned.toPtr(), scalarPinned.toPtr())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
actual fun scalarMultiplication(n: UByteArray, p: UByteArray): UByteArray {
|
|
||||||
val result = UByteArray(crypto_core_ristretto255_BYTES)
|
|
||||||
|
|
||||||
result.usePinned { resultPinned ->
|
|
||||||
n.usePinned { nPinned ->
|
|
||||||
p.usePinned { pPinned ->
|
|
||||||
crypto_scalarmult_ristretto255(resultPinned.toPtr(), nPinned.toPtr(), pPinned.toPtr())
|
|
||||||
.ensureLibsodiumSuccess()
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
actual fun addScalars(x: UByteArray, y: UByteArray): UByteArray {
|
||||||
|
val result = UByteArray(crypto_core_ristretto255_SCALARBYTES)
|
||||||
|
|
||||||
return result
|
result.usePinned { resultPinned ->
|
||||||
}
|
x.usePinned { xPinned ->
|
||||||
|
y.usePinned { yPinned ->
|
||||||
|
crypto_core_ristretto255_scalar_add(resultPinned.toPtr(), xPinned.toPtr(), yPinned.toPtr())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
actual fun scalarMultiplicationBase(n: UByteArray): UByteArray {
|
return result
|
||||||
val result = UByteArray(crypto_core_ristretto255_BYTES)
|
|
||||||
|
|
||||||
result.usePinned { resultPinned ->
|
|
||||||
n.usePinned { nPinned ->
|
|
||||||
crypto_scalarmult_ristretto255_base(resultPinned.toPtr(), nPinned.toPtr())
|
|
||||||
.ensureLibsodiumSuccess()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
actual fun subtractScalars(x: UByteArray, y: UByteArray): UByteArray {
|
||||||
}
|
val result = UByteArray(crypto_core_ristretto255_SCALARBYTES)
|
||||||
|
|
||||||
|
result.usePinned { resultPinned ->
|
||||||
|
x.usePinned { xPinned ->
|
||||||
|
y.usePinned { yPinned ->
|
||||||
|
crypto_core_ristretto255_scalar_sub(resultPinned.toPtr(), xPinned.toPtr(), yPinned.toPtr())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
actual fun multiplyScalars(x: UByteArray, y: UByteArray): UByteArray {
|
||||||
|
val result = UByteArray(crypto_core_ristretto255_SCALARBYTES)
|
||||||
|
|
||||||
|
result.usePinned { resultPinned ->
|
||||||
|
x.usePinned { xPinned ->
|
||||||
|
y.usePinned { yPinned ->
|
||||||
|
crypto_core_ristretto255_scalar_mul(resultPinned.toPtr(), xPinned.toPtr(), yPinned.toPtr())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
actual fun reduceScalar(scalar: UByteArray): UByteArray {
|
||||||
|
val result = UByteArray(crypto_core_ristretto255_SCALARBYTES)
|
||||||
|
|
||||||
|
result.usePinned { resultPinned ->
|
||||||
|
scalar.usePinned { scalarPinned ->
|
||||||
|
crypto_core_ristretto255_scalar_reduce(resultPinned.toPtr(), scalarPinned.toPtr())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
actual fun scalarMultiplication(n: UByteArray, p: UByteArray): UByteArray {
|
||||||
|
val result = UByteArray(crypto_core_ristretto255_BYTES)
|
||||||
|
|
||||||
|
result.usePinned { resultPinned ->
|
||||||
|
n.usePinned { nPinned ->
|
||||||
|
p.usePinned { pPinned ->
|
||||||
|
crypto_scalarmult_ristretto255(resultPinned.toPtr(), nPinned.toPtr(), pPinned.toPtr())
|
||||||
|
.ensureLibsodiumSuccess()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
actual fun scalarMultiplicationBase(n: UByteArray): UByteArray {
|
||||||
|
val result = UByteArray(crypto_core_ristretto255_BYTES)
|
||||||
|
|
||||||
|
result.usePinned { resultPinned ->
|
||||||
|
n.usePinned { nPinned ->
|
||||||
|
crypto_scalarmult_ristretto255_base(resultPinned.toPtr(), nPinned.toPtr())
|
||||||
|
.ensureLibsodiumSuccess()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user