Skip to content

Commit

Permalink
Set a "noop" illegal callback
Browse files Browse the repository at this point in the history
The default "illegal" callback calls abort, which will crash the JVM or native app. We check arguments before calling secp256k1 so it should
never happen, except when trying to create a partial musig2 signature with an secret nonce that does not match the private key.

Methods that could be used to verify that the secret nonce does match the private key are not exported, hence the choice to set a custom callback.
  • Loading branch information
sstone committed Apr 15, 2024
1 parent eb92fcc commit 61df0e8
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 2 deletions.
9 changes: 8 additions & 1 deletion jni/c/src/fr_acinq_secp256k1_Secp256k1CFunctions.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,21 @@ void JNI_ThrowByName(JNIEnv *penv, const char *name, const char *msg)
} \
}

static void secp256k1_noop_illegal_callback_fn(const char* str, void* data) {
(void)str;
(void)data;
}

/*
* Class: fr_acinq_bitcoin_Secp256k1Bindings
* Method: secp256k1_context_create
* Signature: (I)J
*/
JNIEXPORT jlong JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1context_1create(JNIEnv *penv, jclass clazz, jint flags)
{
return (jlong)secp256k1_context_create(flags);
jlong ctx = (jlong)secp256k1_context_create(flags);
secp256k1_context_set_illegal_callback(ctx, &secp256k1_noop_illegal_callback_fn, NULL);
return ctx;
}

/*
Expand Down
5 changes: 4 additions & 1 deletion src/nativeMain/kotlin/fr/acinq/secp256k1/Secp256k1Native.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,11 @@ import secp256k1.*
public object Secp256k1Native : Secp256k1 {

private val ctx: CPointer<secp256k1_context> by lazy {
secp256k1_context_create((SECP256K1_FLAGS_TYPE_CONTEXT or SECP256K1_FLAGS_BIT_CONTEXT_SIGN or SECP256K1_FLAGS_BIT_CONTEXT_VERIFY).toUInt())
val c = secp256k1_context_create((SECP256K1_FLAGS_TYPE_CONTEXT or SECP256K1_FLAGS_BIT_CONTEXT_SIGN or SECP256K1_FLAGS_BIT_CONTEXT_VERIFY).toUInt())
?: error("Could not create secp256k1 context")
val callback = staticCFunction { _: CPointer<ByteVar>?, _: COpaquePointer? -> }
secp256k1_context_set_illegal_callback(c, callback, null)
c
}

private fun Int.requireSuccess(message: String): Int = if (this != 1) throw Secp256k1Exception(message) else this
Expand Down
23 changes: 23 additions & 0 deletions tests/src/commonTest/kotlin/fr/acinq/secp256k1/Secp256k1Test.kt
Original file line number Diff line number Diff line change
Expand Up @@ -520,6 +520,29 @@ class Secp256k1Test {
-1
)
}
assertFails {
val privkeys = listOf(
"0101010101010101010101010101010101010101010101010101010101010101",
"0202020202020202020202020202020202020202020202020202020202020202",
).map { Hex.decode(it) }.toTypedArray()
val pubkeys = privkeys.map { Secp256k1.pubkeyCreate(it) }

val sessionId = Hex.decode("0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F")
val nonces = pubkeys.map { Secp256k1.musigNonceGen(sessionId, null, it, null, null, null) }
val secnonces = nonces.map { it.copyOfRange(0, 132) }
val pubnonces = nonces.map { it.copyOfRange(132, 132 + 66) }
val aggnonce = Secp256k1.musigNonceAgg(pubnonces.toTypedArray())

val keyaggCaches = (0 until 2).map { ByteArray(Secp256k1.MUSIG2_PUBLIC_KEYAGG_CACHE_SIZE) }
val aggpubkey = Secp256k1.musigPubkeyAgg(pubkeys.toTypedArray(), keyaggCaches[0])
assertContentEquals(aggpubkey, Secp256k1.musigPubkeyAgg(pubkeys.toTypedArray(), keyaggCaches[1]))
assertContentEquals(keyaggCaches[0], keyaggCaches[1])
val msg32 = Hex.decode("0303030303030303030303030303030303030303030303030303030303030303")
val sessions = (0 until 2).map { Secp256k1.musigNonceProcess(aggnonce, msg32, keyaggCaches[it]) }

// we sign with the wrong secret nonce. it should fail (i.e. trigger an exception) but not crash the JVM
Secp256k1.musigPartialSign(secnonces[1], privkeys[0], keyaggCaches[0], sessions[0])
}
}

@Test
Expand Down

0 comments on commit 61df0e8

Please sign in to comment.