Skip to content

Commit 61df0e8

Browse files
committed
Set a "noop" illegal callback
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.
1 parent eb92fcc commit 61df0e8

File tree

3 files changed

+35
-2
lines changed

3 files changed

+35
-2
lines changed

jni/c/src/fr_acinq_secp256k1_Secp256k1CFunctions.c

+8-1
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,21 @@ void JNI_ThrowByName(JNIEnv *penv, const char *name, const char *msg)
4444
} \
4545
}
4646

47+
static void secp256k1_noop_illegal_callback_fn(const char* str, void* data) {
48+
(void)str;
49+
(void)data;
50+
}
51+
4752
/*
4853
* Class: fr_acinq_bitcoin_Secp256k1Bindings
4954
* Method: secp256k1_context_create
5055
* Signature: (I)J
5156
*/
5257
JNIEXPORT jlong JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1context_1create(JNIEnv *penv, jclass clazz, jint flags)
5358
{
54-
return (jlong)secp256k1_context_create(flags);
59+
jlong ctx = (jlong)secp256k1_context_create(flags);
60+
secp256k1_context_set_illegal_callback(ctx, &secp256k1_noop_illegal_callback_fn, NULL);
61+
return ctx;
5562
}
5663

5764
/*

src/nativeMain/kotlin/fr/acinq/secp256k1/Secp256k1Native.kt

+4-1
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,11 @@ import secp256k1.*
99
public object Secp256k1Native : Secp256k1 {
1010

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

1619
private fun Int.requireSuccess(message: String): Int = if (this != 1) throw Secp256k1Exception(message) else this

tests/src/commonTest/kotlin/fr/acinq/secp256k1/Secp256k1Test.kt

+23
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,29 @@ class Secp256k1Test {
520520
-1
521521
)
522522
}
523+
assertFails {
524+
val privkeys = listOf(
525+
"0101010101010101010101010101010101010101010101010101010101010101",
526+
"0202020202020202020202020202020202020202020202020202020202020202",
527+
).map { Hex.decode(it) }.toTypedArray()
528+
val pubkeys = privkeys.map { Secp256k1.pubkeyCreate(it) }
529+
530+
val sessionId = Hex.decode("0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F")
531+
val nonces = pubkeys.map { Secp256k1.musigNonceGen(sessionId, null, it, null, null, null) }
532+
val secnonces = nonces.map { it.copyOfRange(0, 132) }
533+
val pubnonces = nonces.map { it.copyOfRange(132, 132 + 66) }
534+
val aggnonce = Secp256k1.musigNonceAgg(pubnonces.toTypedArray())
535+
536+
val keyaggCaches = (0 until 2).map { ByteArray(Secp256k1.MUSIG2_PUBLIC_KEYAGG_CACHE_SIZE) }
537+
val aggpubkey = Secp256k1.musigPubkeyAgg(pubkeys.toTypedArray(), keyaggCaches[0])
538+
assertContentEquals(aggpubkey, Secp256k1.musigPubkeyAgg(pubkeys.toTypedArray(), keyaggCaches[1]))
539+
assertContentEquals(keyaggCaches[0], keyaggCaches[1])
540+
val msg32 = Hex.decode("0303030303030303030303030303030303030303030303030303030303030303")
541+
val sessions = (0 until 2).map { Secp256k1.musigNonceProcess(aggnonce, msg32, keyaggCaches[it]) }
542+
543+
// we sign with the wrong secret nonce. it should fail (i.e. trigger an exception) but not crash the JVM
544+
Secp256k1.musigPartialSign(secnonces[1], privkeys[0], keyaggCaches[0], sessions[0])
545+
}
523546
}
524547

525548
@Test

0 commit comments

Comments
 (0)