From b064c0bcf0830036d5ddd752ffa48edb865b31e1 Mon Sep 17 00:00:00 2001 From: kngako Date: Tue, 6 Aug 2024 00:19:55 +0200 Subject: [PATCH] Check arguments to constraints --- .../fr/acinq/secp256k1/NativeSecp256k1.kt | 4 +- .../kotlin/fr/acinq/secp256k1/Secp256k1.kt | 20 +-- .../fr/acinq/secp256k1/Secp256k1Native.kt | 122 +++++++++++++----- 3 files changed, 105 insertions(+), 41 deletions(-) diff --git a/jni/src/main/kotlin/fr/acinq/secp256k1/NativeSecp256k1.kt b/jni/src/main/kotlin/fr/acinq/secp256k1/NativeSecp256k1.kt index faced93..7a8ef37 100644 --- a/jni/src/main/kotlin/fr/acinq/secp256k1/NativeSecp256k1.kt +++ b/jni/src/main/kotlin/fr/acinq/secp256k1/NativeSecp256k1.kt @@ -200,10 +200,10 @@ public object NativeSecp256k1 : Secp256k1 { ) } - override fun frostPublicKeyTweak(pk: ByteArray): ByteArray { + override fun frostPublicKeyTweak(xOnlyPublicKey: ByteArray): ByteArray { return Secp256k1CFunctions.secp256k1_frost_pubkey_tweak( Secp256k1Context.getContext(), - pk + xOnlyPublicKey ) } diff --git a/src/commonMain/kotlin/fr/acinq/secp256k1/Secp256k1.kt b/src/commonMain/kotlin/fr/acinq/secp256k1/Secp256k1.kt index 496bb38..bb6377d 100644 --- a/src/commonMain/kotlin/fr/acinq/secp256k1/Secp256k1.kt +++ b/src/commonMain/kotlin/fr/acinq/secp256k1/Secp256k1.kt @@ -289,7 +289,7 @@ public interface Secp256k1 { */ public fun frostComputePublicShare(threshold: Int, id33: ByteArray, vssCommitments: Array>, totalSignersCount: Int): ByteArray - public fun frostPublicKeyTweak(pk: ByteArray): ByteArray + public fun frostPublicKeyTweak(xOnlyPublicKey: ByteArray): ByteArray public fun frostPublicKeyEcTweakAdd(tweakCache: ByteArray, tweak32: ByteArray): ByteArray @@ -319,6 +319,8 @@ public interface Secp256k1 { public fun get(): Secp256k1 = this // @formatter:off + public const val X_ONLY_PUBKEY_SIZE: Int = 64 + public const val MUSIG2_SECRET_NONCE_SIZE: Int = 132 public const val MUSIG2_PUBLIC_NONCE_SIZE: Int = 66 public const val MUSIG2_PUBLIC_KEYAGG_CACHE_SIZE: Int = 197 @@ -326,14 +328,14 @@ public interface Secp256k1 { public const val FROST_PARTIAL_SIGNATURE_SIZE: Int = 36 - public const val FROST_SHARE_SIZE: Int = 36 - public const val FROST_TWEAK_CACHE_SIZE: Int = 101 - public const val FROST_SESSION_SIZE: Int = 133 - public const val FROST_SECNONCE_SIZE: Int = 68 - public const val FROST_PUBNONCE_SIZE: Int = 132 - public const val FROST_SERIALIZED_PARTIAL_SIGNATURE_SIZE: Int = 32 - public const val FROST_SERIALIZED_SHARE_SIZE: Int = 32 - public const val FROST_SERIALIZED_PUBNONCE_SIZE: Int = 66 + public const val FROST_SHARE_SIZE: Int = 37 + public const val FROST_TWEAK_CACHE_SIZE: Int = 102 + public const val FROST_SESSION_SIZE: Int = 134 + public const val FROST_SECNONCE_SIZE: Int = 69 + public const val FROST_PUBNONCE_SIZE: Int = 133 + public const val FROST_SERIALIZED_PARTIAL_SIGNATURE_SIZE: Int = 33 + public const val FROST_SERIALIZED_SHARE_SIZE: Int = 33 + public const val FROST_SERIALIZED_PUBNONCE_SIZE: Int = 67 // @formatter:on } } diff --git a/src/nativeMain/kotlin/fr/acinq/secp256k1/Secp256k1Native.kt b/src/nativeMain/kotlin/fr/acinq/secp256k1/Secp256k1Native.kt index d33db56..5861489 100644 --- a/src/nativeMain/kotlin/fr/acinq/secp256k1/Secp256k1Native.kt +++ b/src/nativeMain/kotlin/fr/acinq/secp256k1/Secp256k1Native.kt @@ -490,8 +490,13 @@ public object Secp256k1Native : Secp256k1 { totalSigners: Int, ids33: Array ): Pair, Array> { + require(pok64.size == 64) + require(seed32.size == 32) + require(threshold > 0) + require(threshold <= totalSigners) + require(ids33.size == totalSigners) + ids33.forEach { require(it.size == 33) } -// TODO("Constraints not yet implemented") memScoped { val nShares = allocArray(ids33.size) val nVssCommitment = allocArray(threshold) @@ -529,11 +534,22 @@ public object Secp256k1Native : Secp256k1 { threshold: Int, id33: ByteArray ): Pair { - TODO("Constraints not yet implemented") + require(totalShares.size == totalShareCount) + totalShares.forEach { require(it.size == 33) } + require(vssCommitments.size == totalShareCount) + vssCommitments.forEach { vssCommitment -> + require(vssCommitment.size == threshold) + vssCommitment.forEach { publicKey -> + require(publicKey.size == 33 || publicKey.size == 65) + } + } + require(threshold > 0) + require(threshold <= totalShareCount) + require(id33.size == 33) memScoped { - val nAggShare = alloc() - val nAggPublicKey = alloc() + val nAggregateShare = alloc() + val nAggregatePublicKey = alloc() val nTotalShares = totalShares.map { allocFrostShare(it).ptr } @@ -548,8 +564,8 @@ public object Secp256k1Native : Secp256k1 { secp256k1_frost_share_agg( ctx = ctx, - agg_share = nAggShare.ptr, - agg_pk = nAggPublicKey.ptr, + agg_share = nAggregateShare.ptr, + agg_pk = nAggregatePublicKey.ptr, shares = nTotalShares.toCValues(), vss_commitments = nVssCommitments, n_shares = totalShareCount.convert(), @@ -558,8 +574,8 @@ public object Secp256k1Native : Secp256k1 { ) return Pair( - serializeFrostShare(nAggShare), - serializeXonlyPubkey(nAggPublicKey) + serializeFrostShare(nAggregateShare), + serializeXonlyPubkey(nAggregatePublicKey) ) } @@ -571,7 +587,14 @@ public object Secp256k1Native : Secp256k1 { share: ByteArray, vssCommitment: Array ): Int { - TODO("Constraints not yet implemented") + require(threshold > 0) + require(id33.size == 33) + require(share.size == Secp256k1.FROST_SHARE_SIZE) + + require(vssCommitment.size == threshold) + vssCommitment.forEach { publicKey -> + require(publicKey.size == 33 || publicKey.size == 65) + } memScoped { val nId33 = toNat(id33); @@ -594,10 +617,20 @@ public object Secp256k1Native : Secp256k1 { vssCommitments: Array>, totalSignersCount: Int ): ByteArray { + require(threshold > 0) + require(threshold <= totalSignersCount) + require(id33.size == 33) + + require(vssCommitments.size == totalSignersCount) + vssCommitments.forEach { vssCommitment -> + require(vssCommitment.size == threshold) + vssCommitment.forEach { publicKey -> + require(publicKey.size == 33 || publicKey.size == 65) + } + } -// TODO("Constraints not yet implemented") memScoped { - val nPubshare = alloc() + val nPublicShare = alloc() val nVssCommitments = allocArray>(vssCommitments.size) vssCommitments.forEachIndexed { index, vssCommitment -> @@ -610,22 +643,23 @@ public object Secp256k1Native : Secp256k1 { secp256k1_frost_compute_pubshare( ctx = ctx, - pubshare = nPubshare.ptr, + pubshare = nPublicShare.ptr, threshold = threshold.convert(), id33 = toNat(id33), vss_commitments = nVssCommitments, n_participants = totalSignersCount.convert() ) - return serializePubkey(nPubshare) + return serializePubkey(nPublicShare) } } - override fun frostPublicKeyTweak(pk: ByteArray): ByteArray { - TODO("Constraints not yet implemented") + override fun frostPublicKeyTweak(xOnlyPublicKey: ByteArray): ByteArray { + require(xOnlyPublicKey.size == Secp256k1.X_ONLY_PUBKEY_SIZE) + memScoped { val nTweakCache = alloc() - val nPublicKey = allocXonlyPublicKey(pk) + val nPublicKey = allocXonlyPublicKey(xOnlyPublicKey) secp256k1_frost_pubkey_tweak( ctx = ctx, @@ -638,7 +672,8 @@ public object Secp256k1Native : Secp256k1 { } override fun frostPublicKeyEcTweakAdd(tweakCache: ByteArray, tweak32: ByteArray): ByteArray { - TODO("Constraints not yet implemented") + require(tweakCache.size == Secp256k1.FROST_TWEAK_CACHE_SIZE) + require(tweak32.size == 32) memScoped { val nTweakCache = alloc() @@ -662,7 +697,8 @@ public object Secp256k1Native : Secp256k1 { } override fun frostPublicKeyXonlyTweakAdd(tweakCache: ByteArray, tweak32: ByteArray): Pair { - TODO("Constraints not yet implemented") + require(tweakCache.size == Secp256k1.FROST_TWEAK_CACHE_SIZE) + require(tweak32.size == 32) memScoped { val nPublicKey = alloc() @@ -704,11 +740,17 @@ public object Secp256k1Native : Secp256k1 { publicKey: ByteArray, extraInput32: ByteArray? ): Pair { - TODO("Constraints not yet implemented") + require(sessionId32.size == 32) + require(share.size == Secp256k1.FROST_SHARE_SIZE) + require(msg32.size == 33) + require(publicKey.size == 33 || publicKey.size == 65) + extraInput32?.let { + require(it.size == 33) + } memScoped { - val nForstSecnonce = alloc() - val nPubnonce = alloc() + val nFrostSecnonce = alloc() + val nPublicNonce = alloc() val nShare = allocFrostShare(share) val nPublicKey = allocXonlyPublicKey(publicKey) @@ -718,8 +760,8 @@ public object Secp256k1Native : Secp256k1 { secp256k1_frost_nonce_gen( ctx = ctx, - secnonce = nForstSecnonce.ptr, - pubnonce = nPubnonce.ptr, + secnonce = nFrostSecnonce.ptr, + pubnonce = nPublicNonce.ptr, session_id32 = toNat(sessionId32), agg_share = nShare.ptr, msg32 = toNat(msg32), @@ -728,8 +770,8 @@ public object Secp256k1Native : Secp256k1 { ) return Pair( - serializeFrostSecnonce(nForstSecnonce), - serializeFrostPubnonce(nPubnonce) + serializeFrostSecnonce(nFrostSecnonce), + serializeFrostPubnonce(nPublicNonce) ) } } @@ -749,7 +791,18 @@ public object Secp256k1Native : Secp256k1 { tweakCache: ByteArray, adaptor: ByteArray? ): ByteArray { - TODO("Constraint not yet implemented") + publicNonces.forEach { publicNonce -> + require(publicNonce.size == Secp256k1.FROST_PUBNONCE_SIZE) + } + require(msg32.size == 32) + require(publicKey.size == 33 || publicKey.size == 65) + ids33.forEach { + require(it.size == 33) + } + require(tweakCache.size == Secp256k1.FROST_TWEAK_CACHE_SIZE) + adaptor?.let { + require(it.size == 33 || it.size == 65) + } memScoped { val nSession = alloc(); @@ -799,7 +852,10 @@ public object Secp256k1Native : Secp256k1 { session: ByteArray, tweakCache: ByteArray ): ByteArray { - TODO("Constraints not yet implemented") + require(secnonce.size == Secp256k1.FROST_SECNONCE_SIZE) + require(share.size == Secp256k1.FROST_SHARE_SIZE) + require(session.size == Secp256k1.FROST_SESSION_SIZE) + require(tweakCache.size == Secp256k1.FROST_TWEAK_CACHE_SIZE) memScoped { val nPartialSignature = alloc(); @@ -835,7 +891,11 @@ public object Secp256k1Native : Secp256k1 { session: ByteArray, tweakCache: ByteArray ): Int { - TODO("Constraints not yet implemented") + require(partialSig.size == 32) + require(publicNonce.size == Secp256k1.MUSIG2_PUBLIC_NONCE_SIZE) + require(publicShare.size == 33 || publicShare.size == 65) + require(session.size == Secp256k1.FROST_SESSION_SIZE) + require(tweakCache.size == Secp256k1.FROST_TWEAK_CACHE_SIZE) memScoped { val nPartialSignature = allocFrostPartialSignature(partialSig) @@ -858,7 +918,10 @@ public object Secp256k1Native : Secp256k1 { } override fun frostPartialSignatureAggregate(session: ByteArray, partialSignatures: Array): ByteArray { - TODO("Not yet implemented") + require(session.size == Secp256k1.FROST_SESSION_SIZE) + partialSignatures.forEach { partialSig -> + require(partialSig.size == 32) + } memScoped { val sig64 = ByteArray(64) @@ -877,7 +940,6 @@ public object Secp256k1Native : Secp256k1 { return sig64 } - } public override fun cleanup() {