Cinterop for arrays of pointers

This commit is contained in:
kngako 2024-08-05 22:34:45 +02:00
parent 3c01a2aad4
commit 9e287feb26
4 changed files with 64 additions and 40 deletions

View File

@ -107,13 +107,13 @@ public class Secp256k1CFunctions {
public static native byte[] secp256k1_musig_partial_sig_agg(long ctx, byte[] session, byte[][] psigs); public static native byte[] secp256k1_musig_partial_sig_agg(long ctx, byte[] session, byte[][] psigs);
public static native byte[][] secp256k1_frost_shares_gen(long ctx, byte[][] vss_commitment, byte[] pok64, byte[] seed32, int total_signers, byte[][] ids33); public static native byte[][][] secp256k1_frost_shares_gen(long ctx, byte[] pok64, byte[] seed32, int threshold, int total_signers, byte[][] ids33);
public static native byte[][] secp256k1_frost_share_agg(long ctx, byte[][][] vss_commitments, byte[] id33); public static native byte[][] secp256k1_frost_share_agg(long ctx, byte[][][] vss_commitments, int totalShareCount, int threshold, byte[] id33);
public static native int secp256k1_frost_share_verify(long ctx, byte[] id33, byte[] share, byte[][] vss_commitment); public static native int secp256k1_frost_share_verify(long ctx, byte[] id33, byte[] share, byte[][] vss_commitment);
public static native byte[] secp256k1_frost_compute_pubshare(long ctx, byte[] id33, byte[][][] vss_commitments); public static native byte[] secp256k1_frost_compute_pubshare(long ctx, int threshold, byte[] id33, byte[][][] vss_commitments, int totalSignersCount);
public static native byte[] secp256k1_frost_pubkey_tweak(long ctx, byte[] public_key); public static native byte[] secp256k1_frost_pubkey_tweak(long ctx, byte[] public_key);

View File

@ -130,30 +130,39 @@ public object NativeSecp256k1 : Secp256k1 {
} }
override fun frostSharesGen( override fun frostSharesGen(
vssCommitment: Array<ByteArray>,
pok64: ByteArray, pok64: ByteArray,
seed32: ByteArray, seed32: ByteArray,
threshold: Int,
totalSigners: Int, totalSigners: Int,
ids33: Array<ByteArray> ids33: Array<ByteArray>
): Array<ByteArray> { ): Pair<Array<ByteArray>, Array<ByteArray>> {
return Secp256k1CFunctions.secp256k1_frost_shares_gen( val result = Secp256k1CFunctions.secp256k1_frost_shares_gen(
Secp256k1Context.getContext(), Secp256k1Context.getContext(),
vssCommitment,
pok64, pok64,
seed32, seed32,
threshold,
totalSigners, totalSigners,
ids33 ids33
) )
return Pair(
result[0],
result[1]
)
} }
override fun frostShareAggregate( override fun frostShareAggregate(
totalShares: Array<ByteArray>, totalShares: Array<ByteArray>,
vssCommitments: Array<Array<ByteArray>>, vssCommitments: Array<Array<ByteArray>>,
totalShareCount: Int,
threshold: Int,
id33: ByteArray id33: ByteArray
): Pair<ByteArray, ByteArray> { ): Pair<ByteArray, ByteArray> {
val result = Secp256k1CFunctions.secp256k1_frost_share_agg( val result = Secp256k1CFunctions.secp256k1_frost_share_agg(
Secp256k1Context.getContext(), Secp256k1Context.getContext(),
vssCommitments, vssCommitments,
totalShareCount,
threshold,
id33 id33
) )
return Pair( return Pair(
@ -177,13 +186,17 @@ public object NativeSecp256k1 : Secp256k1 {
} }
override fun frostComputePublicShare( override fun frostComputePublicShare(
threshold: Int,
id33: ByteArray, id33: ByteArray,
vssCommitments: Array<Array<ByteArray>> vssCommitments: Array<Array<ByteArray>>,
totalSignersCount: Int
): ByteArray { ): ByteArray {
return Secp256k1CFunctions.secp256k1_frost_compute_pubshare( return Secp256k1CFunctions.secp256k1_frost_compute_pubshare(
Secp256k1Context.getContext(), Secp256k1Context.getContext(),
threshold,
id33, id33,
vssCommitments vssCommitments,
totalSignersCount
) )
} }

View File

@ -271,14 +271,14 @@ public interface Secp256k1 {
*/ */
public fun musigPartialSigAgg(session: ByteArray, psigs: Array<ByteArray>): ByteArray public fun musigPartialSigAgg(session: ByteArray, psigs: Array<ByteArray>): ByteArray
public fun frostSharesGen(vssCommitment: Array<ByteArray>, pok64: ByteArray, seed32: ByteArray, totalSigners: Int, ids33: Array<ByteArray>): Array<ByteArray> public fun frostSharesGen(pok64: ByteArray, seed32: ByteArray, threshold: Int, totalSigners: Int, ids33: Array<ByteArray>): Pair<Array<ByteArray>,Array<ByteArray>>
/** /**
* *
* total signers is deduced from the size of the totalShares array. * total signers is deduced from the size of the totalShares array.
* threshold is deduced from the vssCommitments (all vssCommitments should have the same length... which is the threshold) * threshold is deduced from the vssCommitments (all vssCommitments should have the same length... which is the threshold)
*/ */
public fun frostShareAggregate(totalShares: Array<ByteArray>, vssCommitments: Array<Array<ByteArray>>, id33: ByteArray): Pair<ByteArray, ByteArray> public fun frostShareAggregate(totalShares: Array<ByteArray>, vssCommitments: Array<Array<ByteArray>>, totalShareCount: Int, threshold: Int, id33: ByteArray): Pair<ByteArray, ByteArray>
public fun frostShareVerify(threshold: Int, id33: ByteArray, share: ByteArray, vssCommitment: Array<ByteArray>): Int public fun frostShareVerify(threshold: Int, id33: ByteArray, share: ByteArray, vssCommitment: Array<ByteArray>): Int
@ -287,7 +287,7 @@ public interface Secp256k1 {
* total signers is deduced from the size of the vssCommitments array. * total signers is deduced from the size of the vssCommitments array.
* threshold is deduced from the vssCommitments (all vssCommitments should have the same length... which is the threshold) * threshold is deduced from the vssCommitments (all vssCommitments should have the same length... which is the threshold)
*/ */
public fun frostComputePublicShare(id33: ByteArray, vssCommitments: Array<Array<ByteArray>>): ByteArray public fun frostComputePublicShare(threshold: Int, id33: ByteArray, vssCommitments: Array<Array<ByteArray>>, totalSignersCount: Int): ByteArray
public fun frostPublicKeyTweak(pk: ByteArray): ByteArray public fun frostPublicKeyTweak(pk: ByteArray): ByteArray

View File

@ -484,27 +484,24 @@ public object Secp256k1Native : Secp256k1 {
} }
override fun frostSharesGen( override fun frostSharesGen(
vssCommitment: Array<ByteArray>,
pok64: ByteArray, pok64: ByteArray,
seed32: ByteArray, seed32: ByteArray,
threshold: Int,
totalSigners: Int, totalSigners: Int,
ids33: Array<ByteArray> ids33: Array<ByteArray>
): Array<ByteArray> { ): Pair<Array<ByteArray>, Array<ByteArray>> {
val threshold = vssCommitment.size
TODO("Constraints not yet implemented") // TODO("Constraints not yet implemented")
memScoped { memScoped {
val nShares = allocArray<secp256k1_frost_share>(ids33.size) val nShares = allocArray<secp256k1_frost_share>(ids33.size)
val nVssCommitment = allocArray<secp256k1_pubkey>(threshold)
val nVssCommitment = vssCommitment.map {
allocPublicKey(it).ptr
}
val nIds33s = ids33.map { toNat(it) } val nIds33s = ids33.map { toNat(it) }
secp256k1_frost_shares_gen( secp256k1_frost_shares_gen(
ctx = ctx, ctx = ctx,
shares = nShares, shares = nShares,
vss_commitment = nVssCommitment.toCValues(), vss_commitment = nVssCommitment,
pok64 = toNat(pok64), pok64 = toNat(pok64),
seed32 = toNat(seed32), seed32 = toNat(seed32),
threshold = threshold.convert(), threshold = threshold.convert(),
@ -512,9 +509,11 @@ public object Secp256k1Native : Secp256k1 {
ids33 = nIds33s.toCValues() ids33 = nIds33s.toCValues()
) )
// TODO: return serialized nShares return Pair(
ids33.indices.map { serializeFrostShare(nShares[it]) }.toTypedArray(),
(0 until threshold).map { serializePubkey(nVssCommitment[it]) }.toTypedArray()
)
} }
} }
private fun MemScope.serializeFrostShare(nFrostShare: secp256k1_frost_share): ByteArray { private fun MemScope.serializeFrostShare(nFrostShare: secp256k1_frost_share): ByteArray {
@ -526,11 +525,10 @@ public object Secp256k1Native : Secp256k1 {
override fun frostShareAggregate( override fun frostShareAggregate(
totalShares: Array<ByteArray>, totalShares: Array<ByteArray>,
vssCommitments: Array<Array<ByteArray>>, vssCommitments: Array<Array<ByteArray>>,
totalShareCount: Int,
threshold: Int,
id33: ByteArray id33: ByteArray
): Pair<ByteArray, ByteArray> { ): Pair<ByteArray, ByteArray> {
val threshold = vssCommitments.first().size
val totalShareCount = totalShares.size
TODO("Constraints not yet implemented") TODO("Constraints not yet implemented")
memScoped { memScoped {
@ -538,10 +536,14 @@ public object Secp256k1Native : Secp256k1 {
val nAggPublicKey = alloc<secp256k1_xonly_pubkey>() val nAggPublicKey = alloc<secp256k1_xonly_pubkey>()
val nTotalShares = totalShares.map { allocFrostShare(it).ptr } val nTotalShares = totalShares.map { allocFrostShare(it).ptr }
val nVssCommitments = vssCommitments.map { vssCommitment ->
vssCommitment.map { val nVssCommitments = allocArray<CPointerVar<secp256k1_pubkey>>(vssCommitments.size)
allocPublicKey(it).ptr vssCommitments.forEachIndexed { index, vssCommitment ->
}.toCValues() nVssCommitments[index] = allocArrayOf(
vssCommitment.map { bytes ->
allocPublicKey(bytes).ptr
}
).reinterpret()
} }
secp256k1_frost_share_agg( secp256k1_frost_share_agg(
@ -549,7 +551,7 @@ public object Secp256k1Native : Secp256k1 {
agg_share = nAggShare.ptr, agg_share = nAggShare.ptr,
agg_pk = nAggPublicKey.ptr, agg_pk = nAggPublicKey.ptr,
shares = nTotalShares.toCValues(), shares = nTotalShares.toCValues(),
vss_commitments = nVssCommitments.toTypedArray(), vss_commitments = nVssCommitments,
n_shares = totalShareCount.convert(), n_shares = totalShareCount.convert(),
threshold = threshold.convert(), threshold = threshold.convert(),
id33 = toNat(id33) id33 = toNat(id33)
@ -572,38 +574,47 @@ public object Secp256k1Native : Secp256k1 {
TODO("Constraints not yet implemented") TODO("Constraints not yet implemented")
memScoped { memScoped {
val nId33 = toNat(id33); val nId33 = toNat(id33);
val nFrostShare = allocFrostShare(share) val nFrostShare = allocFrostShare(share)
val nPubkeys = vssCommitment.map { allocPublicKey(it).ptr } val nVssCommitment = vssCommitment.map { allocPublicKey(it).ptr }
return secp256k1_frost_share_verify( return secp256k1_frost_share_verify(
ctx = ctx, ctx = ctx,
threshold = threshold.convert(), threshold = threshold.convert(),
id33 = nId33, id33 = nId33,
share = nFrostShare.ptr, share = nFrostShare.ptr,
vss_commitment = nPubkeys.toCValues() vss_commitment = nVssCommitment.toCValues()
) )
} }
} }
override fun frostComputePublicShare(id33: ByteArray, vssCommitments: Array<Array<ByteArray>>): ByteArray { override fun frostComputePublicShare(
threshold: Int,
id33: ByteArray,
vssCommitments: Array<Array<ByteArray>>,
totalSignersCount: Int
): ByteArray {
TODO("Constraints not yet implemented") // TODO("Constraints not yet implemented")
memScoped { memScoped {
val nPubshare = alloc<secp256k1_pubkey>() val nPubshare = alloc<secp256k1_pubkey>()
val totalSigners = vssCommitments.size
val threshold = vssCommitments.first().size val nVssCommitments = allocArray<CPointerVar<secp256k1_pubkey>>(vssCommitments.size)
val nVssCommitments = vssCommitments.map { vssCommitment -> vssCommitments.forEachIndexed { index, vssCommitment ->
vssCommitment.map { allocPublicKey(it).ptr } nVssCommitments[index] = allocArrayOf(
vssCommitment.map { bytes ->
allocPublicKey(bytes).ptr
}
).reinterpret()
} }
secp256k1_frost_compute_pubshare( secp256k1_frost_compute_pubshare(
ctx = ctx, ctx = ctx,
pubshare = nPubshare.ptr, pubshare = nPubshare.ptr,
threshold = threshold.convert(), threshold = threshold.convert(),
id33 = toNat(id33), id33 = toNat(id33),
vss_commitments = nVssCommitments, vss_commitments = nVssCommitments,
n_participants = totalSigners.convert() n_participants = totalSignersCount.convert()
) )
return serializePubkey(nPubshare) return serializePubkey(nPubshare)