diff --git a/jni/c/headers/java/fr_acinq_secp256k1_Secp256k1CFunctions.h b/jni/c/headers/java/fr_acinq_secp256k1_Secp256k1CFunctions.h index b3189eb..dea893d 100644 --- a/jni/c/headers/java/fr_acinq_secp256k1_Secp256k1CFunctions.h +++ b/jni/c/headers/java/fr_acinq_secp256k1_Secp256k1CFunctions.h @@ -206,10 +206,10 @@ JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256 /* * Class: fr_acinq_secp256k1_Secp256k1CFunctions * Method: secp256k1_musig_nonce_gen_counter - * Signature: (JJ[B[B[B[B[B)[B + * Signature: (JJ[B[B[B[B)[B */ JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1musig_1nonce_1gen_1counter - (JNIEnv *, jclass, jlong, jlong, jbyteArray, jbyteArray, jbyteArray, jbyteArray, jbyteArray); + (JNIEnv *, jclass, jlong, jlong, jbyteArray, jbyteArray, jbyteArray, jbyteArray); /* * Class: fr_acinq_secp256k1_Secp256k1CFunctions diff --git a/jni/c/src/fr_acinq_secp256k1_Secp256k1CFunctions.c b/jni/c/src/fr_acinq_secp256k1_Secp256k1CFunctions.c index 5014a88..7355a7a 100644 --- a/jni/c/src/fr_acinq_secp256k1_Secp256k1CFunctions.c +++ b/jni/c/src/fr_acinq_secp256k1_Secp256k1CFunctions.c @@ -907,17 +907,16 @@ JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256 return jnonce; } -JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1musig_1nonce_1gen_1counter(JNIEnv *penv, jclass clazz, jlong jctx, jlong jcounter, jbyteArray jseckey, jbyteArray jpubkey, jbyteArray jmsg32, jbyteArray jkeyaggcache, jbyteArray jextra_input32) +JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1musig_1nonce_1gen_1counter(JNIEnv *penv, jclass clazz, jlong jctx, jlong jcounter, jbyteArray jseckey, jbyteArray jmsg32, jbyteArray jkeyaggcache, jbyteArray jextra_input32) { secp256k1_context *ctx = (secp256k1_context *)jctx; int result = 0; size_t size; secp256k1_musig_pubnonce pubnonce; secp256k1_musig_secnonce secnonce; - jbyte *pubkey_ptr; - secp256k1_pubkey pubkey; - unsigned char seckey[32]; + jbyte *seckey; unsigned char msg32[32]; + secp256k1_keypair keypair; secp256k1_musig_keyagg_cache keyaggcache; unsigned char extra_input32[32]; jbyteArray jnonce; @@ -930,20 +929,15 @@ JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256 if (jseckey == NULL) return NULL; + seckey = (*penv)->GetByteArrayElements(penv, jseckey, 0); + result = secp256k1_keypair_create(ctx, &keypair, seckey); + (*penv)->ReleaseByteArrayElements(penv, jseckey, seckey, 0); + CHECKRESULT(!result, "secp256k1_keypair_create failed"); + size = (*penv)->GetArrayLength(penv, jseckey); CHECKRESULT(size != 32, "invalid private key size"); copy_bytes_from_java(penv, jseckey, size, seckey); - if (jpubkey == NULL) - return NULL; - - size = (*penv)->GetArrayLength(penv, jpubkey); - CHECKRESULT((size != 33) && (size != 65), "invalid public key size"); - pubkey_ptr = (*penv)->GetByteArrayElements(penv, jpubkey, 0); - result = secp256k1_ec_pubkey_parse(ctx, &pubkey, (unsigned char *)pubkey_ptr, size); - (*penv)->ReleaseByteArrayElements(penv, jpubkey, pubkey_ptr, 0); - CHECKRESULT(!result, "secp256k1_ec_pubkey_parse failed"); - if (jmsg32 != NULL) { size = (*penv)->GetArrayLength(penv, jmsg32); @@ -966,7 +960,7 @@ JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256 } result = secp256k1_musig_nonce_gen_counter(ctx, &secnonce, &pubnonce, jcounter, - seckey, &pubkey, + &keypair, jmsg32 == NULL ? NULL : msg32, jkeyaggcache == NULL ? NULL : &keyaggcache, jextra_input32 == NULL ? NULL : extra_input32); CHECKRESULT(!result, "secp256k1_musig_nonce_gen failed"); diff --git a/jni/src/main/java/fr/acinq/secp256k1/Secp256k1CFunctions.java b/jni/src/main/java/fr/acinq/secp256k1/Secp256k1CFunctions.java index cec3684..5c12b22 100644 --- a/jni/src/main/java/fr/acinq/secp256k1/Secp256k1CFunctions.java +++ b/jni/src/main/java/fr/acinq/secp256k1/Secp256k1CFunctions.java @@ -91,7 +91,7 @@ public class Secp256k1CFunctions { public static native byte[] secp256k1_musig_nonce_gen(long ctx, byte[] session_rand32, byte[] seckey, byte[] pubkey, byte[] msg32, byte[] keyagg_cache, byte[] extra_input32); - public static native byte[] secp256k1_musig_nonce_gen_counter(long ctx, long nonrepeating_cnt, byte[] seckey, byte[] pubkey, byte[] msg32, byte[] keyagg_cache, byte[] extra_input32); + public static native byte[] secp256k1_musig_nonce_gen_counter(long ctx, long nonrepeating_cnt, byte[] seckey, byte[] msg32, byte[] keyagg_cache, byte[] extra_input32); public static native byte[] secp256k1_musig_nonce_agg(long ctx, byte[][] nonces); diff --git a/jni/src/main/kotlin/fr/acinq/secp256k1/NativeSecp256k1.kt b/jni/src/main/kotlin/fr/acinq/secp256k1/NativeSecp256k1.kt index 77c8eef..4966cf2 100644 --- a/jni/src/main/kotlin/fr/acinq/secp256k1/NativeSecp256k1.kt +++ b/jni/src/main/kotlin/fr/acinq/secp256k1/NativeSecp256k1.kt @@ -96,8 +96,8 @@ public object NativeSecp256k1 : Secp256k1 { return Secp256k1CFunctions.secp256k1_musig_nonce_gen(Secp256k1Context.getContext(), sessionRandom32, privkey, pubkey, msg32, keyaggCache, extraInput32) } - override fun musigNonceGenCounter(nonRepeatingCounter: ULong, privkey: ByteArray, pubkey: ByteArray, msg32: ByteArray?, keyaggCache: ByteArray?, extraInput32: ByteArray?): ByteArray { - return Secp256k1CFunctions.secp256k1_musig_nonce_gen_counter(Secp256k1Context.getContext(), nonRepeatingCounter.toLong(), privkey, pubkey, msg32, keyaggCache, extraInput32) + override fun musigNonceGenCounter(nonRepeatingCounter: ULong, privkey: ByteArray, msg32: ByteArray?, keyaggCache: ByteArray?, extraInput32: ByteArray?): ByteArray { + return Secp256k1CFunctions.secp256k1_musig_nonce_gen_counter(Secp256k1Context.getContext(), nonRepeatingCounter.toLong(), privkey, msg32, keyaggCache, extraInput32) } override fun musigNonceAgg(pubnonces: Array): ByteArray { diff --git a/native/secp256k1 b/native/secp256k1 index 77489bf..fdc0960 160000 --- a/native/secp256k1 +++ b/native/secp256k1 @@ -1 +1 @@ -Subproject commit 77489bf422e3714b5a5f6427b97ea4ef91bd34dc +Subproject commit fdc09608036822afc1cebbe0c5b56cebf8ba508d diff --git a/src/commonMain/kotlin/fr/acinq/secp256k1/Secp256k1.kt b/src/commonMain/kotlin/fr/acinq/secp256k1/Secp256k1.kt index 15fe42a..d2856e0 100644 --- a/src/commonMain/kotlin/fr/acinq/secp256k1/Secp256k1.kt +++ b/src/commonMain/kotlin/fr/acinq/secp256k1/Secp256k1.kt @@ -176,13 +176,12 @@ public interface Secp256k1 { * * @param nonRepeatingCounter non-repeating counter that must never be reused with the same private key * @param privkey signer's private key. - * @param pubkey signer's public key * @param msg32 (optional) 32-byte message that will be signed, if already known. * @param keyaggCache (optional) key aggregation cache data from the signing session. * @param extraInput32 (optional) additional 32-byte random data. * @return serialized version of the secret nonce and the corresponding public nonce. */ - public fun musigNonceGenCounter(nonRepeatingCounter: ULong, privkey: ByteArray, pubkey: ByteArray, msg32: ByteArray?, keyaggCache: ByteArray?, extraInput32: ByteArray?): ByteArray + public fun musigNonceGenCounter(nonRepeatingCounter: ULong, privkey: ByteArray, msg32: ByteArray?, keyaggCache: ByteArray?, extraInput32: ByteArray?): ByteArray /** * Aggregate public nonces from all participants of a signing session. diff --git a/src/nativeMain/kotlin/fr/acinq/secp256k1/Secp256k1Native.kt b/src/nativeMain/kotlin/fr/acinq/secp256k1/Secp256k1Native.kt index 678effb..6bb6161 100644 --- a/src/nativeMain/kotlin/fr/acinq/secp256k1/Secp256k1Native.kt +++ b/src/nativeMain/kotlin/fr/acinq/secp256k1/Secp256k1Native.kt @@ -325,22 +325,22 @@ public object Secp256k1Native : Secp256k1 { return nonce } - override fun musigNonceGenCounter(nonRepeatingCounter: ULong, privkey: ByteArray, pubkey: ByteArray, msg32: ByteArray?, keyaggCache: ByteArray?, extraInput32: ByteArray?): ByteArray { + override fun musigNonceGenCounter(nonRepeatingCounter: ULong, privkey: ByteArray, msg32: ByteArray?, keyaggCache: ByteArray?, extraInput32: ByteArray?): ByteArray { require(privkey.size ==32) - require(pubkey.size == 33 || pubkey.size == 65) msg32?.let { require(it.size == 32) } keyaggCache?.let { require(it.size == Secp256k1.MUSIG2_PUBLIC_KEYAGG_CACHE_SIZE) } extraInput32?.let { require(it.size == 32) } val nonce = memScoped { val secnonce = alloc() val pubnonce = alloc() - val nPubkey = allocPublicKey(pubkey) + val nKeypair = alloc() + secp256k1_keypair_create(ctx, nKeypair.ptr, toNat(privkey)) val nKeyAggCache = keyaggCache?.let { val n = alloc() memcpy(n.ptr, toNat(it), Secp256k1.MUSIG2_PUBLIC_KEYAGG_CACHE_SIZE.toULong()) n } - secp256k1_musig_nonce_gen_counter(ctx, secnonce.ptr, pubnonce.ptr, nonRepeatingCounter, toNat(privkey), nPubkey.ptr, msg32?.let { toNat(it) },nKeyAggCache?.ptr, extraInput32?.let { toNat(it) }).requireSuccess("secp256k1_musig_nonce_gen_counter() failed") + secp256k1_musig_nonce_gen_counter(ctx, secnonce.ptr, pubnonce.ptr, nonRepeatingCounter, nKeypair.ptr, msg32?.let { toNat(it) },nKeyAggCache?.ptr, extraInput32?.let { toNat(it) }).requireSuccess("secp256k1_musig_nonce_gen_counter() failed") val nPubnonce = allocArray(Secp256k1.MUSIG2_PUBLIC_NONCE_SIZE) secp256k1_musig_pubnonce_serialize(ctx, nPubnonce, pubnonce.ptr).requireSuccess("secp256k1_musig_pubnonce_serialize failed") secnonce.ptr.readBytes(Secp256k1.MUSIG2_SECRET_NONCE_SIZE) + nPubnonce.readBytes(Secp256k1.MUSIG2_PUBLIC_NONCE_SIZE) diff --git a/tests/src/commonTest/kotlin/fr/acinq/secp256k1/Musig2Test.kt b/tests/src/commonTest/kotlin/fr/acinq/secp256k1/Musig2Test.kt index 68718ff..35ec6b1 100644 --- a/tests/src/commonTest/kotlin/fr/acinq/secp256k1/Musig2Test.kt +++ b/tests/src/commonTest/kotlin/fr/acinq/secp256k1/Musig2Test.kt @@ -111,8 +111,7 @@ class Musig2Test { @Test fun `generate secret nonce from counter`() { val sk = Hex.decode("EEC1CB7D1B7254C5CAB0D9C61AB02E643D464A59FE6C96A7EFE871F07C5AEF54") - val pk = Secp256k1.pubkeyCreate(sk) - val nonce = Secp256k1.musigNonceGenCounter(0UL, sk, pk, null, null, null) + val nonce = Secp256k1.musigNonceGenCounter(0UL, sk, null, null, null) val secnonce = nonce.copyOfRange(0, Secp256k1.MUSIG2_SECRET_NONCE_SIZE) val pubnonce = nonce.copyOfRange(Secp256k1.MUSIG2_SECRET_NONCE_SIZE, Secp256k1.MUSIG2_SECRET_NONCE_SIZE + Secp256k1.MUSIG2_PUBLIC_NONCE_SIZE) assertContentEquals(secnonce.copyOfRange(4, 4 + 64), Hex.decode("842F1380CD17A198FC3DAD3B7DA7492941F46976F2702FF7C66F24F472036AF1DA3F952DDE4A2DA6B6325707CE87A4E3616D06FC5F81A9C99386D20A99CECF99"))