diff --git a/quartz/src/androidTest/java/com/vitorpamplona/quartz/crypto/nip01/Nip01Test.kt b/quartz/src/androidTest/java/com/vitorpamplona/quartz/crypto/nip01/Nip01Test.kt new file mode 100644 index 000000000..5c93f1cbb --- /dev/null +++ b/quartz/src/androidTest/java/com/vitorpamplona/quartz/crypto/nip01/Nip01Test.kt @@ -0,0 +1,93 @@ +/** + * Copyright (c) 2024 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.crypto.nip01 + +import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.vitorpamplona.quartz.encoders.hexToByteArray +import com.vitorpamplona.quartz.encoders.toHexKey +import fr.acinq.secp256k1.Secp256k1 +import org.junit.Assert.assertEquals +import org.junit.Assert.assertNotEquals +import org.junit.Assert.assertTrue +import org.junit.Test +import org.junit.runner.RunWith +import java.security.SecureRandom + +@RunWith(AndroidJUnit4::class) +class Nip01Test { + private val nip01 = Nip01(Secp256k1.get(), SecureRandom()) + private val privateKey = "f410f88bcec6cbfda04d6a273c7b1dd8bba144cd45b71e87109cfa11dd7ed561".hexToByteArray() + + @Test + fun testGetPublicFromPrivateKey() { + assertEquals( + "7d4b8806f1fd713c287235411bf95aa81b7242ead892733ec84b3f2719845be6", + nip01.pubkeyCreate(privateKey).toHexKey(), + ) + } + + @Test + fun testDeterministicSign() { + assertEquals( + "1484d0e0bd62165e822e31f1f4cc8e1ce8e20c30a060e24fb0ecd7baf7c624f661fb7a3e4f0ddb43018e5f0b4892c929af64d8b7a86021aa081ec8231e3dfa37", + nip01.signDeterministic(nip01.sha256("Test".toByteArray()), privateKey).toHexKey(), + ) + } + + @Test + fun testSha256() { + assertEquals( + "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25", + nip01.sha256("Test".toByteArray()).toHexKey(), + ) + } + + @Test + fun testDeterministicVerify() { + assertTrue( + nip01.verify( + "1484d0e0bd62165e822e31f1f4cc8e1ce8e20c30a060e24fb0ecd7baf7c624f661fb7a3e4f0ddb43018e5f0b4892c929af64d8b7a86021aa081ec8231e3dfa37".hexToByteArray(), + nip01.sha256("Test".toByteArray()), + nip01.pubkeyCreate(privateKey), + ), + ) + } + + @Test + fun testNonDeterministicSign() { + assertNotEquals( + "1484d0e0bd62165e822e31f1f4cc8e1ce8e20c30a060e24fb0ecd7baf7c624f661fb7a3e4f0ddb43018e5f0b4892c929af64d8b7a86021aa081ec8231e3dfa37", + nip01.sign(nip01.sha256("Test".toByteArray()), privateKey).toHexKey(), + ) + } + + @Test + fun testNonDeterministicSignVerify() { + val signature = nip01.sign(nip01.sha256("Test".toByteArray()), privateKey) + assertTrue( + nip01.verify( + signature, + nip01.sha256("Test".toByteArray()), + nip01.pubkeyCreate(privateKey), + ), + ) + } +} diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/crypto/nip01/Nip01.kt b/quartz/src/main/java/com/vitorpamplona/quartz/crypto/nip01/Nip01.kt index 3bbf58ea3..eb5159735 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/crypto/nip01/Nip01.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/crypto/nip01/Nip01.kt @@ -38,9 +38,14 @@ class Nip01( fun sign( data: ByteArray, privKey: ByteArray, - auxrand32: ByteArray? = null, + auxrand32: ByteArray? = random(32), ): ByteArray = secp256k1.signSchnorr(data, privKey, auxrand32) + fun signDeterministic( + data: ByteArray, + privKey: ByteArray, + ): ByteArray = secp256k1.signSchnorr(data, privKey, null) + fun verify( signature: ByteArray, hash: ByteArray,