Merge pull request #1821 from KotlinGeekDev/kmp-completeness
Kmp completeness, Part 2 - Libsodium
This commit is contained in:
@@ -61,12 +61,48 @@ kotlin {
|
||||
// project can be found here:
|
||||
// https://developer.android.com/kotlin/multiplatform/migrate
|
||||
val xcfName = "quartz-kmpKit"
|
||||
val libsodiumPath = project.file("src/nativeInterop/libsodium")
|
||||
val libsodiumHeaderFilesPath = project.file("$libsodiumPath/include/sodium")
|
||||
|
||||
// This generates the Libsodium definition file, necessary for creating native bindings(a Kotlin API) for libsodium(for iOS).
|
||||
// val headersTask = tasks.register<Exec>("ExtractLibsodiumHeaders") {
|
||||
// val unpackDirectory = "$libsodiumPath/include"
|
||||
// unzipTo(
|
||||
// project.file(unpackDirectory),
|
||||
// project.file("$unpackDirectory/sodium.zip")
|
||||
// )
|
||||
// }
|
||||
|
||||
val libsodiumDefFileGeneration = tasks.register<Exec>("GenerateSodiumCinteropFile") {
|
||||
val definitionFile = project.file("src/nativeInterop/cinterop/Clibsodium.def")
|
||||
if (!definitionFile.exists()){
|
||||
definitionFile.createNewFile()
|
||||
definitionFile.writeText("package = Clibsodium")
|
||||
definitionFile.appendText("\n" + "staticLibraries = libsodium.a libsodium-simulator.a")
|
||||
definitionFile.appendText("\n" + "libraryPaths = ${libsodiumPath}/ios/lib ${libsodiumPath}/ios-simulators/lib")
|
||||
}
|
||||
}
|
||||
|
||||
listOf(
|
||||
iosArm64(),
|
||||
iosX64(),
|
||||
iosSimulatorArm64(),
|
||||
).forEach { target ->
|
||||
|
||||
target.compilations.getByName("main") {
|
||||
// headersTask.get()
|
||||
val Clibsodium by cinterops.creating {
|
||||
assert(project.file("Clibsodium.def").exists())
|
||||
definitionFile.set(project.file("Clibsodium.def"))
|
||||
|
||||
headers(
|
||||
"$libsodiumHeaderFilesPath/crypto_aead_xchacha20poly1305.h",
|
||||
"$libsodiumHeaderFilesPath/crypto_core_hchacha20.h",
|
||||
"$libsodiumHeaderFilesPath/crypto_stream_chacha20.h"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
target.swiftPackageConfig(cinteropName = "swiftbridge") {
|
||||
minIos = "17"
|
||||
minMacos = "14"
|
||||
@@ -239,6 +275,8 @@ kotlin {
|
||||
implementation(libs.charlietap.cachemap)
|
||||
implementation(libs.net.thauvin.erik.urlencoder.lib)
|
||||
implementation(libs.dev.whyoleg.cryptography.provider.apple.optimal)
|
||||
implementation("io.github.andreypfau:kotlinx-crypto-hmac:0.0.4")
|
||||
implementation("io.github.andreypfau:kotlinx-crypto-sha2:0.0.4")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,14 @@
|
||||
*/
|
||||
package com.vitorpamplona.quartz.utils
|
||||
|
||||
import kotlinx.cinterop.CValuesRef
|
||||
import kotlinx.cinterop.ExperimentalForeignApi
|
||||
import kotlinx.cinterop.UByteVar
|
||||
import kotlinx.cinterop.refTo
|
||||
import kotlin.experimental.ExperimentalNativeApi
|
||||
|
||||
actual object LibSodiumInstance {
|
||||
@OptIn(ExperimentalForeignApi::class)
|
||||
actual fun cryptoAeadXChaCha20Poly1305IetfDecrypt(
|
||||
message: ByteArray,
|
||||
nSec: ByteArray,
|
||||
@@ -29,9 +36,22 @@ actual object LibSodiumInstance {
|
||||
nPub: ByteArray,
|
||||
k: ByteArray,
|
||||
): Boolean {
|
||||
TODO("Not yet implemented")
|
||||
val returnCode =
|
||||
Clibsodium.crypto_aead_xchacha20poly1305_ietf_decrypt(
|
||||
m = message.uRefTo(0),
|
||||
mlen_p = ulongArrayOf(message.size.toULong()).refTo(0),
|
||||
nsec = nSec.uRefTo(0),
|
||||
c = ciphertext.uRefTo(0),
|
||||
clen = ciphertext.size.toULong(),
|
||||
ad = ad.uRefTo(0),
|
||||
adlen = ad.size.toULong(),
|
||||
npub = nPub.uRefTo(0),
|
||||
k = k.uRefTo(0),
|
||||
)
|
||||
return returnCode == 0
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalForeignApi::class)
|
||||
actual fun cryptoAeadXChaCha20Poly1305IetfEncrypt(
|
||||
ciphertext: ByteArray,
|
||||
message: ByteArray,
|
||||
@@ -40,22 +60,71 @@ actual object LibSodiumInstance {
|
||||
nPub: ByteArray,
|
||||
k: ByteArray,
|
||||
): Boolean {
|
||||
TODO("Not yet implemented")
|
||||
val retCode =
|
||||
Clibsodium.crypto_aead_xchacha20poly1305_ietf_encrypt(
|
||||
c = ciphertext.uRefTo(0),
|
||||
clen_p = ulongArrayOf(ciphertext.size.toULong()).refTo(0),
|
||||
m = message.uRefTo(0),
|
||||
mlen = message.size.toULong(),
|
||||
ad = ad.uRefTo(0),
|
||||
adlen = ad.size.toULong(),
|
||||
nsec = nSec.uRefTo(0),
|
||||
npub = nPub.uRefTo(0),
|
||||
k = k.uRefTo(0),
|
||||
)
|
||||
|
||||
return retCode == 0
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalForeignApi::class)
|
||||
actual fun cryptoStreamChaCha20IetfXor(
|
||||
message: ByteArray,
|
||||
nonce: ByteArray?,
|
||||
key: ByteArray?,
|
||||
): ByteArray {
|
||||
TODO("Not yet implemented")
|
||||
val ciphertext = ByteArray(message.size)
|
||||
Clibsodium.crypto_stream_chacha20_ietf_xor(
|
||||
c = ciphertext.uRefTo(0),
|
||||
m = message.uRefTo(0),
|
||||
mlen = message.size.toULong(),
|
||||
n = nonce?.uRefTo(0),
|
||||
k = key?.uRefTo(0),
|
||||
)
|
||||
return ciphertext
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalForeignApi::class, ExperimentalNativeApi::class)
|
||||
actual fun cryptoStreamXChaCha20Xor(
|
||||
messageBytes: ByteArray,
|
||||
nonce: ByteArray,
|
||||
key: ByteArray,
|
||||
): ByteArray {
|
||||
TODO("Not yet implemented")
|
||||
val cipher = ByteArray(messageBytes.size)
|
||||
val k2 = ByteArray(32)
|
||||
|
||||
val nonceChaCha = nonce.drop(16).toByteArray()
|
||||
assert(nonceChaCha.size == 8)
|
||||
|
||||
Clibsodium.crypto_core_hchacha20(
|
||||
out = k2.uRefTo(0),
|
||||
nonce.uRefTo(0),
|
||||
k = key.uRefTo(0),
|
||||
c = null,
|
||||
)
|
||||
|
||||
val resultCode =
|
||||
Clibsodium.crypto_stream_chacha20_xor_ic(
|
||||
c = cipher.uRefTo(0),
|
||||
m = messageBytes.uRefTo(0),
|
||||
mlen = messageBytes.size.toULong(),
|
||||
n = nonceChaCha.uRefTo(0),
|
||||
ic = 0L.toULong(),
|
||||
k = k2.uRefTo(0),
|
||||
)
|
||||
return if (resultCode == 0) cipher else throw IllegalStateException("Could not decrypt message")
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalForeignApi::class)
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
private fun ByteArray.uRefTo(index: Int) = refTo(index) as CValuesRef<UByteVar>
|
||||
|
||||
@@ -20,62 +20,46 @@
|
||||
*/
|
||||
package com.vitorpamplona.quartz.utils.mac
|
||||
|
||||
import dev.whyoleg.cryptography.CryptographyProvider
|
||||
import dev.whyoleg.cryptography.algorithms.HMAC
|
||||
import dev.whyoleg.cryptography.algorithms.SHA256
|
||||
import dev.whyoleg.cryptography.algorithms.SHA512
|
||||
import dev.whyoleg.cryptography.providers.apple.Apple
|
||||
import io.github.andreypfau.kotlinx.crypto.HMac
|
||||
import io.github.andreypfau.kotlinx.crypto.Sha256
|
||||
import io.github.andreypfau.kotlinx.crypto.Sha512
|
||||
|
||||
actual class MacInstance actual constructor(
|
||||
algorithm: String,
|
||||
key: ByteArray,
|
||||
) {
|
||||
private val cryptoProvider = CryptographyProvider.Apple
|
||||
|
||||
private var internalMacInstance: HMAC.Key =
|
||||
cryptoProvider
|
||||
.get(HMAC)
|
||||
.keyDecoder(digestForAlgorithm(algorithm))
|
||||
.decodeFromByteArrayBlocking(HMAC.Key.Format.RAW, key)
|
||||
|
||||
private var hmacSignFunction = internalMacInstance.signatureGenerator().createSignFunction()
|
||||
private var nativeHmac = HMac(digestForAlgorithm(algorithm), key)
|
||||
|
||||
actual fun init(
|
||||
key: ByteArray,
|
||||
algorithm: String,
|
||||
) {
|
||||
internalMacInstance =
|
||||
cryptoProvider
|
||||
.get(HMAC)
|
||||
.keyDecoder(digestForAlgorithm(algorithm))
|
||||
.decodeFromByteArrayBlocking(HMAC.Key.Format.RAW, key)
|
||||
|
||||
hmacSignFunction = internalMacInstance.signatureGenerator().createSignFunction()
|
||||
nativeHmac = HMac(digestForAlgorithm(algorithm), key)
|
||||
}
|
||||
|
||||
actual fun getMacLength(): Int = hmacSignFunction.signIntoByteArray(internalMacInstance.encodeToByteArrayBlocking(HMAC.Key.Format.RAW))
|
||||
actual fun getMacLength(): Int = nativeHmac.macSize
|
||||
|
||||
actual fun update(array: ByteArray) {
|
||||
hmacSignFunction.update(array)
|
||||
nativeHmac.update(array)
|
||||
}
|
||||
|
||||
actual fun update(byte: Byte) {
|
||||
hmacSignFunction.update(byteArrayOf(byte))
|
||||
nativeHmac.update(byte)
|
||||
}
|
||||
|
||||
actual fun doFinal(): ByteArray = hmacSignFunction.signToByteArray()
|
||||
actual fun doFinal(): ByteArray = nativeHmac.digest()
|
||||
|
||||
actual fun doFinal(
|
||||
output: ByteArray,
|
||||
offset: Int,
|
||||
) {
|
||||
hmacSignFunction.signIntoByteArray(output, offset)
|
||||
nativeHmac.digest(output, offset)
|
||||
}
|
||||
|
||||
private fun digestForAlgorithm(algorithm: String) =
|
||||
when (algorithm) {
|
||||
"HmacSHA256" -> SHA256
|
||||
"HmacSHA512" -> SHA512
|
||||
"HmacSHA256" -> Sha256()
|
||||
"HmacSHA512" -> Sha512()
|
||||
else -> error("Algorithm is not yet supported.")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Vitor Pamplona
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||
* Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.quartz.nip44Encryption
|
||||
|
||||
import com.vitorpamplona.quartz.nip01Core.core.hexToByteArray
|
||||
import com.vitorpamplona.quartz.nip01Core.core.toHexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.crypto.KeyPair
|
||||
import com.vitorpamplona.quartz.nip01Core.crypto.Nip01Crypto
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class Nip44v1Test {
|
||||
private val nip44v1 = Nip44v1()
|
||||
|
||||
@Test
|
||||
fun testSharedSecretCompatibilityWithCoracle() {
|
||||
val privateKey = "f410f88bcec6cbfda04d6a273c7b1dd8bba144cd45b71e87109cfa11dd7ed561"
|
||||
val publicKey = "765cd7cf91d3ad07423d114d5a39c61d52b2cdbc18ba055ddbbeec71fbe2aa2f"
|
||||
|
||||
val key =
|
||||
nip44v1.getSharedSecret(
|
||||
privateKey = privateKey.hexToByteArray(),
|
||||
pubKey = publicKey.hexToByteArray(),
|
||||
)
|
||||
|
||||
assertEquals("577c966f499dddd8e8dcc34e8f352e283cc177e53ae372794947e0b8ede7cfd8", key.toHexKey())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testSharedSecret() {
|
||||
val sender = KeyPair()
|
||||
val receiver = KeyPair()
|
||||
|
||||
val sharedSecret1 = nip44v1.getSharedSecret(sender.privKey!!, receiver.pubKey)
|
||||
val sharedSecret2 = nip44v1.getSharedSecret(receiver.privKey!!, sender.pubKey)
|
||||
|
||||
assertEquals(sharedSecret1.toHexKey(), sharedSecret2.toHexKey())
|
||||
|
||||
val secretKey1 = KeyPair(privKey = sharedSecret1)
|
||||
val secretKey2 = KeyPair(privKey = sharedSecret2)
|
||||
|
||||
assertEquals(secretKey1.pubKey.toHexKey(), secretKey2.pubKey.toHexKey())
|
||||
assertEquals(secretKey1.privKey?.toHexKey(), secretKey2.privKey?.toHexKey())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun encryptDecrypt() {
|
||||
val msg = "Hi"
|
||||
|
||||
val privateKey = Nip01Crypto.privKeyCreate()
|
||||
val publicKey = Nip01Crypto.pubKeyCreate(privateKey)
|
||||
|
||||
val encrypted = nip44v1.encrypt(msg, privateKey, publicKey)
|
||||
val decrypted = nip44v1.decrypt(encrypted, privateKey, publicKey)
|
||||
|
||||
assertEquals(msg, decrypted)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun encryptDecryptSharedSecret() {
|
||||
val msg = "Hi"
|
||||
|
||||
val privateKey = Nip01Crypto.privKeyCreate()
|
||||
val publicKey = Nip01Crypto.pubKeyCreate(privateKey)
|
||||
|
||||
val sharedSecret = nip44v1.getSharedSecret(privateKey, publicKey)
|
||||
|
||||
val encrypted = nip44v1.encrypt(msg, sharedSecret)
|
||||
val decrypted = nip44v1.decrypt(encrypted, sharedSecret)
|
||||
|
||||
assertEquals(msg, decrypted)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,182 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Vitor Pamplona
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||
* Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.quartz.nip44Encryption
|
||||
|
||||
import com.vitorpamplona.quartz.TestResourceLoader
|
||||
import com.vitorpamplona.quartz.nip01Core.core.JsonMapper
|
||||
import com.vitorpamplona.quartz.nip01Core.core.hexToByteArray
|
||||
import com.vitorpamplona.quartz.nip01Core.core.toHexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.crypto.KeyPair
|
||||
import com.vitorpamplona.quartz.nip01Core.crypto.Nip01Crypto
|
||||
import com.vitorpamplona.quartz.utils.RandomInstance
|
||||
import com.vitorpamplona.quartz.utils.sha256.sha256
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertNotNull
|
||||
import kotlin.test.assertNull
|
||||
import kotlin.test.fail
|
||||
|
||||
class Nip44v2Test {
|
||||
private val vectors: VectorFile =
|
||||
JsonMapper.jsonInstance.decodeFromString<VectorFile>(
|
||||
TestResourceLoader().loadString("nip44.vectors.json"),
|
||||
)
|
||||
|
||||
private val nip44v2 = Nip44v2()
|
||||
|
||||
@Test
|
||||
fun conversationKeyTest() {
|
||||
for (v in vectors.v2?.valid?.getConversationKey!!) {
|
||||
val conversationKey =
|
||||
nip44v2.getConversationKey(v.sec1!!.hexToByteArray(), v.pub2!!.hexToByteArray())
|
||||
|
||||
assertEquals(v.conversationKey, conversationKey.toHexKey())
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun paddingTest() {
|
||||
for (v in vectors.v2?.valid?.calcPaddedLen!!) {
|
||||
val actual = nip44v2.calcPaddedLen(v[0])
|
||||
assertEquals(v[1], actual)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testCompressedWith02Keys() {
|
||||
val privateKeyA = "f410f88bcec6cbfda04d6a273c7b1dd8bba144cd45b71e87109cfa11dd7ed561".hexToByteArray()
|
||||
val privateKeyB = "65f039136f8da8d3e87b4818746b53318d5481e24b2673f162815144223a0b5a".hexToByteArray()
|
||||
|
||||
val publicKeyA = Nip01Crypto.pubKeyCreate(privateKeyA)
|
||||
val publicKeyB = Nip01Crypto.pubKeyCreate(privateKeyB)
|
||||
|
||||
assertEquals(
|
||||
nip44v2.getConversationKey(privateKeyA, publicKeyB).toHexKey(),
|
||||
nip44v2.getConversationKey(privateKeyB, publicKeyA).toHexKey(),
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testCompressedWith03Keys() {
|
||||
val privateKeyA = "f410f88bcec6cbfda04d6a273c7b1dd8bba144cd45b71e87109cfa11dd7ed561".hexToByteArray()
|
||||
val privateKeyB = "e6159851715b4aa6190c22b899b0c792847de0a4435ac5b678f35738351c43b0".hexToByteArray()
|
||||
|
||||
val publicKeyA = Nip01Crypto.pubKeyCreate(privateKeyA)
|
||||
val publicKeyB = Nip01Crypto.pubKeyCreate(privateKeyB)
|
||||
|
||||
assertEquals(
|
||||
nip44v2.getConversationKey(privateKeyA, publicKeyB).toHexKey(),
|
||||
nip44v2.getConversationKey(privateKeyB, publicKeyA).toHexKey(),
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun encryptDecryptTest() {
|
||||
for (v in vectors.v2?.valid?.encryptDecrypt!!) {
|
||||
val pub2 = KeyPair(v.sec2!!.hexToByteArray())
|
||||
val conversationKey1 = nip44v2.getConversationKey(v.sec1!!.hexToByteArray(), pub2.pubKey)
|
||||
assertEquals(v.conversationKey, conversationKey1.toHexKey())
|
||||
|
||||
val ciphertext =
|
||||
nip44v2
|
||||
.encryptWithNonce(
|
||||
v.plaintext!!,
|
||||
conversationKey1,
|
||||
v.nonce!!.hexToByteArray(),
|
||||
).encodePayload()
|
||||
|
||||
assertEquals(v.payload, ciphertext)
|
||||
|
||||
val pub1 = KeyPair(v.sec1.hexToByteArray())
|
||||
val conversationKey2 = nip44v2.getConversationKey(v.sec2.hexToByteArray(), pub1.pubKey)
|
||||
assertEquals(v.conversationKey, conversationKey2.toHexKey())
|
||||
|
||||
val decrypted = nip44v2.decrypt(v.payload!!, conversationKey2)
|
||||
assertEquals(v.plaintext, decrypted)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun encryptDecryptLongTest() {
|
||||
for (v in vectors.v2?.valid?.encryptDecryptLongMsg!!) {
|
||||
val conversationKey = v.conversationKey!!.hexToByteArray()
|
||||
val plaintext = v.pattern!!.repeat(v.repeat!!)
|
||||
|
||||
assertEquals(v.plaintextSha256, sha256Hex(plaintext.encodeToByteArray()))
|
||||
|
||||
val ciphertext =
|
||||
nip44v2
|
||||
.encryptWithNonce(
|
||||
plaintext,
|
||||
conversationKey,
|
||||
v.nonce!!.hexToByteArray(),
|
||||
).encodePayload()
|
||||
|
||||
assertEquals(v.payloadSha256, sha256Hex(ciphertext.encodeToByteArray()))
|
||||
|
||||
val decrypted = nip44v2.decrypt(ciphertext, conversationKey)
|
||||
|
||||
assertEquals(plaintext, decrypted)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun extendedMessageLengths() {
|
||||
for (v in vectors.v2?.invalid?.encryptMsgLengths!!) {
|
||||
val key = RandomInstance.bytes(32)
|
||||
try {
|
||||
val input = "a".repeat(v)
|
||||
val result = nip44v2.encrypt(input, key)
|
||||
val decrypted = nip44v2.decrypt(result, key)
|
||||
assertEquals(input, decrypted)
|
||||
} catch (e: Exception) {
|
||||
assertNotNull(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun invalidDecrypt() {
|
||||
for (v in vectors.v2?.invalid?.decrypt!!) {
|
||||
try {
|
||||
val result = nip44v2.decrypt(v.payload!!, v.conversationKey!!.hexToByteArray())
|
||||
assertNull(result)
|
||||
// fail("Should Throw for ${v.note}")
|
||||
} catch (e: Exception) {
|
||||
assertNotNull(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun invalidConversationKey() {
|
||||
for (v in vectors.v2?.invalid?.getConversationKey!!) {
|
||||
try {
|
||||
nip44v2.getConversationKey(v.sec1!!.hexToByteArray(), v.pub2!!.hexToByteArray())
|
||||
fail("Should Throw for ${v.note}")
|
||||
} catch (e: Exception) {
|
||||
assertNotNull(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun sha256Hex(data: ByteArray) = sha256(data).toHexKey()
|
||||
}
|
||||
+103
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Vitor Pamplona
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||
* Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.quartz.nip44Encryption
|
||||
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class VectorFile(
|
||||
val v2: V2? = V2(),
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class V2(
|
||||
val valid: Valid? = Valid(),
|
||||
val invalid: Invalid? = Invalid(),
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class Valid(
|
||||
@SerialName("get_conversation_key") val getConversationKey: ArrayList<GetConversationKey> = arrayListOf(),
|
||||
@SerialName("get_message_keys") val getMessageKeys: GetMessageKeys? = GetMessageKeys(),
|
||||
@SerialName("calc_padded_len") val calcPaddedLen: ArrayList<ArrayList<Int>> = arrayListOf(),
|
||||
@SerialName("encrypt_decrypt") val encryptDecrypt: ArrayList<EncryptDecrypt> = arrayListOf(),
|
||||
@SerialName("encrypt_decrypt_long_msg")
|
||||
val encryptDecryptLongMsg: ArrayList<EncryptDecryptLongMsg> = arrayListOf(),
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class Invalid(
|
||||
@SerialName("encrypt_msg_lengths") val encryptMsgLengths: ArrayList<Int> = arrayListOf(),
|
||||
@SerialName("get_conversation_key") val getConversationKey: ArrayList<GetConversationKey> = arrayListOf(),
|
||||
@SerialName("decrypt") val decrypt: ArrayList<Decrypt> = arrayListOf(),
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class GetConversationKey(
|
||||
val sec1: String? = null,
|
||||
val pub2: String? = null,
|
||||
val note: String? = null,
|
||||
@SerialName("conversation_key") val conversationKey: String? = null,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class GetMessageKeys(
|
||||
@SerialName("conversation_key") val conversationKey: String? = null,
|
||||
val keys: ArrayList<Keys> = arrayListOf(),
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class Keys(
|
||||
@SerialName("nonce") val nonce: String? = null,
|
||||
@SerialName("chacha_key") val chachaKey: String? = null,
|
||||
@SerialName("chacha_nonce") val chachaNonce: String? = null,
|
||||
@SerialName("hmac_key") val hmacKey: String? = null,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class EncryptDecrypt(
|
||||
val sec1: String? = null,
|
||||
val sec2: String? = null,
|
||||
@SerialName("conversation_key") val conversationKey: String? = null,
|
||||
val nonce: String? = null,
|
||||
val plaintext: String? = null,
|
||||
val payload: String? = null,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class EncryptDecryptLongMsg(
|
||||
@SerialName("conversation_key") val conversationKey: String? = null,
|
||||
val nonce: String? = null,
|
||||
val pattern: String? = null,
|
||||
val repeat: Int? = null,
|
||||
@SerialName("plaintext_sha256") val plaintextSha256: String? = null,
|
||||
@SerialName("payload_sha256") val payloadSha256: String? = null,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class Decrypt(
|
||||
@SerialName("conversation_key") val conversationKey: String? = null,
|
||||
val nonce: String? = null,
|
||||
val plaintext: String? = null,
|
||||
val payload: String? = null,
|
||||
val note: String? = null,
|
||||
)
|
||||
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Vitor Pamplona
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||
* Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.quartz.nip49PrivKeyEnc
|
||||
|
||||
import com.vitorpamplona.quartz.nip01Core.core.toHexKey
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertNotNull
|
||||
import kotlin.test.fail
|
||||
|
||||
public class NIP49Test {
|
||||
companion object {
|
||||
val TEST_CASE = "ncryptsec1qgg9947rlpvqu76pj5ecreduf9jxhselq2nae2kghhvd5g7dgjtcxfqtd67p9m0w57lspw8gsq6yphnm8623nsl8xn9j4jdzz84zm3frztj3z7s35vpzmqf6ksu8r89qk5z2zxfmu5gv8th8wclt0h4p"
|
||||
|
||||
val TEST_CASE_EXPECTED = "3501454135014541350145413501453fefb02227e449e57cf4d3a3ce05378683"
|
||||
val TEST_CASE_PASSWORD = "nostr"
|
||||
|
||||
val MAIN_TEST_CASES =
|
||||
listOf<Nip49TestCase>(
|
||||
Nip49TestCase(".ksjabdk.aselqwe", "14c226dbdd865d5e1645e72c7470fd0a17feb42cc87b750bab6538171b3a3f8a", 1, 0x00),
|
||||
Nip49TestCase("skjdaklrnçurbç l", "f7f2f77f98890885462764afb15b68eb5f69979c8046ecb08cad7c4ae6b221ab", 2, 0x01),
|
||||
Nip49TestCase("777z7z7z7z7z7z7z", "11b25a101667dd9208db93c0827c6bdad66729a5b521156a7e9d3b22b3ae8944", 3, 0x02),
|
||||
Nip49TestCase(".ksjabdk.aselqwe", "14c226dbdd865d5e1645e72c7470fd0a17feb42cc87b750bab6538171b3a3f8a", 7, 0x00),
|
||||
Nip49TestCase("skjdaklrnçurbç l", "f7f2f77f98890885462764afb15b68eb5f69979c8046ecb08cad7c4ae6b221ab", 8, 0x01),
|
||||
Nip49TestCase("777z7z7z7z7z7z7z", "11b25a101667dd9208db93c0827c6bdad66729a5b521156a7e9d3b22b3ae8944", 9, 0x02),
|
||||
Nip49TestCase("", "f7f2f77f98890885462764afb15b68eb5f69979c8046ecb08cad7c4ae6b221ab", 4, 0x00),
|
||||
Nip49TestCase("", "11b25a101667dd9208db93c0827c6bdad66729a5b521156a7e9d3b22b3ae8944", 5, 0x01),
|
||||
Nip49TestCase("", "f7f2f77f98890885462764afb15b68eb5f69979c8046ecb08cad7c4ae6b221ab", 1, 0x00),
|
||||
Nip49TestCase("", "11b25a101667dd9208db93c0827c6bdad66729a5b521156a7e9d3b22b3ae8944", 9, 0x01),
|
||||
)
|
||||
}
|
||||
|
||||
val nip49 = Nip49()
|
||||
|
||||
@Test
|
||||
fun decodeBech32() {
|
||||
val data =
|
||||
Nip49.EncryptedInfo.decodePayload(
|
||||
TEST_CASE,
|
||||
)!!
|
||||
|
||||
assertEquals(2.toByte(), data.version)
|
||||
assertEquals(16.toByte(), data.logn)
|
||||
assertEquals("52d7c3f8580e7b41953381e5bc49646b", data.salt.toHexKey())
|
||||
assertEquals("c33f02a7dcaac8bdd8da23cd449783240b6ebc12edeea7bf", data.nonce.toHexKey())
|
||||
assertEquals(0.toByte(), data.keySecurity)
|
||||
assertEquals("b8e8803440de7b3e9519c3e734cb2ac9a211ea2dc52312e5117a11a3022d813ab438719ca0b504a1193be510c3aee776", data.encryptedKey.toHexKey())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun decrypt() {
|
||||
val decrypted = nip49.decrypt(TEST_CASE, TEST_CASE_PASSWORD)
|
||||
assertEquals(TEST_CASE_EXPECTED, decrypted)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun encryptDecryptTestCase() {
|
||||
val encrypted = nip49.encrypt(TEST_CASE_EXPECTED, TEST_CASE_PASSWORD, 16, 0)
|
||||
val decrypted = nip49.decrypt(encrypted!!, TEST_CASE_PASSWORD)
|
||||
|
||||
assertEquals(TEST_CASE_EXPECTED, decrypted)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun encryptDecrypt() {
|
||||
MAIN_TEST_CASES.forEach {
|
||||
val encrypted = nip49.encrypt(it.secretKey, it.password, it.logn, it.ksb)
|
||||
|
||||
assertNotNull(encrypted)
|
||||
|
||||
val decrypted = nip49.decrypt(encrypted!!, it.password)
|
||||
|
||||
assertEquals(it.secretKey, decrypted)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun normalization() {
|
||||
val samePassword1 = byteArrayOf(0xE2.toByte(), 0x84.toByte(), 0xAB.toByte(), 0xE2.toByte(), 0x84.toByte(), 0xA6.toByte(), 0xE1.toByte(), 0xBA.toByte(), 0x9B.toByte(), 0xCC.toByte(), 0xA3.toByte()).decodeToString()
|
||||
val samePassword2 = byteArrayOf(0xC3.toByte(), 0x85.toByte(), 0xCE.toByte(), 0xA9.toByte(), 0xE1.toByte(), 0xB9.toByte(), 0xA9.toByte()).decodeToString()
|
||||
|
||||
if (samePassword1.encodeToByteArray().contentEquals(samePassword2.encodeToByteArray())) {
|
||||
fail("Passwords should have a different byte representation")
|
||||
}
|
||||
|
||||
val encrypted = nip49.encrypt(TEST_CASE_EXPECTED, samePassword1, 8, 0)
|
||||
|
||||
assertNotNull(encrypted)
|
||||
|
||||
val decrypted = nip49.decrypt(encrypted!!, samePassword2)
|
||||
|
||||
assertEquals(TEST_CASE_EXPECTED, decrypted)
|
||||
}
|
||||
|
||||
class Nip49TestCase(
|
||||
val password: String,
|
||||
val secretKey: String,
|
||||
val logn: Int,
|
||||
val ksb: Byte,
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,664 @@
|
||||
{
|
||||
"v2": {
|
||||
"valid": {
|
||||
"get_conversation_key": [
|
||||
{
|
||||
"sec1": "315e59ff51cb9209768cf7da80791ddcaae56ac9775eb25b6dee1234bc5d2268",
|
||||
"pub2": "c2f9d9948dc8c7c38321e4b85c8558872eafa0641cd269db76848a6073e69133",
|
||||
"conversation_key": "3dfef0ce2a4d80a25e7a328accf73448ef67096f65f79588e358d9a0eb9013f1"
|
||||
},
|
||||
{
|
||||
"sec1": "a1e37752c9fdc1273be53f68c5f74be7c8905728e8de75800b94262f9497c86e",
|
||||
"pub2": "03bb7947065dde12ba991ea045132581d0954f042c84e06d8c00066e23c1a800",
|
||||
"conversation_key": "4d14f36e81b8452128da64fe6f1eae873baae2f444b02c950b90e43553f2178b"
|
||||
},
|
||||
{
|
||||
"sec1": "98a5902fd67518a0c900f0fb62158f278f94a21d6f9d33d30cd3091195500311",
|
||||
"pub2": "aae65c15f98e5e677b5050de82e3aba47a6fe49b3dab7863cf35d9478ba9f7d1",
|
||||
"conversation_key": "9c00b769d5f54d02bf175b7284a1cbd28b6911b06cda6666b2243561ac96bad7"
|
||||
},
|
||||
{
|
||||
"sec1": "86ae5ac8034eb2542ce23ec2f84375655dab7f836836bbd3c54cefe9fdc9c19f",
|
||||
"pub2": "59f90272378089d73f1339710c02e2be6db584e9cdbe86eed3578f0c67c23585",
|
||||
"conversation_key": "19f934aafd3324e8415299b64df42049afaa051c71c98d0aa10e1081f2e3e2ba"
|
||||
},
|
||||
{
|
||||
"sec1": "2528c287fe822421bc0dc4c3615878eb98e8a8c31657616d08b29c00ce209e34",
|
||||
"pub2": "f66ea16104c01a1c532e03f166c5370a22a5505753005a566366097150c6df60",
|
||||
"conversation_key": "c833bbb292956c43366145326d53b955ffb5da4e4998a2d853611841903f5442"
|
||||
},
|
||||
{
|
||||
"sec1": "49808637b2d21129478041813aceb6f2c9d4929cd1303cdaf4fbdbd690905ff2",
|
||||
"pub2": "74d2aab13e97827ea21baf253ad7e39b974bb2498cc747cdb168582a11847b65",
|
||||
"conversation_key": "4bf304d3c8c4608864c0fe03890b90279328cd24a018ffa9eb8f8ccec06b505d"
|
||||
},
|
||||
{
|
||||
"sec1": "af67c382106242c5baabf856efdc0629cc1c5b4061f85b8ceaba52aa7e4b4082",
|
||||
"pub2": "bdaf0001d63e7ec994fad736eab178ee3c2d7cfc925ae29f37d19224486db57b",
|
||||
"conversation_key": "a3a575dd66d45e9379904047ebfb9a7873c471687d0535db00ef2daa24b391db"
|
||||
},
|
||||
{
|
||||
"sec1": "0e44e2d1db3c1717b05ffa0f08d102a09c554a1cbbf678ab158b259a44e682f1",
|
||||
"pub2": "1ffa76c5cc7a836af6914b840483726207cb750889753d7499fb8b76aa8fe0de",
|
||||
"conversation_key": "a39970a667b7f861f100e3827f4adbf6f464e2697686fe1a81aeda817d6b8bdf"
|
||||
},
|
||||
{
|
||||
"sec1": "5fc0070dbd0666dbddc21d788db04050b86ed8b456b080794c2a0c8e33287bb6",
|
||||
"pub2": "31990752f296dd22e146c9e6f152a269d84b241cc95bb3ff8ec341628a54caf0",
|
||||
"conversation_key": "72c21075f4b2349ce01a3e604e02a9ab9f07e35dd07eff746de348b4f3c6365e"
|
||||
},
|
||||
{
|
||||
"sec1": "1b7de0d64d9b12ddbb52ef217a3a7c47c4362ce7ea837d760dad58ab313cba64",
|
||||
"pub2": "24383541dd8083b93d144b431679d70ef4eec10c98fceef1eff08b1d81d4b065",
|
||||
"conversation_key": "dd152a76b44e63d1afd4dfff0785fa07b3e494a9e8401aba31ff925caeb8f5b1"
|
||||
},
|
||||
{
|
||||
"sec1": "df2f560e213ca5fb33b9ecde771c7c0cbd30f1cf43c2c24de54480069d9ab0af",
|
||||
"pub2": "eeea26e552fc8b5e377acaa03e47daa2d7b0c787fac1e0774c9504d9094c430e",
|
||||
"conversation_key": "770519e803b80f411c34aef59c3ca018608842ebf53909c48d35250bd9323af6"
|
||||
},
|
||||
{
|
||||
"sec1": "cffff919fcc07b8003fdc63bc8a00c0f5dc81022c1c927c62c597352190d95b9",
|
||||
"pub2": "eb5c3cca1a968e26684e5b0eb733aecfc844f95a09ac4e126a9e58a4e4902f92",
|
||||
"conversation_key": "46a14ee7e80e439ec75c66f04ad824b53a632b8409a29bbb7c192e43c00bb795"
|
||||
},
|
||||
{
|
||||
"sec1": "64ba5a685e443e881e9094647ddd32db14444bb21aa7986beeba3d1c4673ba0a",
|
||||
"pub2": "50e6a4339fac1f3bf86f2401dd797af43ad45bbf58e0801a7877a3984c77c3c4",
|
||||
"conversation_key": "968b9dbbfcede1664a4ca35a5d3379c064736e87aafbf0b5d114dff710b8a946"
|
||||
},
|
||||
{
|
||||
"sec1": "dd0c31ccce4ec8083f9b75dbf23cc2878e6d1b6baa17713841a2428f69dee91a",
|
||||
"pub2": "b483e84c1339812bed25be55cff959778dfc6edde97ccd9e3649f442472c091b",
|
||||
"conversation_key": "09024503c7bde07eb7865505891c1ea672bf2d9e25e18dd7a7cea6c69bf44b5d"
|
||||
},
|
||||
{
|
||||
"sec1": "af71313b0d95c41e968a172b33ba5ebd19d06cdf8a7a98df80ecf7af4f6f0358",
|
||||
"pub2": "2a5c25266695b461ee2af927a6c44a3c598b8095b0557e9bd7f787067435bc7c",
|
||||
"conversation_key": "fe5155b27c1c4b4e92a933edae23726a04802a7cc354a77ac273c85aa3c97a92"
|
||||
},
|
||||
{
|
||||
"sec1": "6636e8a389f75fe068a03b3edb3ea4a785e2768e3f73f48ffb1fc5e7cb7289dc",
|
||||
"pub2": "514eb2064224b6a5829ea21b6e8f7d3ea15ff8e70e8555010f649eb6e09aec70",
|
||||
"conversation_key": "ff7afacd4d1a6856d37ca5b546890e46e922b508639214991cf8048ddbe9745c"
|
||||
},
|
||||
{
|
||||
"sec1": "94b212f02a3cfb8ad147d52941d3f1dbe1753804458e6645af92c7b2ea791caa",
|
||||
"pub2": "f0cac333231367a04b652a77ab4f8d658b94e86b5a8a0c472c5c7b0d4c6a40cc",
|
||||
"conversation_key": "e292eaf873addfed0a457c6bd16c8effde33d6664265697f69f420ab16f6669b"
|
||||
},
|
||||
{
|
||||
"sec1": "aa61f9734e69ae88e5d4ced5aae881c96f0d7f16cca603d3bed9eec391136da6",
|
||||
"pub2": "4303e5360a884c360221de8606b72dd316da49a37fe51e17ada4f35f671620a6",
|
||||
"conversation_key": "8e7d44fd4767456df1fb61f134092a52fcd6836ebab3b00766e16732683ed848"
|
||||
},
|
||||
{
|
||||
"sec1": "5e914bdac54f3f8e2cba94ee898b33240019297b69e96e70c8a495943a72fc98",
|
||||
"pub2": "5bd097924f606695c59f18ff8fd53c174adbafaaa71b3c0b4144a3e0a474b198",
|
||||
"conversation_key": "f5a0aecf2984bf923c8cd5e7bb8be262d1a8353cb93959434b943a07cf5644bc"
|
||||
},
|
||||
{
|
||||
"sec1": "8b275067add6312ddee064bcdbeb9d17e88aa1df36f430b2cea5cc0413d8278a",
|
||||
"pub2": "65bbbfca819c90c7579f7a82b750a18c858db1afbec8f35b3c1e0e7b5588e9b8",
|
||||
"conversation_key": "2c565e7027eb46038c2263563d7af681697107e975e9914b799d425effd248d6"
|
||||
},
|
||||
{
|
||||
"sec1": "1ac848de312285f85e0f7ec208aac20142a1f453402af9b34ec2ec7a1f9c96fc",
|
||||
"pub2": "45f7318fe96034d23ee3ddc25b77f275cc1dd329664dd51b89f89c4963868e41",
|
||||
"conversation_key": "b56e970e5057a8fd929f8aad9248176b9af87819a708d9ddd56e41d1aec74088"
|
||||
},
|
||||
{
|
||||
"sec1": "295a1cf621de401783d29d0e89036aa1c62d13d9ad307161b4ceb535ba1b40e6",
|
||||
"pub2": "840115ddc7f1034d3b21d8e2103f6cb5ab0b63cf613f4ea6e61ae3d016715cdd",
|
||||
"conversation_key": "b4ee9c0b9b9fef88975773394f0a6f981ca016076143a1bb575b9ff46e804753"
|
||||
},
|
||||
{
|
||||
"sec1": "a28eed0fe977893856ab9667e06ace39f03abbcdb845c329a1981be438ba565d",
|
||||
"pub2": "b0f38b950a5013eba5ab4237f9ed29204a59f3625c71b7e210fec565edfa288c",
|
||||
"conversation_key": "9d3a802b45bc5aeeb3b303e8e18a92ddd353375710a31600d7f5fff8f3a7285b"
|
||||
},
|
||||
{
|
||||
"sec1": "7ab65af72a478c05f5c651bdc4876c74b63d20d04cdbf71741e46978797cd5a4",
|
||||
"pub2": "f1112159161b568a9cb8c9dd6430b526c4204bcc8ce07464b0845b04c041beda",
|
||||
"conversation_key": "943884cddaca5a3fef355e9e7f08a3019b0b66aa63ec90278b0f9fdb64821e79"
|
||||
},
|
||||
{
|
||||
"sec1": "95c79a7b75ba40f2229e85756884c138916f9d103fc8f18acc0877a7cceac9fe",
|
||||
"pub2": "cad76bcbd31ca7bbda184d20cc42f725ed0bb105b13580c41330e03023f0ffb3",
|
||||
"conversation_key": "81c0832a669eea13b4247c40be51ccfd15bb63fcd1bba5b4530ce0e2632f301b"
|
||||
},
|
||||
{
|
||||
"sec1": "baf55cc2febd4d980b4b393972dfc1acf49541e336b56d33d429bce44fa12ec9",
|
||||
"pub2": "0c31cf87fe565766089b64b39460ebbfdedd4a2bc8379be73ad3c0718c912e18",
|
||||
"conversation_key": "37e2344da9ecdf60ae2205d81e89d34b280b0a3f111171af7e4391ded93b8ea6"
|
||||
},
|
||||
{
|
||||
"sec1": "6eeec45acd2ed31693c5256026abf9f072f01c4abb61f51cf64e6956b6dc8907",
|
||||
"pub2": "e501b34ed11f13d816748c0369b0c728e540df3755bab59ed3327339e16ff828",
|
||||
"conversation_key": "afaa141b522ddb27bb880d768903a7f618bb8b6357728cae7fb03af639b946e6"
|
||||
},
|
||||
{
|
||||
"sec1": "261a076a9702af1647fb343c55b3f9a4f1096273002287df0015ba81ce5294df",
|
||||
"pub2": "b2777c863878893ae100fb740c8fab4bebd2bf7be78c761a75593670380a6112",
|
||||
"conversation_key": "76f8d2853de0734e51189ced523c09427c3e46338b9522cd6f74ef5e5b475c74"
|
||||
},
|
||||
{
|
||||
"sec1": "ed3ec71ca406552ea41faec53e19f44b8f90575eda4b7e96380f9cc73c26d6f3",
|
||||
"pub2": "86425951e61f94b62e20cae24184b42e8e17afcf55bafa58645efd0172624fae",
|
||||
"conversation_key": "f7ffc520a3a0e9e9b3c0967325c9bf12707f8e7a03f28b6cd69ae92cf33f7036"
|
||||
},
|
||||
{
|
||||
"sec1": "5a788fc43378d1303ac78639c59a58cb88b08b3859df33193e63a5a3801c722e",
|
||||
"pub2": "a8cba2f87657d229db69bee07850fd6f7a2ed070171a06d006ec3a8ac562cf70",
|
||||
"conversation_key": "7d705a27feeedf78b5c07283362f8e361760d3e9f78adab83e3ae5ce7aeb6409"
|
||||
},
|
||||
{
|
||||
"sec1": "63bffa986e382b0ac8ccc1aa93d18a7aa445116478be6f2453bad1f2d3af2344",
|
||||
"pub2": "b895c70a83e782c1cf84af558d1038e6b211c6f84ede60408f519a293201031d",
|
||||
"conversation_key": "3a3b8f00d4987fc6711d9be64d9c59cf9a709c6c6481c2cde404bcc7a28f174e"
|
||||
},
|
||||
{
|
||||
"sec1": "e4a8bcacbf445fd3721792b939ff58e691cdcba6a8ba67ac3467b45567a03e5c",
|
||||
"pub2": "b54053189e8c9252c6950059c783edb10675d06d20c7b342f73ec9fa6ed39c9d",
|
||||
"conversation_key": "7b3933b4ef8189d347169c7955589fc1cfc01da5239591a08a183ff6694c44ad"
|
||||
},
|
||||
{
|
||||
"sec1": "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364139",
|
||||
"pub2": "0000000000000000000000000000000000000000000000000000000000000002",
|
||||
"conversation_key": "8b6392dbf2ec6a2b2d5b1477fc2be84d63ef254b667cadd31bd3f444c44ae6ba",
|
||||
"note": "sec1 = n-2, pub2: random, 0x02"
|
||||
},
|
||||
{
|
||||
"sec1": "0000000000000000000000000000000000000000000000000000000000000002",
|
||||
"pub2": "1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdeb",
|
||||
"conversation_key": "be234f46f60a250bef52a5ee34c758800c4ca8e5030bf4cc1a31d37ba2104d43",
|
||||
"note": "sec1 = 2, pub2: rand"
|
||||
},
|
||||
{
|
||||
"sec1": "0000000000000000000000000000000000000000000000000000000000000001",
|
||||
"pub2": "79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798",
|
||||
"conversation_key": "3b4610cb7189beb9cc29eb3716ecc6102f1247e8f3101a03a1787d8908aeb54e",
|
||||
"note": "sec1 == pub2"
|
||||
}
|
||||
],
|
||||
"get_message_keys": {
|
||||
"conversation_key": "a1a3d60f3470a8612633924e91febf96dc5366ce130f658b1f0fc652c20b3b54",
|
||||
"keys": [
|
||||
{
|
||||
"nonce": "e1e6f880560d6d149ed83dcc7e5861ee62a5ee051f7fde9975fe5d25d2a02d72",
|
||||
"chacha_key": "f145f3bed47cb70dbeaac07f3a3fe683e822b3715edb7c4fe310829014ce7d76",
|
||||
"chacha_nonce": "c4ad129bb01180c0933a160c",
|
||||
"hmac_key": "027c1db445f05e2eee864a0975b0ddef5b7110583c8c192de3732571ca5838c4"
|
||||
},
|
||||
{
|
||||
"nonce": "e1d6d28c46de60168b43d79dacc519698512ec35e8ccb12640fc8e9f26121101",
|
||||
"chacha_key": "e35b88f8d4a8f1606c5082f7a64b100e5d85fcdb2e62aeafbec03fb9e860ad92",
|
||||
"chacha_nonce": "22925e920cee4a50a478be90",
|
||||
"hmac_key": "46a7c55d4283cb0df1d5e29540be67abfe709e3b2e14b7bf9976e6df994ded30"
|
||||
},
|
||||
{
|
||||
"nonce": "cfc13bef512ac9c15951ab00030dfaf2626fdca638dedb35f2993a9eeb85d650",
|
||||
"chacha_key": "020783eb35fdf5b80ef8c75377f4e937efb26bcbad0e61b4190e39939860c4bf",
|
||||
"chacha_nonce": "d3594987af769a52904656ac",
|
||||
"hmac_key": "237ec0ccb6ebd53d179fa8fd319e092acff599ef174c1fdafd499ef2b8dee745"
|
||||
},
|
||||
{
|
||||
"nonce": "ea6eb84cac23c5c1607c334e8bdf66f7977a7e374052327ec28c6906cbe25967",
|
||||
"chacha_key": "ff68db24b34fa62c78ac5ffeeaf19533afaedf651fb6a08384e46787f6ce94be",
|
||||
"chacha_nonce": "50bb859aa2dde938cc49ec7a",
|
||||
"hmac_key": "06ff32e1f7b29753a727d7927b25c2dd175aca47751462d37a2039023ec6b5a6"
|
||||
},
|
||||
{
|
||||
"nonce": "8c2e1dd3792802f1f9f7842e0323e5d52ad7472daf360f26e15f97290173605d",
|
||||
"chacha_key": "2f9daeda8683fdeede81adac247c63cc7671fa817a1fd47352e95d9487989d8b",
|
||||
"chacha_nonce": "400224ba67fc2f1b76736916",
|
||||
"hmac_key": "465c05302aeeb514e41c13ed6405297e261048cfb75a6f851ffa5b445b746e4b"
|
||||
},
|
||||
{
|
||||
"nonce": "05c28bf3d834fa4af8143bf5201a856fa5fac1a3aee58f4c93a764fc2f722367",
|
||||
"chacha_key": "1e3d45777025a035be566d80fd580def73ed6f7c043faec2c8c1c690ad31c110",
|
||||
"chacha_nonce": "021905b1ea3afc17cb9bf96f",
|
||||
"hmac_key": "74a6e481a89dcd130aaeb21060d7ec97ad30f0007d2cae7b1b11256cc70dfb81"
|
||||
},
|
||||
{
|
||||
"nonce": "5e043fb153227866e75a06d60185851bc90273bfb93342f6632a728e18a07a17",
|
||||
"chacha_key": "1ea72c9293841e7737c71567d8120145a58991aaa1c436ef77bf7adb83f882f1",
|
||||
"chacha_nonce": "72f69a5a5f795465cee59da8",
|
||||
"hmac_key": "e9daa1a1e9a266ecaa14e970a84bce3fbbf329079bbccda626582b4e66a0d4c9"
|
||||
},
|
||||
{
|
||||
"nonce": "7be7338eaf06a87e274244847fe7a97f5c6a91f44adc18fcc3e411ad6f786dbf",
|
||||
"chacha_key": "881e7968a1f0c2c80742ee03cd49ea587e13f22699730f1075ade01931582bf6",
|
||||
"chacha_nonce": "6e69be92d61c04a276021565",
|
||||
"hmac_key": "901afe79e74b19967c8829af23617d7d0ffbf1b57190c096855c6a03523a971b"
|
||||
},
|
||||
{
|
||||
"nonce": "94571c8d590905bad7becd892832b472f2aa5212894b6ce96e5ba719c178d976",
|
||||
"chacha_key": "f80873dd48466cb12d46364a97b8705c01b9b4230cb3ec3415a6b9551dc42eef",
|
||||
"chacha_nonce": "3dda53569cfcb7fac1805c35",
|
||||
"hmac_key": "e9fc264345e2839a181affebc27d2f528756e66a5f87b04bf6c5f1997047051e"
|
||||
},
|
||||
{
|
||||
"nonce": "13a6ee974b1fd759135a2c2010e3cdda47081c78e771125e4f0c382f0284a8cb",
|
||||
"chacha_key": "bc5fb403b0bed0d84cf1db872b6522072aece00363178c98ad52178d805fca85",
|
||||
"chacha_nonce": "65064239186e50304cc0f156",
|
||||
"hmac_key": "e872d320dde4ed3487958a8e43b48aabd3ced92bc24bb8ff1ccb57b590d9701a"
|
||||
},
|
||||
{
|
||||
"nonce": "082fecdb85f358367b049b08be0e82627ae1d8edb0f27327ccb593aa2613b814",
|
||||
"chacha_key": "1fbdb1cf6f6ea816349baf697932b36107803de98fcd805ebe9849b8ad0e6a45",
|
||||
"chacha_nonce": "2e605e1d825a3eaeb613db9c",
|
||||
"hmac_key": "fae910f591cf3c7eb538c598583abad33bc0a03085a96ca4ea3a08baf17c0eec"
|
||||
},
|
||||
{
|
||||
"nonce": "4c19020c74932c30ec6b2d8cd0d5bb80bd0fc87da3d8b4859d2fb003810afd03",
|
||||
"chacha_key": "1ab9905a0189e01cda82f843d226a82a03c4f5b6dbea9b22eb9bc953ba1370d4",
|
||||
"chacha_nonce": "cbb2530ea653766e5a37a83a",
|
||||
"hmac_key": "267f68acac01ac7b34b675e36c2cef5e7b7a6b697214add62a491bedd6efc178"
|
||||
},
|
||||
{
|
||||
"nonce": "67723a3381497b149ce24814eddd10c4c41a1e37e75af161930e6b9601afd0ff",
|
||||
"chacha_key": "9ecbd25e7e2e6c97b8c27d376dcc8c5679da96578557e4e21dba3a7ef4e4ac07",
|
||||
"chacha_nonce": "ef649fcf335583e8d45e3c2e",
|
||||
"hmac_key": "04dbbd812fa8226fdb45924c521a62e3d40a9e2b5806c1501efdeba75b006bf1"
|
||||
},
|
||||
{
|
||||
"nonce": "42063fe80b093e8619b1610972b4c3ab9e76c14fd908e642cd4997cafb30f36c",
|
||||
"chacha_key": "211c66531bbcc0efcdd0130f9f1ebc12a769105eb39608994bcb188fa6a73a4a",
|
||||
"chacha_nonce": "67803605a7e5010d0f63f8c8",
|
||||
"hmac_key": "e840e4e8921b57647369d121c5a19310648105dbdd008200ebf0d3b668704ff8"
|
||||
},
|
||||
{
|
||||
"nonce": "b5ac382a4be7ac03b554fe5f3043577b47ea2cd7cfc7e9ca010b1ffbb5cf1a58",
|
||||
"chacha_key": "b3b5f14f10074244ee42a3837a54309f33981c7232a8b16921e815e1f7d1bb77",
|
||||
"chacha_nonce": "4e62a0073087ed808be62469",
|
||||
"hmac_key": "c8efa10230b5ea11633816c1230ca05fa602ace80a7598916d83bae3d3d2ccd7"
|
||||
},
|
||||
{
|
||||
"nonce": "e9d1eba47dd7e6c1532dc782ff63125db83042bb32841db7eeafd528f3ea7af9",
|
||||
"chacha_key": "54241f68dc2e50e1db79e892c7c7a471856beeb8d51b7f4d16f16ab0645d2f1a",
|
||||
"chacha_nonce": "a963ed7dc29b7b1046820a1d",
|
||||
"hmac_key": "aba215c8634530dc21c70ddb3b3ee4291e0fa5fa79be0f85863747bde281c8b2"
|
||||
},
|
||||
{
|
||||
"nonce": "a94ecf8efeee9d7068de730fad8daf96694acb70901d762de39fa8a5039c3c49",
|
||||
"chacha_key": "c0565e9e201d2381a2368d7ffe60f555223874610d3d91fbbdf3076f7b1374dd",
|
||||
"chacha_nonce": "329bb3024461e84b2e1c489b",
|
||||
"hmac_key": "ac42445491f092481ce4fa33b1f2274700032db64e3a15014fbe8c28550f2fec"
|
||||
},
|
||||
{
|
||||
"nonce": "533605ea214e70c25e9a22f792f4b78b9f83a18ab2103687c8a0075919eaaa53",
|
||||
"chacha_key": "ab35a5e1e54d693ff023db8500d8d4e79ad8878c744e0eaec691e96e141d2325",
|
||||
"chacha_nonce": "653d759042b85194d4d8c0a7",
|
||||
"hmac_key": "b43628e37ba3c31ce80576f0a1f26d3a7c9361d29bb227433b66f49d44f167ba"
|
||||
},
|
||||
{
|
||||
"nonce": "7f38df30ceea1577cb60b355b4f5567ff4130c49e84fed34d779b764a9cc184c",
|
||||
"chacha_key": "a37d7f211b84a551a127ff40908974eb78415395d4f6f40324428e850e8c42a3",
|
||||
"chacha_nonce": "b822e2c959df32b3cb772a7c",
|
||||
"hmac_key": "1ba31764f01f69b5c89ded2d7c95828e8052c55f5d36f1cd535510d61ba77420"
|
||||
},
|
||||
{
|
||||
"nonce": "11b37f9dbc4d0185d1c26d5f4ed98637d7c9701fffa65a65839fa4126573a4e5",
|
||||
"chacha_key": "964f38d3a31158a5bfd28481247b18dd6e44d69f30ba2a40f6120c6d21d8a6ba",
|
||||
"chacha_nonce": "5f72c5b87c590bcd0f93b305",
|
||||
"hmac_key": "2fc4553e7cedc47f29690439890f9f19c1077ef3e9eaeef473d0711e04448918"
|
||||
},
|
||||
{
|
||||
"nonce": "8be790aa483d4cdd843189f71f135b3ec7e31f381312c8fe9f177aab2a48eafa",
|
||||
"chacha_key": "95c8c74d633721a131316309cf6daf0804d59eaa90ea998fc35bac3d2fbb7a94",
|
||||
"chacha_nonce": "409a7654c0e4bf8c2c6489be",
|
||||
"hmac_key": "21bb0b06eb2b460f8ab075f497efa9a01c9cf9146f1e3986c3bf9da5689b6dc4"
|
||||
},
|
||||
{
|
||||
"nonce": "19fd2a718ea084827d6bd73f509229ddf856732108b59fc01819f611419fd140",
|
||||
"chacha_key": "cc6714b9f5616c66143424e1413d520dae03b1a4bd202b82b0a89b0727f5cdc8",
|
||||
"chacha_nonce": "1b7fd2534f015a8f795d8f32",
|
||||
"hmac_key": "2bef39c4ce5c3c59b817e86351373d1554c98bc131c7e461ed19d96cfd6399a0"
|
||||
},
|
||||
{
|
||||
"nonce": "3c2acd893952b2f6d07d8aea76f545ca45961a93fe5757f6a5a80811d5e0255d",
|
||||
"chacha_key": "c8de6c878cb469278d0af894bc181deb6194053f73da5014c2b5d2c8db6f2056",
|
||||
"chacha_nonce": "6ffe4f1971b904a1b1a81b99",
|
||||
"hmac_key": "df1cd69dd3646fca15594284744d4211d70e7d8472e545d276421fbb79559fd4"
|
||||
},
|
||||
{
|
||||
"nonce": "7dbea4cead9ac91d4137f1c0a6eebb6ba0d1fb2cc46d829fbc75f8d86aca6301",
|
||||
"chacha_key": "c8e030f6aa680c3d0b597da9c92bb77c21c4285dd620c5889f9beba7446446b0",
|
||||
"chacha_nonce": "a9b5a67d081d3b42e737d16f",
|
||||
"hmac_key": "355a85f551bc3cce9a14461aa60994742c9bbb1c81a59ca102dc64e61726ab8e"
|
||||
},
|
||||
{
|
||||
"nonce": "45422e676cdae5f1071d3647d7a5f1f5adafb832668a578228aa1155a491f2f3",
|
||||
"chacha_key": "758437245f03a88e2c6a32807edfabff51a91c81ca2f389b0b46f2c97119ea90",
|
||||
"chacha_nonce": "263830a065af33d9c6c5aa1f",
|
||||
"hmac_key": "7c581cf3489e2de203a95106bfc0de3d4032e9d5b92b2b61fb444acd99037e17"
|
||||
},
|
||||
{
|
||||
"nonce": "babc0c03fad24107ad60678751f5db2678041ff0d28671ede8d65bdf7aa407e9",
|
||||
"chacha_key": "bd68a28bd48d9ffa3602db72c75662ac2848a0047a313d2ae2d6bc1ac153d7e9",
|
||||
"chacha_nonce": "d0f9d2a1ace6c758f594ffdd",
|
||||
"hmac_key": "eb435e3a642adfc9d59813051606fc21f81641afd58ea6641e2f5a9f123bb50a"
|
||||
},
|
||||
{
|
||||
"nonce": "7a1b8aac37d0d20b160291fad124ab697cfca53f82e326d78fef89b4b0ea8f83",
|
||||
"chacha_key": "9e97875b651a1d30d17d086d1e846778b7faad6fcbc12e08b3365d700f62e4fe",
|
||||
"chacha_nonce": "ccdaad5b3b7645be430992eb",
|
||||
"hmac_key": "6f2f55cf35174d75752f63c06cc7cbc8441759b142999ed2d5a6d09d263e1fc4"
|
||||
},
|
||||
{
|
||||
"nonce": "8370e4e32d7e680a83862cab0da6136ef607014d043e64cdf5ecc0c4e20b3d9a",
|
||||
"chacha_key": "1472bed5d19db9c546106de946e0649cd83cc9d4a66b087a65906e348dcf92e2",
|
||||
"chacha_nonce": "ed02dece5fc3a186f123420b",
|
||||
"hmac_key": "7b3f7739f49d30c6205a46b174f984bb6a9fc38e5ccfacef2dac04fcbd3b184e"
|
||||
},
|
||||
{
|
||||
"nonce": "9f1c5e8a29cd5677513c2e3a816551d6833ee54991eb3f00d5b68096fc8f0183",
|
||||
"chacha_key": "5e1a7544e4d4dafe55941fcbdf326f19b0ca37fc49c4d47e9eec7fb68cde4975",
|
||||
"chacha_nonce": "7d9acb0fdc174e3c220f40de",
|
||||
"hmac_key": "e265ab116fbbb86b2aefc089a0986a0f5b77eda50c7410404ad3b4f3f385c7a7"
|
||||
},
|
||||
{
|
||||
"nonce": "c385aa1c37c2bfd5cc35fcdbdf601034d39195e1cabff664ceb2b787c15d0225",
|
||||
"chacha_key": "06bf4e60677a13e54c4a38ab824d2ef79da22b690da2b82d0aa3e39a14ca7bdd",
|
||||
"chacha_nonce": "26b450612ca5e905b937e147",
|
||||
"hmac_key": "22208152be2b1f5f75e6bfcc1f87763d48bb7a74da1be3d102096f257207f8b3"
|
||||
},
|
||||
{
|
||||
"nonce": "3ff73528f88a50f9d35c0ddba4560bacee5b0462d0f4cb6e91caf41847040ce4",
|
||||
"chacha_key": "850c8a17a23aa761d279d9901015b2bbdfdff00adbf6bc5cf22bd44d24ecabc9",
|
||||
"chacha_nonce": "4a296a1fb0048e5020d3b129",
|
||||
"hmac_key": "b1bf49a533c4da9b1d629b7ff30882e12d37d49c19abd7b01b7807d75ee13806"
|
||||
},
|
||||
{
|
||||
"nonce": "2dcf39b9d4c52f1cb9db2d516c43a7c6c3b8c401f6a4ac8f131a9e1059957036",
|
||||
"chacha_key": "17f8057e6156ba7cc5310d01eda8c40f9aa388f9fd1712deb9511f13ecc37d27",
|
||||
"chacha_nonce": "a8188daff807a1182200b39d",
|
||||
"hmac_key": "47b89da97f68d389867b5d8a2d7ba55715a30e3d88a3cc11f3646bc2af5580ef"
|
||||
}
|
||||
]
|
||||
},
|
||||
"calc_padded_len": [
|
||||
[16, 32],
|
||||
[32, 32],
|
||||
[33, 64],
|
||||
[37, 64],
|
||||
[45, 64],
|
||||
[49, 64],
|
||||
[64, 64],
|
||||
[65, 96],
|
||||
[100, 128],
|
||||
[111, 128],
|
||||
[200, 224],
|
||||
[250, 256],
|
||||
[320, 320],
|
||||
[383, 384],
|
||||
[384, 384],
|
||||
[400, 448],
|
||||
[500, 512],
|
||||
[512, 512],
|
||||
[515, 640],
|
||||
[700, 768],
|
||||
[800, 896],
|
||||
[900, 1024],
|
||||
[1020, 1024],
|
||||
[65536, 65536]
|
||||
],
|
||||
"encrypt_decrypt": [
|
||||
{
|
||||
"sec1": "0000000000000000000000000000000000000000000000000000000000000001",
|
||||
"sec2": "0000000000000000000000000000000000000000000000000000000000000002",
|
||||
"conversation_key": "c41c775356fd92eadc63ff5a0dc1da211b268cbea22316767095b2871ea1412d",
|
||||
"nonce": "0000000000000000000000000000000000000000000000000000000000000001",
|
||||
"plaintext": "a",
|
||||
"payload": "AgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABee0G5VSK0/9YypIObAtDKfYEAjD35uVkHyB0F4DwrcNaCXlCWZKaArsGrY6M9wnuTMxWfp1RTN9Xga8no+kF5Vsb"
|
||||
},
|
||||
{
|
||||
"sec1": "0000000000000000000000000000000000000000000000000000000000000002",
|
||||
"sec2": "0000000000000000000000000000000000000000000000000000000000000001",
|
||||
"conversation_key": "c41c775356fd92eadc63ff5a0dc1da211b268cbea22316767095b2871ea1412d",
|
||||
"nonce": "f00000000000000000000000000000f00000000000000000000000000000000f",
|
||||
"plaintext": "🍕🫃",
|
||||
"payload": "AvAAAAAAAAAAAAAAAAAAAPAAAAAAAAAAAAAAAAAAAAAPSKSK6is9ngkX2+cSq85Th16oRTISAOfhStnixqZziKMDvB0QQzgFZdjLTPicCJaV8nDITO+QfaQ61+KbWQIOO2Yj"
|
||||
},
|
||||
{
|
||||
"sec1": "5c0c523f52a5b6fad39ed2403092df8cebc36318b39383bca6c00808626fab3a",
|
||||
"sec2": "4b22aa260e4acb7021e32f38a6cdf4b673c6a277755bfce287e370c924dc936d",
|
||||
"conversation_key": "3e2b52a63be47d34fe0a80e34e73d436d6963bc8f39827f327057a9986c20a45",
|
||||
"nonce": "b635236c42db20f021bb8d1cdff5ca75dd1a0cc72ea742ad750f33010b24f73b",
|
||||
"plaintext": "表ポあA鷗ŒéB逍Üߪąñ丂㐀𠀀",
|
||||
"payload": "ArY1I2xC2yDwIbuNHN/1ynXdGgzHLqdCrXUPMwELJPc7s7JqlCMJBAIIjfkpHReBPXeoMCyuClwgbT419jUWU1PwaNl4FEQYKCDKVJz+97Mp3K+Q2YGa77B6gpxB/lr1QgoqpDf7wDVrDmOqGoiPjWDqy8KzLueKDcm9BVP8xeTJIxs="
|
||||
},
|
||||
{
|
||||
"sec1": "8f40e50a84a7462e2b8d24c28898ef1f23359fff50d8c509e6fb7ce06e142f9c",
|
||||
"sec2": "b9b0a1e9cc20100c5faa3bbe2777303d25950616c4c6a3fa2e3e046f936ec2ba",
|
||||
"conversation_key": "d5a2f879123145a4b291d767428870f5a8d9e5007193321795b40183d4ab8c2b",
|
||||
"nonce": "b20989adc3ddc41cd2c435952c0d59a91315d8c5218d5040573fc3749543acaf",
|
||||
"plaintext": "ability🤝的 ȺȾ",
|
||||
"payload": "ArIJia3D3cQc0sQ1lSwNWakTFdjFIY1QQFc/w3SVQ6yvbG2S0x4Yu86QGwPTy7mP3961I1XqB6SFFTzqDZZavhxoWMj7mEVGMQIsh2RLWI5EYQaQDIePSnXPlzf7CIt+voTD"
|
||||
},
|
||||
{
|
||||
"sec1": "875adb475056aec0b4809bd2db9aa00cff53a649e7b59d8edcbf4e6330b0995c",
|
||||
"sec2": "9c05781112d5b0a2a7148a222e50e0bd891d6b60c5483f03456e982185944aae",
|
||||
"conversation_key": "3b15c977e20bfe4b8482991274635edd94f366595b1a3d2993515705ca3cedb8",
|
||||
"nonce": "8d4442713eb9d4791175cb040d98d6fc5be8864d6ec2f89cf0895a2b2b72d1b1",
|
||||
"plaintext": "pepper👀їжак",
|
||||
"payload": "Ao1EQnE+udR5EXXLBA2Y1vxb6IZNbsL4nPCJWisrctGxY3AduCS+jTUgAAnfvKafkmpy15+i9YMwCdccisRa8SvzW671T2JO4LFSPX31K4kYUKelSAdSPwe9NwO6LhOsnoJ+"
|
||||
},
|
||||
{
|
||||
"sec1": "eba1687cab6a3101bfc68fd70f214aa4cc059e9ec1b79fdb9ad0a0a4e259829f",
|
||||
"sec2": "dff20d262bef9dfd94666548f556393085e6ea421c8af86e9d333fa8747e94b3",
|
||||
"conversation_key": "4f1538411098cf11c8af216836444787c462d47f97287f46cf7edb2c4915b8a5",
|
||||
"nonce": "2180b52ae645fcf9f5080d81b1f0b5d6f2cd77ff3c986882bb549158462f3407",
|
||||
"plaintext": "( ͡° ͜ʖ ͡°)",
|
||||
"payload": "AiGAtSrmRfz59QgNgbHwtdbyzXf/PJhogrtUkVhGLzQHv4qhKQwnFQ54OjVMgqCea/Vj0YqBSdhqNR777TJ4zIUk7R0fnizp6l1zwgzWv7+ee6u+0/89KIjY5q1wu6inyuiv"
|
||||
},
|
||||
{
|
||||
"sec1": "d5633530f5bcfebceb5584cfbbf718a30df0751b729dd9a789b9f30c0587d74e",
|
||||
"sec2": "b74e6a341fb134127272b795a08b59250e5fa45a82a2eb4095e4ce9ed5f5e214",
|
||||
"conversation_key": "75fe686d21a035f0c7cd70da64ba307936e5ca0b20710496a6b6b5f573377bdd",
|
||||
"nonce": "e4cd5f7ce4eea024bc71b17ad456a986a74ac426c2c62b0a15eb5c5c8f888b68",
|
||||
"plaintext": "مُنَاقَشَةُ سُبُلِ اِسْتِخْدَامِ اللُّغَةِ فِي النُّظُمِ الْقَائِمَةِ وَفِيم يَخُصَّ التَّطْبِيقَاتُ الْحاسُوبِيَّةُ،",
|
||||
"payload": "AuTNX3zk7qAkvHGxetRWqYanSsQmwsYrChXrXFyPiItoIBsWu1CB+sStla2M4VeANASHxM78i1CfHQQH1YbBy24Tng7emYW44ol6QkFD6D8Zq7QPl+8L1c47lx8RoODEQMvNCbOk5ffUV3/AhONHBXnffrI+0025c+uRGzfqpYki4lBqm9iYU+k3Tvjczq9wU0mkVDEaM34WiQi30MfkJdRbeeYaq6kNvGPunLb3xdjjs5DL720d61Flc5ZfoZm+CBhADy9D9XiVZYLKAlkijALJur9dATYKci6OBOoc2SJS2Clai5hOVzR0yVeyHRgRfH9aLSlWW5dXcUxTo7qqRjNf8W5+J4jF4gNQp5f5d0YA4vPAzjBwSP/5bGzNDslKfcAH"
|
||||
},
|
||||
{
|
||||
"sec1": "d5633530f5bcfebceb5584cfbbf718a30df0751b729dd9a789b9f30c0587d74e",
|
||||
"sec2": "b74e6a341fb134127272b795a08b59250e5fa45a82a2eb4095e4ce9ed5f5e214",
|
||||
"conversation_key": "75fe686d21a035f0c7cd70da64ba307936e5ca0b20710496a6b6b5f573377bdd",
|
||||
"nonce": "38d1ca0abef9e5f564e89761a86cee04574b6825d3ef2063b10ad75899e4b023",
|
||||
"plaintext": "الكل في المجمو عة (5)",
|
||||
"payload": "AjjRygq++eX1ZOiXYahs7gRXS2gl0+8gY7EK11iZ5LAjbOTrlfrxak5Lki42v2jMPpLSicy8eHjsWkkMtF0i925vOaKG/ZkMHh9ccQBdfTvgEGKzztedqDCAWb5TP1YwU1PsWaiiqG3+WgVvJiO4lUdMHXL7+zKKx8bgDtowzz4QAwI="
|
||||
},
|
||||
{
|
||||
"sec1": "d5633530f5bcfebceb5584cfbbf718a30df0751b729dd9a789b9f30c0587d74e",
|
||||
"sec2": "b74e6a341fb134127272b795a08b59250e5fa45a82a2eb4095e4ce9ed5f5e214",
|
||||
"conversation_key": "75fe686d21a035f0c7cd70da64ba307936e5ca0b20710496a6b6b5f573377bdd",
|
||||
"nonce": "4f1a31909f3483a9e69c8549a55bbc9af25fa5bbecf7bd32d9896f83ef2e12e0",
|
||||
"plaintext": "𝖑𝖆𝖟𝖞 社會科學院語學研究所",
|
||||
"payload": "Ak8aMZCfNIOp5pyFSaVbvJryX6W77Pe9MtmJb4PvLhLgh/TsxPLFSANcT67EC1t/qxjru5ZoADjKVEt2ejdx+xGvH49mcdfbc+l+L7gJtkH7GLKpE9pQNQWNHMAmj043PAXJZ++fiJObMRR2mye5VHEANzZWkZXMrXF7YjuG10S1pOU="
|
||||
},
|
||||
{
|
||||
"sec1": "d5633530f5bcfebceb5584cfbbf718a30df0751b729dd9a789b9f30c0587d74e",
|
||||
"sec2": "b74e6a341fb134127272b795a08b59250e5fa45a82a2eb4095e4ce9ed5f5e214",
|
||||
"conversation_key": "75fe686d21a035f0c7cd70da64ba307936e5ca0b20710496a6b6b5f573377bdd",
|
||||
"nonce": "a3e219242d85465e70adcd640b564b3feff57d2ef8745d5e7a0663b2dccceb54",
|
||||
"plaintext": "🙈 🙉 🙊 0️⃣ 1️⃣ 2️⃣ 3️⃣ 4️⃣ 5️⃣ 6️⃣ 7️⃣ 8️⃣ 9️⃣ 🔟 Powerلُلُصّبُلُلصّبُررً ॣ ॣh ॣ ॣ冗",
|
||||
"payload": "AqPiGSQthUZecK3NZAtWSz/v9X0u+HRdXnoGY7LczOtUf05aMF89q1FLwJvaFJYICZoMYgRJHFLwPiOHce7fuAc40kX0wXJvipyBJ9HzCOj7CgtnC1/cmPCHR3s5AIORmroBWglm1LiFMohv1FSPEbaBD51VXxJa4JyWpYhreSOEjn1wd0lMKC9b+osV2N2tpbs+rbpQem2tRen3sWflmCqjkG5VOVwRErCuXuPb5+hYwd8BoZbfCrsiAVLd7YT44dRtKNBx6rkabWfddKSLtreHLDysOhQUVOp/XkE7OzSkWl6sky0Hva6qJJ/V726hMlomvcLHjE41iKmW2CpcZfOedg=="
|
||||
}
|
||||
],
|
||||
"encrypt_decrypt_long_msg": [
|
||||
{
|
||||
"conversation_key": "8fc262099ce0d0bb9b89bac05bb9e04f9bc0090acc181fef6840ccee470371ed",
|
||||
"nonce": "326bcb2c943cd6bb717588c9e5a7e738edf6ed14ec5f5344caa6ef56f0b9cff7",
|
||||
"pattern": "x",
|
||||
"repeat": 65535,
|
||||
"plaintext_sha256": "09ab7495d3e61a76f0deb12cb0306f0696cbb17ffc12131368c7a939f12f56d3",
|
||||
"payload_sha256": "90714492225faba06310bff2f249ebdc2a5e609d65a629f1c87f2d4ffc55330a"
|
||||
},
|
||||
{
|
||||
"conversation_key": "56adbe3720339363ab9c3b8526ffce9fd77600927488bfc4b59f7a68ffe5eae0",
|
||||
"nonce": "ad68da81833c2a8ff609c3d2c0335fd44fe5954f85bb580c6a8d467aa9fc5dd0",
|
||||
"pattern": "!",
|
||||
"repeat": 65535,
|
||||
"plaintext_sha256": "6af297793b72ae092c422e552c3bb3cbc310da274bd1cf9e31023a7fe4a2d75e",
|
||||
"payload_sha256": "8013e45a109fad3362133132b460a2d5bce235fe71c8b8f4014793fb52a49844"
|
||||
},
|
||||
{
|
||||
"conversation_key": "7fc540779979e472bb8d12480b443d1e5eb1098eae546ef2390bee499bbf46be",
|
||||
"nonce": "34905e82105c20de9a2f6cd385a0d541e6bcc10601d12481ff3a7575dc622033",
|
||||
"pattern": "🦄",
|
||||
"repeat": 16383,
|
||||
"plaintext_sha256": "a249558d161b77297bc0cb311dde7d77190f6571b25c7e4429cd19044634a61f",
|
||||
"payload_sha256": "b3348422471da1f3c59d79acfe2fe103f3cd24488109e5b18734cdb5953afd15"
|
||||
},
|
||||
{
|
||||
"conversation_key": "56adbe3720339363ab9c3b8526ffce9fd77600927488bfc4b59f7a68ffe5eae0",
|
||||
"nonce": "ad68da81833c2a8ff609c3d2c0335fd44fe5954f85bb580c6a8d467aa9fc5dd0",
|
||||
"pattern": "!",
|
||||
"repeat": 65536,
|
||||
"plaintext_sha256": "b007fe445ff5b583c095c4688c75d8afef66d4c93eb6aeebcea0942e670e1cd3",
|
||||
"payload_sha256": "f816ffbcb053a0669488992e2d7c57c2d950d3d4af6e19a16297f3e565a4103f"
|
||||
},
|
||||
{
|
||||
"conversation_key": "56adbe3720339363ab9c3b8526ffce9fd77600927488bfc4b59f7a68ffe5eae0",
|
||||
"nonce": "ad68da81833c2a8ff609c3d2c0335fd44fe5954f85bb580c6a8d467aa9fc5dd0",
|
||||
"pattern": "a",
|
||||
"repeat": 20000000,
|
||||
"plaintext_sha256": "aded0ea9b4d06589b13d00bab483faf479d61ed5de21f1760aa7018a28e330e5",
|
||||
"payload_sha256": "9e683311894d52e48a825837883c539263c7787c7fe024e1590d96776a31684b"
|
||||
}
|
||||
]
|
||||
},
|
||||
"invalid": {
|
||||
"encrypt_msg_lengths": [0, 65536, 100000, 10000000],
|
||||
"get_conversation_key": [
|
||||
{
|
||||
"sec1": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
||||
"pub2": "1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
|
||||
"note": "sec1 higher than curve.n"
|
||||
},
|
||||
{
|
||||
"sec1": "0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"pub2": "1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
|
||||
"note": "sec1 is 0"
|
||||
},
|
||||
{
|
||||
"sec1": "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364139",
|
||||
"pub2": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
||||
"note": "pub2 is invalid, no sqrt, all-ff"
|
||||
},
|
||||
{
|
||||
"sec1": "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141",
|
||||
"pub2": "1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
|
||||
"note": "sec1 == curve.n"
|
||||
},
|
||||
{
|
||||
"sec1": "0000000000000000000000000000000000000000000000000000000000000002",
|
||||
"pub2": "1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
|
||||
"note": "pub2 is invalid, no sqrt"
|
||||
},
|
||||
{
|
||||
"sec1": "0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20",
|
||||
"pub2": "0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"note": "pub2 is point of order 3 on twist"
|
||||
},
|
||||
{
|
||||
"sec1": "0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20",
|
||||
"pub2": "eb1f7200aecaa86682376fb1c13cd12b732221e774f553b0a0857f88fa20f86d",
|
||||
"note": "pub2 is point of order 13 on twist"
|
||||
},
|
||||
{
|
||||
"sec1": "0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20",
|
||||
"pub2": "709858a4c121e4a84eb59c0ded0261093c71e8ca29efeef21a6161c447bcaf9f",
|
||||
"note": "pub2 is point of order 3319 on twist"
|
||||
}
|
||||
],
|
||||
"decrypt": [
|
||||
{
|
||||
"conversation_key": "ca2527a037347b91bea0c8a30fc8d9600ffd81ec00038671e3a0f0cb0fc9f642",
|
||||
"nonce": "daaea5ca345b268e5b62060ca72c870c48f713bc1e00ff3fc0ddb78e826f10db",
|
||||
"plaintext": "n o b l e",
|
||||
"payload": "#Atqupco0WyaOW2IGDKcshwxI9xO8HgD/P8Ddt46CbxDbrhdG8VmJdU0MIDf06CUvEvdnr1cp1fiMtlM/GrE92xAc1K5odTpCzUB+mjXgbaqtntBUbTToSUoT0ovrlPwzGjyp",
|
||||
"note": "unknown encryption version"
|
||||
},
|
||||
{
|
||||
"conversation_key": "36f04e558af246352dcf73b692fbd3646a2207bd8abd4b1cd26b234db84d9481",
|
||||
"nonce": "ad408d4be8616dc84bb0bf046454a2a102edac937c35209c43cd7964c5feb781",
|
||||
"plaintext": "⚠️",
|
||||
"payload": "AK1AjUvoYW3IS7C/BGRUoqEC7ayTfDUgnEPNeWTF/reBZFaha6EAIRueE9D1B1RuoiuFScC0Q94yjIuxZD3JStQtE8JMNacWFs9rlYP+ZydtHhRucp+lxfdvFlaGV/sQlqZz",
|
||||
"note": "unknown encryption version 0"
|
||||
},
|
||||
{
|
||||
"conversation_key": "ca2527a037347b91bea0c8a30fc8d9600ffd81ec00038671e3a0f0cb0fc9f642",
|
||||
"nonce": "daaea5ca345b268e5b62060ca72c870c48f713bc1e00ff3fc0ddb78e826f10db",
|
||||
"plaintext": "n o s t r",
|
||||
"payload": "Atфupco0WyaOW2IGDKcshwxI9xO8HgD/P8Ddt46CbxDbrhdG8VmJZE0UICD06CUvEvdnr1cp1fiMtlM/GrE92xAc1EwsVCQEgWEu2gsHUVf4JAa3TpgkmFc3TWsax0v6n/Wq",
|
||||
"note": "invalid base64"
|
||||
},
|
||||
{
|
||||
"conversation_key": "cff7bd6a3e29a450fd27f6c125d5edeb0987c475fd1e8d97591e0d4d8a89763c",
|
||||
"nonce": "09ff97750b084012e15ecb84614ce88180d7b8ec0d468508a86b6d70c0361a25",
|
||||
"plaintext": "¯\\_(ツ)_/¯",
|
||||
"payload": "Agn/l3ULCEAS4V7LhGFM6IGA17jsDUaFCKhrbXDANholyySBfeh+EN8wNB9gaLlg4j6wdBYh+3oK+mnxWu3NKRbSvQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
|
||||
"note": "invalid MAC"
|
||||
},
|
||||
{
|
||||
"conversation_key": "cfcc9cf682dfb00b11357f65bdc45e29156b69db424d20b3596919074f5bf957",
|
||||
"nonce": "65b14b0b949aaa7d52c417eb753b390e8ad6d84b23af4bec6d9bfa3e03a08af4",
|
||||
"plaintext": "🥎",
|
||||
"payload": "AmWxSwuUmqp9UsQX63U7OQ6K1thLI69L7G2b+j4DoIr0oRWQ8avl4OLqWZiTJ10vIgKrNqjoaX+fNhE9RqmR5g0f6BtUg1ijFMz71MO1D4lQLQfW7+UHva8PGYgQ1QpHlKgR",
|
||||
"note": "invalid MAC"
|
||||
},
|
||||
{
|
||||
"conversation_key": "5254827d29177622d40a7b67cad014fe7137700c3c523903ebbe3e1b74d40214",
|
||||
"nonce": "7ab65dbb8bbc2b8e35cafb5745314e1f050325a864d11d0475ef75b3660d91c1",
|
||||
"plaintext": "elliptic-curve cryptography",
|
||||
"payload": "Anq2XbuLvCuONcr7V0UxTh8FAyWoZNEdBHXvdbNmDZHB573MI7R7rrTYftpqmvUpahmBC2sngmI14/L0HjOZ7lWGJlzdh6luiOnGPc46cGxf08MRC4CIuxx3i2Lm0KqgJ7vA",
|
||||
"note": "invalid padding"
|
||||
},
|
||||
{
|
||||
"conversation_key": "fea39aca9aa8340c3a78ae1f0902aa7e726946e4efcd7783379df8096029c496",
|
||||
"nonce": "7d4283e3b54c885d6afee881f48e62f0a3f5d7a9e1cb71ccab594a7882c39330",
|
||||
"plaintext": "noble",
|
||||
"payload": "An1Cg+O1TIhdav7ogfSOYvCj9dep4ctxzKtZSniCw5MwRrrPJFyAQYZh5VpjC2QYzny5LIQ9v9lhqmZR4WBYRNJ0ognHVNMwiFV1SHpvUFT8HHZN/m/QarflbvDHAtO6pY16",
|
||||
"note": "invalid padding"
|
||||
},
|
||||
{
|
||||
"conversation_key": "0c4cffb7a6f7e706ec94b2e879f1fc54ff8de38d8db87e11787694d5392d5b3f",
|
||||
"nonce": "6f9fd72667c273acd23ca6653711a708434474dd9eb15c3edb01ce9a95743e9b",
|
||||
"plaintext": "censorship-resistant and global social network",
|
||||
"payload": "Am+f1yZnwnOs0jymZTcRpwhDRHTdnrFcPtsBzpqVdD6b2NZDaNm/TPkZGr75kbB6tCSoq7YRcbPiNfJXNch3Tf+o9+zZTMxwjgX/nm3yDKR2kHQMBhVleCB9uPuljl40AJ8kXRD0gjw+aYRJFUMK9gCETZAjjmrsCM+nGRZ1FfNsHr6Z",
|
||||
"note": "invalid padding"
|
||||
},
|
||||
{
|
||||
"conversation_key": "5cd2d13b9e355aeb2452afbd3786870dbeecb9d355b12cb0a3b6e9da5744cd35",
|
||||
"nonce": "b60036976a1ada277b948fd4caa065304b96964742b89d26f26a25263a5060bd",
|
||||
"plaintext": "0",
|
||||
"payload": "",
|
||||
"note": "invalid payload length: 0"
|
||||
},
|
||||
{
|
||||
"conversation_key": "d61d3f09c7dfe1c0be91af7109b60a7d9d498920c90cbba1e137320fdd938853",
|
||||
"nonce": "1a29d02c8b4527745a2ccb38bfa45655deb37bc338ab9289d756354cea1fd07c",
|
||||
"plaintext": "1",
|
||||
"payload": "Ag==",
|
||||
"note": "invalid payload length: 4"
|
||||
},
|
||||
{
|
||||
"conversation_key": "873bb0fc665eb950a8e7d5971965539f6ebd645c83c08cd6a85aafbad0f0bc47",
|
||||
"nonce": "c826d3c38e765ab8cc42060116cd1464b2a6ce01d33deba5dedfb48615306d4a",
|
||||
"plaintext": "2",
|
||||
"payload": "AqxgToSh3H7iLYRJjoWAM+vSv/Y1mgNlm6OWWjOYUClrFF8=",
|
||||
"note": "invalid payload length: 48"
|
||||
},
|
||||
{
|
||||
"conversation_key": "9f2fef8f5401ac33f74641b568a7a30bb19409c76ffdc5eae2db6b39d2617fbe",
|
||||
"nonce": "9ff6484642545221624eaac7b9ea27133a4cc2356682a6033aceeef043549861",
|
||||
"plaintext": "3",
|
||||
"payload": "Ap/2SEZCVFIhYk6qx7nqJxM6TMI1ZoKmAzrO7vBDVJhhuZXWiM20i/tIsbjT0KxkJs2MZjh1oXNYMO9ggfk7i47WQA==",
|
||||
"note": "invalid payload length: 92"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* ISC License
|
||||
*
|
||||
* Copyright (c) 2013-2026
|
||||
* Frank Denis <j at pureftpd dot org>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
@@ -0,0 +1,4 @@
|
||||
module Clibsodium {
|
||||
header "sodium.h"
|
||||
export *
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
|
||||
#ifndef sodium_H
|
||||
#define sodium_H
|
||||
|
||||
#include "sodium/version.h"
|
||||
|
||||
#include "sodium/core.h"
|
||||
#include "sodium/crypto_aead_xchacha20poly1305.h"
|
||||
#include "sodium/crypto_core_hchacha20.h"
|
||||
#include "sodium/crypto_stream_chacha20.h"
|
||||
#include "sodium/runtime.h"
|
||||
#include "sodium/utils.h"
|
||||
|
||||
#ifndef SODIUM_LIBRARY_MINIMAL
|
||||
#include "sodium/crypto_box_curve25519xchacha20poly1305.h"
|
||||
#include "sodium/crypto_core_ed25519.h"
|
||||
#include "sodium/crypto_core_ristretto255.h"
|
||||
#include "sodium/crypto_pwhash_scryptsalsa208sha256.h"
|
||||
#include "sodium/crypto_scalarmult_ed25519.h"
|
||||
#include "sodium/crypto_scalarmult_ristretto255.h"
|
||||
#include "sodium/crypto_secretbox_xchacha20poly1305.h"
|
||||
#include "sodium/crypto_stream_salsa2012.h"
|
||||
#include "sodium/crypto_stream_salsa208.h"
|
||||
#include "sodium/crypto_stream_xchacha20.h"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,100 @@
|
||||
#ifndef crypto_aead_xchacha20poly1305_H
|
||||
#define crypto_aead_xchacha20poly1305_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include "export.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
# ifdef __GNUC__
|
||||
# pragma GCC diagnostic ignored "-Wlong-long"
|
||||
# endif
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define crypto_aead_xchacha20poly1305_ietf_KEYBYTES 32U
|
||||
SODIUM_EXPORT
|
||||
size_t crypto_aead_xchacha20poly1305_ietf_keybytes(void);
|
||||
|
||||
#define crypto_aead_xchacha20poly1305_ietf_NSECBYTES 0U
|
||||
SODIUM_EXPORT
|
||||
size_t crypto_aead_xchacha20poly1305_ietf_nsecbytes(void);
|
||||
|
||||
#define crypto_aead_xchacha20poly1305_ietf_NPUBBYTES 24U
|
||||
SODIUM_EXPORT
|
||||
size_t crypto_aead_xchacha20poly1305_ietf_npubbytes(void);
|
||||
|
||||
#define crypto_aead_xchacha20poly1305_ietf_ABYTES 16U
|
||||
SODIUM_EXPORT
|
||||
size_t crypto_aead_xchacha20poly1305_ietf_abytes(void);
|
||||
|
||||
#define crypto_aead_xchacha20poly1305_ietf_MESSAGEBYTES_MAX \
|
||||
(SODIUM_SIZE_MAX - crypto_aead_xchacha20poly1305_ietf_ABYTES)
|
||||
SODIUM_EXPORT
|
||||
size_t crypto_aead_xchacha20poly1305_ietf_messagebytes_max(void);
|
||||
|
||||
SODIUM_EXPORT
|
||||
int crypto_aead_xchacha20poly1305_ietf_encrypt(unsigned char *c,
|
||||
unsigned long long *clen_p,
|
||||
const unsigned char *m,
|
||||
unsigned long long mlen,
|
||||
const unsigned char *ad,
|
||||
unsigned long long adlen,
|
||||
const unsigned char *nsec,
|
||||
const unsigned char *npub,
|
||||
const unsigned char *k)
|
||||
__attribute__ ((nonnull(1, 8, 9)));
|
||||
|
||||
SODIUM_EXPORT
|
||||
int crypto_aead_xchacha20poly1305_ietf_decrypt(unsigned char *m,
|
||||
unsigned long long *mlen_p,
|
||||
unsigned char *nsec,
|
||||
const unsigned char *c,
|
||||
unsigned long long clen,
|
||||
const unsigned char *ad,
|
||||
unsigned long long adlen,
|
||||
const unsigned char *npub,
|
||||
const unsigned char *k)
|
||||
__attribute__ ((warn_unused_result)) __attribute__ ((nonnull(4, 8, 9)));
|
||||
|
||||
SODIUM_EXPORT
|
||||
int crypto_aead_xchacha20poly1305_ietf_encrypt_detached(unsigned char *c,
|
||||
unsigned char *mac,
|
||||
unsigned long long *maclen_p,
|
||||
const unsigned char *m,
|
||||
unsigned long long mlen,
|
||||
const unsigned char *ad,
|
||||
unsigned long long adlen,
|
||||
const unsigned char *nsec,
|
||||
const unsigned char *npub,
|
||||
const unsigned char *k)
|
||||
__attribute__ ((nonnull(1, 2, 9, 10)));
|
||||
|
||||
SODIUM_EXPORT
|
||||
int crypto_aead_xchacha20poly1305_ietf_decrypt_detached(unsigned char *m,
|
||||
unsigned char *nsec,
|
||||
const unsigned char *c,
|
||||
unsigned long long clen,
|
||||
const unsigned char *mac,
|
||||
const unsigned char *ad,
|
||||
unsigned long long adlen,
|
||||
const unsigned char *npub,
|
||||
const unsigned char *k)
|
||||
__attribute__ ((warn_unused_result)) __attribute__ ((nonnull(3, 5, 8, 9)));
|
||||
|
||||
SODIUM_EXPORT
|
||||
void crypto_aead_xchacha20poly1305_ietf_keygen(unsigned char k[crypto_aead_xchacha20poly1305_ietf_KEYBYTES])
|
||||
__attribute__ ((nonnull));
|
||||
|
||||
/* Aliases */
|
||||
|
||||
#define crypto_aead_xchacha20poly1305_IETF_KEYBYTES crypto_aead_xchacha20poly1305_ietf_KEYBYTES
|
||||
#define crypto_aead_xchacha20poly1305_IETF_NSECBYTES crypto_aead_xchacha20poly1305_ietf_NSECBYTES
|
||||
#define crypto_aead_xchacha20poly1305_IETF_NPUBBYTES crypto_aead_xchacha20poly1305_ietf_NPUBBYTES
|
||||
#define crypto_aead_xchacha20poly1305_IETF_ABYTES crypto_aead_xchacha20poly1305_ietf_ABYTES
|
||||
#define crypto_aead_xchacha20poly1305_IETF_MESSAGEBYTES_MAX crypto_aead_xchacha20poly1305_ietf_MESSAGEBYTES_MAX
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,36 @@
|
||||
#ifndef crypto_core_hchacha20_H
|
||||
#define crypto_core_hchacha20_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include "export.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define crypto_core_hchacha20_OUTPUTBYTES 32U
|
||||
SODIUM_EXPORT
|
||||
size_t crypto_core_hchacha20_outputbytes(void);
|
||||
|
||||
#define crypto_core_hchacha20_INPUTBYTES 16U
|
||||
SODIUM_EXPORT
|
||||
size_t crypto_core_hchacha20_inputbytes(void);
|
||||
|
||||
#define crypto_core_hchacha20_KEYBYTES 32U
|
||||
SODIUM_EXPORT
|
||||
size_t crypto_core_hchacha20_keybytes(void);
|
||||
|
||||
#define crypto_core_hchacha20_CONSTBYTES 16U
|
||||
SODIUM_EXPORT
|
||||
size_t crypto_core_hchacha20_constbytes(void);
|
||||
|
||||
SODIUM_EXPORT
|
||||
int crypto_core_hchacha20(unsigned char *out, const unsigned char *in,
|
||||
const unsigned char *k, const unsigned char *c)
|
||||
__attribute__ ((nonnull(1, 2, 3)));
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,106 @@
|
||||
#ifndef crypto_stream_chacha20_H
|
||||
#define crypto_stream_chacha20_H
|
||||
|
||||
/*
|
||||
* WARNING: This is just a stream cipher. It is NOT authenticated encryption.
|
||||
* While it provides some protection against eavesdropping, it does NOT
|
||||
* provide any security against active attacks.
|
||||
* Unless you know what you're doing, what you are looking for is probably
|
||||
* the crypto_box functions.
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include "export.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
# ifdef __GNUC__
|
||||
# pragma GCC diagnostic ignored "-Wlong-long"
|
||||
# endif
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define crypto_stream_chacha20_KEYBYTES 32U
|
||||
SODIUM_EXPORT
|
||||
size_t crypto_stream_chacha20_keybytes(void);
|
||||
|
||||
#define crypto_stream_chacha20_NONCEBYTES 8U
|
||||
SODIUM_EXPORT
|
||||
size_t crypto_stream_chacha20_noncebytes(void);
|
||||
|
||||
#define crypto_stream_chacha20_MESSAGEBYTES_MAX SODIUM_SIZE_MAX
|
||||
SODIUM_EXPORT
|
||||
size_t crypto_stream_chacha20_messagebytes_max(void);
|
||||
|
||||
/* ChaCha20 with a 64-bit nonce and a 64-bit counter, as originally designed */
|
||||
|
||||
SODIUM_EXPORT
|
||||
int crypto_stream_chacha20(unsigned char *c, unsigned long long clen,
|
||||
const unsigned char *n, const unsigned char *k)
|
||||
__attribute__ ((nonnull));
|
||||
|
||||
SODIUM_EXPORT
|
||||
int crypto_stream_chacha20_xor(unsigned char *c, const unsigned char *m,
|
||||
unsigned long long mlen, const unsigned char *n,
|
||||
const unsigned char *k)
|
||||
__attribute__ ((nonnull(1, 4, 5)));
|
||||
|
||||
SODIUM_EXPORT
|
||||
int crypto_stream_chacha20_xor_ic(unsigned char *c, const unsigned char *m,
|
||||
unsigned long long mlen,
|
||||
const unsigned char *n, uint64_t ic,
|
||||
const unsigned char *k)
|
||||
__attribute__ ((nonnull(1, 4, 6)));
|
||||
|
||||
SODIUM_EXPORT
|
||||
void crypto_stream_chacha20_keygen(unsigned char k[crypto_stream_chacha20_KEYBYTES])
|
||||
__attribute__ ((nonnull));
|
||||
|
||||
/* ChaCha20 with a 96-bit nonce and a 32-bit counter (IETF) */
|
||||
|
||||
#define crypto_stream_chacha20_ietf_KEYBYTES 32U
|
||||
SODIUM_EXPORT
|
||||
size_t crypto_stream_chacha20_ietf_keybytes(void);
|
||||
|
||||
#define crypto_stream_chacha20_ietf_NONCEBYTES 12U
|
||||
SODIUM_EXPORT
|
||||
size_t crypto_stream_chacha20_ietf_noncebytes(void);
|
||||
|
||||
#define crypto_stream_chacha20_ietf_MESSAGEBYTES_MAX \
|
||||
SODIUM_MIN(SODIUM_SIZE_MAX, 64ULL * (1ULL << 32))
|
||||
SODIUM_EXPORT
|
||||
size_t crypto_stream_chacha20_ietf_messagebytes_max(void);
|
||||
|
||||
SODIUM_EXPORT
|
||||
int crypto_stream_chacha20_ietf(unsigned char *c, unsigned long long clen,
|
||||
const unsigned char *n, const unsigned char *k)
|
||||
__attribute__ ((nonnull));
|
||||
|
||||
SODIUM_EXPORT
|
||||
int crypto_stream_chacha20_ietf_xor(unsigned char *c, const unsigned char *m,
|
||||
unsigned long long mlen, const unsigned char *n,
|
||||
const unsigned char *k)
|
||||
__attribute__ ((nonnull(1, 4, 5)));
|
||||
|
||||
SODIUM_EXPORT
|
||||
int crypto_stream_chacha20_ietf_xor_ic(unsigned char *c, const unsigned char *m,
|
||||
unsigned long long mlen,
|
||||
const unsigned char *n, uint32_t ic,
|
||||
const unsigned char *k)
|
||||
__attribute__ ((nonnull(1, 4, 6)));
|
||||
|
||||
SODIUM_EXPORT
|
||||
void crypto_stream_chacha20_ietf_keygen(unsigned char k[crypto_stream_chacha20_ietf_KEYBYTES])
|
||||
__attribute__ ((nonnull));
|
||||
|
||||
/* Aliases */
|
||||
|
||||
#define crypto_stream_chacha20_IETF_KEYBYTES crypto_stream_chacha20_ietf_KEYBYTES
|
||||
#define crypto_stream_chacha20_IETF_NONCEBYTES crypto_stream_chacha20_ietf_NONCEBYTES
|
||||
#define crypto_stream_chacha20_IETF_MESSAGEBYTES_MAX crypto_stream_chacha20_ietf_MESSAGEBYTES_MAX
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,57 @@
|
||||
|
||||
#ifndef sodium_export_H
|
||||
#define sodium_export_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <limits.h>
|
||||
|
||||
#if !defined(__clang__) && !defined(__GNUC__)
|
||||
# ifdef __attribute__
|
||||
# undef __attribute__
|
||||
# endif
|
||||
# define __attribute__(a)
|
||||
#endif
|
||||
|
||||
#ifdef SODIUM_STATIC
|
||||
# define SODIUM_EXPORT
|
||||
# define SODIUM_EXPORT_WEAK
|
||||
#else
|
||||
# if defined(_MSC_VER)
|
||||
# ifdef SODIUM_DLL_EXPORT
|
||||
# define SODIUM_EXPORT __declspec(dllexport)
|
||||
# else
|
||||
# define SODIUM_EXPORT __declspec(dllimport)
|
||||
# endif
|
||||
# else
|
||||
# if defined(__SUNPRO_C)
|
||||
# ifndef __GNU_C__
|
||||
# define SODIUM_EXPORT __attribute__ (visibility(__global))
|
||||
# else
|
||||
# define SODIUM_EXPORT __attribute__ __global
|
||||
# endif
|
||||
# elif defined(_MSG_VER)
|
||||
# define SODIUM_EXPORT extern __declspec(dllexport)
|
||||
# else
|
||||
# define SODIUM_EXPORT __attribute__ ((visibility ("default")))
|
||||
# endif
|
||||
# endif
|
||||
# if defined(__ELF__) && !defined(SODIUM_DISABLE_WEAK_FUNCTIONS)
|
||||
# define SODIUM_EXPORT_WEAK SODIUM_EXPORT __attribute__((weak))
|
||||
# else
|
||||
# define SODIUM_EXPORT_WEAK SODIUM_EXPORT
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef CRYPTO_ALIGN
|
||||
# if defined(__INTEL_COMPILER) || defined(_MSC_VER)
|
||||
# define CRYPTO_ALIGN(x) __declspec(align(x))
|
||||
# else
|
||||
# define CRYPTO_ALIGN(x) __attribute__ ((aligned(x)))
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#define SODIUM_MIN(A, B) ((A) < (B) ? (A) : (B))
|
||||
#define SODIUM_SIZE_MAX SODIUM_MIN(UINT64_MAX, SIZE_MAX)
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,55 @@
|
||||
|
||||
#ifndef sodium_runtime_H
|
||||
#define sodium_runtime_H
|
||||
|
||||
#include "export.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
SODIUM_EXPORT_WEAK
|
||||
int sodium_runtime_has_neon(void);
|
||||
|
||||
SODIUM_EXPORT_WEAK
|
||||
int sodium_runtime_has_armcrypto(void);
|
||||
|
||||
SODIUM_EXPORT_WEAK
|
||||
int sodium_runtime_has_sse2(void);
|
||||
|
||||
SODIUM_EXPORT_WEAK
|
||||
int sodium_runtime_has_sse3(void);
|
||||
|
||||
SODIUM_EXPORT_WEAK
|
||||
int sodium_runtime_has_ssse3(void);
|
||||
|
||||
SODIUM_EXPORT_WEAK
|
||||
int sodium_runtime_has_sse41(void);
|
||||
|
||||
SODIUM_EXPORT_WEAK
|
||||
int sodium_runtime_has_avx(void);
|
||||
|
||||
SODIUM_EXPORT_WEAK
|
||||
int sodium_runtime_has_avx2(void);
|
||||
|
||||
SODIUM_EXPORT_WEAK
|
||||
int sodium_runtime_has_avx512f(void);
|
||||
|
||||
SODIUM_EXPORT_WEAK
|
||||
int sodium_runtime_has_pclmul(void);
|
||||
|
||||
SODIUM_EXPORT_WEAK
|
||||
int sodium_runtime_has_aesni(void);
|
||||
|
||||
SODIUM_EXPORT_WEAK
|
||||
int sodium_runtime_has_rdrand(void);
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
int _sodium_runtime_get_cpu_features(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,177 @@
|
||||
|
||||
#ifndef sodium_utils_H
|
||||
#define sodium_utils_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "export.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef SODIUM_C99
|
||||
# if defined(__cplusplus) || !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L
|
||||
# define SODIUM_C99(X)
|
||||
# else
|
||||
# define SODIUM_C99(X) X
|
||||
# endif
|
||||
#endif
|
||||
|
||||
SODIUM_EXPORT
|
||||
void sodium_memzero(void *const pnt, const size_t len);
|
||||
|
||||
SODIUM_EXPORT
|
||||
void sodium_stackzero(const size_t len);
|
||||
|
||||
/*
|
||||
* WARNING: sodium_memcmp() must be used to verify if two secret keys
|
||||
* are equal, in constant time.
|
||||
* It returns 0 if the keys are equal, and -1 if they differ.
|
||||
* This function is not designed for lexicographical comparisons.
|
||||
*/
|
||||
SODIUM_EXPORT
|
||||
int sodium_memcmp(const void *const b1_, const void *const b2_, size_t len)
|
||||
__attribute__((warn_unused_result));
|
||||
|
||||
/*
|
||||
* sodium_compare() returns -1 if b1_ < b2_, 1 if b1_ > b2_ and 0 if b1_ == b2_
|
||||
* It is suitable for lexicographical comparisons, or to compare nonces
|
||||
* and counters stored in little-endian format.
|
||||
* However, it is slower than sodium_memcmp().
|
||||
*/
|
||||
SODIUM_EXPORT
|
||||
int sodium_compare(const unsigned char *b1_, const unsigned char *b2_, size_t len)
|
||||
__attribute__((warn_unused_result));
|
||||
|
||||
SODIUM_EXPORT
|
||||
int sodium_is_zero(const unsigned char *n, const size_t nlen);
|
||||
|
||||
SODIUM_EXPORT
|
||||
void sodium_increment(unsigned char *n, const size_t nlen);
|
||||
|
||||
SODIUM_EXPORT
|
||||
void sodium_add(unsigned char *a, const unsigned char *b, const size_t len);
|
||||
|
||||
SODIUM_EXPORT
|
||||
void sodium_sub(unsigned char *a, const unsigned char *b, const size_t len);
|
||||
|
||||
SODIUM_EXPORT
|
||||
char *sodium_bin2hex(char *const hex, const size_t hex_maxlen, const unsigned char *const bin,
|
||||
const size_t bin_len) __attribute__((nonnull(1)));
|
||||
|
||||
SODIUM_EXPORT
|
||||
int sodium_hex2bin(unsigned char *const bin, const size_t bin_maxlen, const char *const hex,
|
||||
const size_t hex_len, const char *const ignore, size_t *const bin_len,
|
||||
const char **const hex_end) __attribute__((nonnull(1)));
|
||||
|
||||
#define sodium_base64_VARIANT_ORIGINAL 1
|
||||
#define sodium_base64_VARIANT_ORIGINAL_NO_PADDING 3
|
||||
#define sodium_base64_VARIANT_URLSAFE 5
|
||||
#define sodium_base64_VARIANT_URLSAFE_NO_PADDING 7
|
||||
|
||||
/*
|
||||
* Computes the required length to encode BIN_LEN bytes as a base64 string
|
||||
* using the given variant. The computed length includes a trailing \0.
|
||||
*/
|
||||
#define sodium_base64_ENCODED_LEN(BIN_LEN, VARIANT) \
|
||||
(((BIN_LEN) / 3U) * 4U + \
|
||||
((((BIN_LEN) - ((BIN_LEN) / 3U) * 3U) | (((BIN_LEN) - ((BIN_LEN) / 3U) * 3U) >> 1)) & 1U) * \
|
||||
(4U - (~((((VARIANT) & 2U) >> 1) - 1U) & (3U - ((BIN_LEN) - ((BIN_LEN) / 3U) * 3U)))) + \
|
||||
1U)
|
||||
|
||||
SODIUM_EXPORT
|
||||
size_t sodium_base64_encoded_len(const size_t bin_len, const int variant);
|
||||
|
||||
SODIUM_EXPORT
|
||||
char *sodium_bin2base64(char *const b64, const size_t b64_maxlen, const unsigned char *const bin,
|
||||
const size_t bin_len, const int variant) __attribute__((nonnull(1)));
|
||||
|
||||
SODIUM_EXPORT
|
||||
int sodium_base642bin(unsigned char *const bin, const size_t bin_maxlen, const char *const b64,
|
||||
const size_t b64_len, const char *const ignore, size_t *const bin_len,
|
||||
const char **const b64_end, const int variant) __attribute__((nonnull(1)));
|
||||
|
||||
SODIUM_EXPORT
|
||||
int sodium_ip2bin(unsigned char bin[16], const char *ip, size_t ip_len)
|
||||
__attribute__((warn_unused_result)) __attribute__((nonnull));
|
||||
|
||||
SODIUM_EXPORT
|
||||
char *sodium_bin2ip(char *ip, size_t ip_maxlen, const unsigned char bin[16])
|
||||
__attribute__((nonnull));
|
||||
|
||||
SODIUM_EXPORT
|
||||
int sodium_mlock(void *const addr, const size_t len) __attribute__((nonnull));
|
||||
|
||||
SODIUM_EXPORT
|
||||
int sodium_munlock(void *const addr, const size_t len) __attribute__((nonnull));
|
||||
|
||||
/* WARNING: sodium_malloc() and sodium_allocarray() are not general-purpose
|
||||
* allocation functions.
|
||||
*
|
||||
* They return a pointer to a region filled with 0xd0 bytes, immediately
|
||||
* followed by a guard page. As a result, accessing a single byte after the
|
||||
* requested allocation size will intentionally trigger a segmentation fault.
|
||||
*
|
||||
* A canary and an additional guard page placed before the beginning of the
|
||||
* region may also kill the process if a buffer underflow is detected.
|
||||
*
|
||||
* The memory layout is:
|
||||
* [unprotected region size (read only)][guard page (no access)][unprotected pages
|
||||
* (read/write)][guard page (no access)]
|
||||
*
|
||||
* The layout of the unprotected pages is:
|
||||
* [optional padding][16-bytes canary][user region]
|
||||
*
|
||||
* Important limitations:
|
||||
* - These functions are significantly slower than standard allocation functions.
|
||||
* - Each allocation requires 3 or 4 additional pages.
|
||||
* - The returned address will not be aligned if the allocation size is not
|
||||
* a multiple of the required alignment. For this reason, these functions
|
||||
* are designed to store data such as secret keys and messages.
|
||||
*
|
||||
* sodium_malloc() can be used to allocate any libsodium data structure.
|
||||
*
|
||||
* The crypto_generichash_state structure is packed and its length is
|
||||
* either 357 or 361 bytes. When using sodium_malloc() to allocate a
|
||||
* crypto_generichash_state structure, padding must be added to ensure
|
||||
* proper alignment. Use crypto_generichash_statebytes() rather than sizeof():
|
||||
*
|
||||
* state = sodium_malloc(crypto_generichash_statebytes());
|
||||
*/
|
||||
|
||||
SODIUM_EXPORT
|
||||
void *sodium_malloc(const size_t size) __attribute__((malloc));
|
||||
|
||||
SODIUM_EXPORT
|
||||
void *sodium_allocarray(size_t count, size_t size) __attribute__((malloc));
|
||||
|
||||
SODIUM_EXPORT
|
||||
void sodium_free(void *ptr);
|
||||
|
||||
SODIUM_EXPORT
|
||||
int sodium_mprotect_noaccess(void *ptr) __attribute__((nonnull));
|
||||
|
||||
SODIUM_EXPORT
|
||||
int sodium_mprotect_readonly(void *ptr) __attribute__((nonnull));
|
||||
|
||||
SODIUM_EXPORT
|
||||
int sodium_mprotect_readwrite(void *ptr) __attribute__((nonnull));
|
||||
|
||||
SODIUM_EXPORT
|
||||
int sodium_pad(size_t *padded_buflen_p, unsigned char *buf, size_t unpadded_buflen,
|
||||
size_t blocksize, size_t max_buflen) __attribute__((nonnull(2)));
|
||||
|
||||
SODIUM_EXPORT
|
||||
int sodium_unpad(size_t *unpadded_buflen_p, const unsigned char *buf, size_t padded_buflen,
|
||||
size_t blocksize) __attribute__((nonnull(2)));
|
||||
|
||||
/* -------- */
|
||||
|
||||
int _sodium_alloc_init(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,33 @@
|
||||
|
||||
#ifndef sodium_version_H
|
||||
#define sodium_version_H
|
||||
|
||||
#include "export.h"
|
||||
|
||||
#define SODIUM_VERSION_STRING "1.0.21"
|
||||
|
||||
#define SODIUM_LIBRARY_VERSION_MAJOR 26
|
||||
#define SODIUM_LIBRARY_VERSION_MINOR 3
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
SODIUM_EXPORT
|
||||
const char *sodium_version_string(void);
|
||||
|
||||
SODIUM_EXPORT
|
||||
int sodium_library_version_major(void);
|
||||
|
||||
SODIUM_EXPORT
|
||||
int sodium_library_version_minor(void);
|
||||
|
||||
SODIUM_EXPORT
|
||||
int sodium_library_minimal(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user