Use frost in Secp256k1 native logic
This commit is contained in:
parent
4826863644
commit
3c01a2aad4
3
.gitignore
vendored
3
.gitignore
vendored
@ -14,4 +14,5 @@ local.properties
|
||||
# OS
|
||||
.DS_Store
|
||||
jni/bin/*
|
||||
jni/jvm/bin/*
|
||||
jni/jvm/bin/*
|
||||
/jni/src/main/java/fr/acinq/secp256k1/Secp256k1CFunctions.class
|
||||
|
@ -267,6 +267,102 @@ JNIEXPORT jint JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1mu
|
||||
JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1musig_1partial_1sig_1agg
|
||||
(JNIEnv *, jclass, jlong, jbyteArray, jobjectArray);
|
||||
|
||||
/*
|
||||
* Class: fr_acinq_secp256k1_Secp256k1CFunctions
|
||||
* Method: secp256k1_frost_shares_gen
|
||||
* Signature: (J[[B[B[BI[[B)[[B
|
||||
*/
|
||||
JNIEXPORT jobjectArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1frost_1shares_1gen
|
||||
(JNIEnv *, jclass, jlong, jobjectArray, jbyteArray, jbyteArray, jint, jobjectArray);
|
||||
|
||||
/*
|
||||
* Class: fr_acinq_secp256k1_Secp256k1CFunctions
|
||||
* Method: secp256k1_frost_share_agg
|
||||
* Signature: (J[[[B[B)[[B
|
||||
*/
|
||||
JNIEXPORT jobjectArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1frost_1share_1agg
|
||||
(JNIEnv *, jclass, jlong, jobjectArray, jbyteArray);
|
||||
|
||||
/*
|
||||
* Class: fr_acinq_secp256k1_Secp256k1CFunctions
|
||||
* Method: secp256k1_frost_share_verify
|
||||
* Signature: (J[B[B[[B)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1frost_1share_1verify
|
||||
(JNIEnv *, jclass, jlong, jbyteArray, jbyteArray, jobjectArray);
|
||||
|
||||
/*
|
||||
* Class: fr_acinq_secp256k1_Secp256k1CFunctions
|
||||
* Method: secp256k1_frost_compute_pubshare
|
||||
* Signature: (J[B[[[B)[B
|
||||
*/
|
||||
JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1frost_1compute_1pubshare
|
||||
(JNIEnv *, jclass, jlong, jbyteArray, jobjectArray);
|
||||
|
||||
/*
|
||||
* Class: fr_acinq_secp256k1_Secp256k1CFunctions
|
||||
* Method: secp256k1_frost_pubkey_tweak
|
||||
* Signature: (J[B)[B
|
||||
*/
|
||||
JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1frost_1pubkey_1tweak
|
||||
(JNIEnv *, jclass, jlong, jbyteArray);
|
||||
|
||||
/*
|
||||
* Class: fr_acinq_secp256k1_Secp256k1CFunctions
|
||||
* Method: secp256k1_frost_pubkey_ec_tweak_add
|
||||
* Signature: (J[B)[B
|
||||
*/
|
||||
JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1frost_1pubkey_1ec_1tweak_1add
|
||||
(JNIEnv *, jclass, jlong, jbyteArray);
|
||||
|
||||
/*
|
||||
* Class: fr_acinq_secp256k1_Secp256k1CFunctions
|
||||
* Method: secp256k1_frost_pubkey_xonly_tweak_add
|
||||
* Signature: (J[B)[[B
|
||||
*/
|
||||
JNIEXPORT jobjectArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1frost_1pubkey_1xonly_1tweak_1add
|
||||
(JNIEnv *, jclass, jlong, jbyteArray);
|
||||
|
||||
/*
|
||||
* Class: fr_acinq_secp256k1_Secp256k1CFunctions
|
||||
* Method: secp256k1_frost_nonce_gen
|
||||
* Signature: (J[B[B[B[B[B)[[B
|
||||
*/
|
||||
JNIEXPORT jobjectArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1frost_1nonce_1gen
|
||||
(JNIEnv *, jclass, jlong, jbyteArray, jbyteArray, jbyteArray, jbyteArray, jbyteArray);
|
||||
|
||||
/*
|
||||
* Class: fr_acinq_secp256k1_Secp256k1CFunctions
|
||||
* Method: secp256k1_frost_nonce_process
|
||||
* Signature: (J[[B[B[B[B[[B[B[B)[B
|
||||
*/
|
||||
JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1frost_1nonce_1process
|
||||
(JNIEnv *, jclass, jlong, jobjectArray, jbyteArray, jbyteArray, jbyteArray, jobjectArray, jbyteArray, jbyteArray);
|
||||
|
||||
/*
|
||||
* Class: fr_acinq_secp256k1_Secp256k1CFunctions
|
||||
* Method: secp256k1_frost_partial_sign
|
||||
* Signature: (J[B[B[B[B)[B
|
||||
*/
|
||||
JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1frost_1partial_1sign
|
||||
(JNIEnv *, jclass, jlong, jbyteArray, jbyteArray, jbyteArray, jbyteArray);
|
||||
|
||||
/*
|
||||
* Class: fr_acinq_secp256k1_Secp256k1CFunctions
|
||||
* Method: secp256k1_frost_partial_sig_verify
|
||||
* Signature: (J[B[B[B[B[B)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1frost_1partial_1sig_1verify
|
||||
(JNIEnv *, jclass, jlong, jbyteArray, jbyteArray, jbyteArray, jbyteArray, jbyteArray);
|
||||
|
||||
/*
|
||||
* Class: fr_acinq_secp256k1_Secp256k1CFunctions
|
||||
* Method: secp256k1_frost_partial_sig_aggregate
|
||||
* Signature: (J[B[[B)[B
|
||||
*/
|
||||
JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1frost_1partial_1sig_1aggregate
|
||||
(JNIEnv *, jclass, jlong, jbyteArray, jobjectArray);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "include/secp256k1_recovery.h"
|
||||
#include "include/secp256k1_schnorrsig.h"
|
||||
#include "include/secp256k1_musig.h"
|
||||
#include "include/secp256k1_frost.h"
|
||||
#include "fr_acinq_secp256k1_Secp256k1CFunctions.h"
|
||||
|
||||
#define SIG_FORMAT_UNKNOWN 0
|
||||
@ -1336,3 +1337,14 @@ JNIEXPORT jbyteArray JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256
|
||||
copy_bytes_to_java(penv, jpsig, 64, sig64);
|
||||
return jpsig;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: fr_acinq_secp256k1_Secp256k1CFunctions
|
||||
* Method: secp256k1_frost_share_verify
|
||||
* Signature: (J[B[B[[B)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_fr_acinq_secp256k1_Secp256k1CFunctions_secp256k1_1frost_1share_1verify
|
||||
(JNIEnv *, jclass, jlong, jbyteArray, jbyteArray, jobjectArray)
|
||||
{
|
||||
return 0;
|
||||
}
|
@ -106,4 +106,29 @@ public class Secp256k1CFunctions {
|
||||
public static native int secp256k1_musig_partial_sig_verify(long ctx, byte[] psig, byte[] pubnonce, byte[] pubkey, byte[] keyagg_cache, byte[] session);
|
||||
|
||||
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_share_agg(long ctx, byte[][][] vss_commitments, byte[] id33);
|
||||
|
||||
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_pubkey_tweak(long ctx, byte[] public_key);
|
||||
|
||||
public static native byte[] secp256k1_frost_pubkey_ec_tweak_add(long ctx, byte[] tweakCache, byte[] tweak32);
|
||||
|
||||
public static native byte[][] secp256k1_frost_pubkey_xonly_tweak_add(long ctx, byte[] tweakCache, byte[] tweak32);
|
||||
|
||||
public static native byte[][] secp256k1_frost_nonce_gen(long ctx, byte[] sessionId32, byte[] share, byte[] msg32, byte[] publicKey, byte[] extraInput32);
|
||||
|
||||
public static native byte[] secp256k1_frost_nonce_process(long ctx, byte[][] pubnonces, byte[] msg32, byte[] publicKey, byte[] id33, byte[][] ids33, byte[] tweakCache, byte[] adaptor);
|
||||
|
||||
public static native byte[] secp256k1_frost_partial_sign(long ctx, byte[] secnonce, byte[] share, byte[] session, byte[] tweak_cache);
|
||||
|
||||
public static native int secp256k1_frost_partial_sig_verify(long ctx, byte[] partialSig, byte[] publicNonce, byte[] publicShare, byte[] session, byte[] tweakCache);
|
||||
|
||||
public static native byte[] secp256k1_frost_partial_sig_aggregate(long ctx, byte[] session, byte[][] partialSignatures);
|
||||
|
||||
}
|
||||
|
@ -129,6 +129,175 @@ public object NativeSecp256k1 : Secp256k1 {
|
||||
return Secp256k1CFunctions.secp256k1_musig_partial_sig_agg(Secp256k1Context.getContext(), session, psigs)
|
||||
}
|
||||
|
||||
override fun frostSharesGen(
|
||||
vssCommitment: Array<ByteArray>,
|
||||
pok64: ByteArray,
|
||||
seed32: ByteArray,
|
||||
totalSigners: Int,
|
||||
ids33: Array<ByteArray>
|
||||
): Array<ByteArray> {
|
||||
return Secp256k1CFunctions.secp256k1_frost_shares_gen(
|
||||
Secp256k1Context.getContext(),
|
||||
vssCommitment,
|
||||
pok64,
|
||||
seed32,
|
||||
totalSigners,
|
||||
ids33
|
||||
)
|
||||
}
|
||||
|
||||
override fun frostShareAggregate(
|
||||
totalShares: Array<ByteArray>,
|
||||
vssCommitments: Array<Array<ByteArray>>,
|
||||
id33: ByteArray
|
||||
): Pair<ByteArray, ByteArray> {
|
||||
val result = Secp256k1CFunctions.secp256k1_frost_share_agg(
|
||||
Secp256k1Context.getContext(),
|
||||
vssCommitments,
|
||||
id33
|
||||
)
|
||||
return Pair(
|
||||
result[0], // agg_share
|
||||
result[1] // agg_pk
|
||||
)
|
||||
}
|
||||
|
||||
override fun frostShareVerify(
|
||||
threshold: Int,
|
||||
id33: ByteArray,
|
||||
share: ByteArray,
|
||||
vssCommitment: Array<ByteArray>
|
||||
): Int {
|
||||
return Secp256k1CFunctions.secp256k1_frost_share_verify(
|
||||
Secp256k1Context.getContext(),
|
||||
id33,
|
||||
share,
|
||||
vssCommitment
|
||||
)
|
||||
}
|
||||
|
||||
override fun frostComputePublicShare(
|
||||
id33: ByteArray,
|
||||
vssCommitments: Array<Array<ByteArray>>
|
||||
): ByteArray {
|
||||
return Secp256k1CFunctions.secp256k1_frost_compute_pubshare(
|
||||
Secp256k1Context.getContext(),
|
||||
id33,
|
||||
vssCommitments
|
||||
)
|
||||
}
|
||||
|
||||
override fun frostPublicKeyTweak(pk: ByteArray): ByteArray {
|
||||
return Secp256k1CFunctions.secp256k1_frost_pubkey_tweak(
|
||||
Secp256k1Context.getContext(),
|
||||
pk
|
||||
)
|
||||
}
|
||||
|
||||
override fun frostPublicKeyEcTweakAdd(tweakCache: ByteArray, tweak32: ByteArray): ByteArray {
|
||||
return Secp256k1CFunctions.secp256k1_frost_pubkey_ec_tweak_add(
|
||||
Secp256k1Context.getContext(),
|
||||
tweakCache,
|
||||
tweak32
|
||||
)
|
||||
}
|
||||
|
||||
override fun frostPublicKeyXonlyTweakAdd(tweakCache: ByteArray, tweak32: ByteArray): Pair<ByteArray, ByteArray> {
|
||||
val result = Secp256k1CFunctions.secp256k1_frost_pubkey_xonly_tweak_add(
|
||||
Secp256k1Context.getContext(),
|
||||
tweakCache,
|
||||
tweak32
|
||||
)
|
||||
|
||||
return Pair(
|
||||
result[0], // output_pubkey
|
||||
result[1] // tweak_cache
|
||||
)
|
||||
}
|
||||
|
||||
override fun frostNonceGen(
|
||||
sessionId32: ByteArray,
|
||||
share: ByteArray,
|
||||
msg32: ByteArray,
|
||||
publicKey: ByteArray,
|
||||
extraInput32: ByteArray?
|
||||
): Pair<ByteArray, ByteArray> {
|
||||
val result = Secp256k1CFunctions.secp256k1_frost_nonce_gen(
|
||||
Secp256k1Context.getContext(),
|
||||
sessionId32,
|
||||
share,
|
||||
msg32,
|
||||
publicKey,
|
||||
extraInput32
|
||||
)
|
||||
|
||||
return Pair(
|
||||
result[0], // secnonce
|
||||
result[1] // pubnonce
|
||||
)
|
||||
}
|
||||
|
||||
override fun frostNonceProcess(
|
||||
publicNonces: Array<ByteArray>,
|
||||
msg32: ByteArray,
|
||||
publicKey: ByteArray,
|
||||
id33: ByteArray,
|
||||
ids33: Array<ByteArray>,
|
||||
tweakCache: ByteArray,
|
||||
adaptor: ByteArray?
|
||||
): ByteArray {
|
||||
return Secp256k1CFunctions.secp256k1_frost_nonce_process(
|
||||
Secp256k1Context.getContext(),
|
||||
publicNonces,
|
||||
msg32,
|
||||
publicKey,
|
||||
id33,
|
||||
ids33,
|
||||
tweakCache,
|
||||
adaptor
|
||||
)
|
||||
}
|
||||
|
||||
override fun frostPartialSign(
|
||||
secnonce: ByteArray,
|
||||
share: ByteArray,
|
||||
session: ByteArray,
|
||||
tweakCache: ByteArray
|
||||
): ByteArray {
|
||||
return Secp256k1CFunctions.secp256k1_frost_partial_sign(
|
||||
Secp256k1Context.getContext(),
|
||||
secnonce,
|
||||
share,
|
||||
session,
|
||||
tweakCache
|
||||
)
|
||||
}
|
||||
|
||||
override fun frostPartialSignatureVerify(
|
||||
partialSig: ByteArray,
|
||||
publicNonce: ByteArray,
|
||||
publicShare: ByteArray,
|
||||
session: ByteArray,
|
||||
tweakCache: ByteArray
|
||||
): Int {
|
||||
return Secp256k1CFunctions.secp256k1_frost_partial_sig_verify(
|
||||
Secp256k1Context.getContext(),
|
||||
partialSig,
|
||||
publicNonce,
|
||||
publicShare,
|
||||
session,
|
||||
tweakCache
|
||||
)
|
||||
}
|
||||
|
||||
override fun frostPartialSignatureAggregate(session: ByteArray, partialSignatures: Array<ByteArray>): ByteArray {
|
||||
return Secp256k1CFunctions.secp256k1_frost_partial_sig_aggregate(
|
||||
Secp256k1Context.getContext(),
|
||||
session,
|
||||
partialSignatures
|
||||
)
|
||||
}
|
||||
|
||||
override fun cleanup() {
|
||||
return Secp256k1CFunctions.secp256k1_context_destroy(Secp256k1Context.getContext())
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ export STRIP=$ANDROID_NDK/toolchains/llvm/prebuilt/$TOOLCHAIN/bin/llvm-strip
|
||||
cd secp256k1
|
||||
|
||||
./autogen.sh
|
||||
./configure CFLAGS=-fpic --host=$TARGET --enable-experimental --enable-module_ecdh --enable-module-recovery --enable-module-schnorrsig --enable-module-musig --enable-benchmark=no --enable-shared=no --enable-exhaustive-tests=no --enable-tests=no
|
||||
./configure CFLAGS=-fpic --host=$TARGET --enable-experimental --enable-module_ecdh --enable-module-recovery --enable-module-schnorrsig --enable-module-musig --enable-module-frost --enable-benchmark=no --enable-shared=no --enable-exhaustive-tests=no --enable-tests=no
|
||||
make clean
|
||||
make
|
||||
|
||||
|
@ -6,7 +6,7 @@ cp xconfigure.sh secp256k1
|
||||
cd secp256k1
|
||||
|
||||
./autogen.sh
|
||||
sh xconfigure.sh --enable-experimental --enable-module_ecdh --enable-module-recovery --enable-module-schnorrsig --enable-module-musig --enable-benchmark=no --enable-shared=no --enable-exhaustive-tests=no --enable-tests=no
|
||||
sh xconfigure.sh --enable-experimental --enable-module_ecdh --enable-module-recovery --enable-module-schnorrsig --enable-module-musig --enable-module-frost --enable-benchmark=no --enable-shared=no --enable-exhaustive-tests=no --enable-tests=no
|
||||
|
||||
mkdir -p ../build/ios
|
||||
cp -v _build/universal/ios/* ../build/ios/
|
||||
|
@ -25,7 +25,7 @@ else
|
||||
fi
|
||||
|
||||
./autogen.sh
|
||||
CFLAGS="$CFLAGS" LDFLAGS="$LDFLAGS" ./configure $CONF_OPTS --enable-experimental --enable-module_ecdh --enable-module-recovery --enable-module-schnorrsig --enable-module-musig --enable-benchmark=no --enable-shared=no --enable-exhaustive-tests=no --enable-tests=no
|
||||
CFLAGS="$CFLAGS" LDFLAGS="$LDFLAGS" ./configure $CONF_OPTS --enable-experimental --enable-module_ecdh --enable-module-recovery --enable-module-schnorrsig --enable-module-musig --enable-module-frost --enable-benchmark=no --enable-shared=no --enable-exhaustive-tests=no --enable-tests=no
|
||||
make clean
|
||||
make
|
||||
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit df0bdeb09654ecedc7766dff700719959cf960cb
|
||||
Subproject commit ac7967d79c0d69fd17aed5107481d2c5d9998cf8
|
@ -271,6 +271,44 @@ public interface Secp256k1 {
|
||||
*/
|
||||
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>
|
||||
|
||||
/**
|
||||
*
|
||||
* 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)
|
||||
*/
|
||||
public fun frostShareAggregate(totalShares: Array<ByteArray>, vssCommitments: Array<Array<ByteArray>>, id33: ByteArray): Pair<ByteArray, ByteArray>
|
||||
|
||||
public fun frostShareVerify(threshold: Int, id33: ByteArray, share: ByteArray, vssCommitment: Array<ByteArray>): Int
|
||||
|
||||
/**
|
||||
*
|
||||
* 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)
|
||||
*/
|
||||
public fun frostComputePublicShare(id33: ByteArray, vssCommitments: Array<Array<ByteArray>>): ByteArray
|
||||
|
||||
public fun frostPublicKeyTweak(pk: ByteArray): ByteArray
|
||||
|
||||
public fun frostPublicKeyEcTweakAdd(tweakCache: ByteArray, tweak32: ByteArray): ByteArray
|
||||
|
||||
public fun frostPublicKeyXonlyTweakAdd(tweakCache: ByteArray, tweak32: ByteArray): Pair<ByteArray, ByteArray>
|
||||
|
||||
public fun frostNonceGen(sessionId32: ByteArray, share: ByteArray, msg32: ByteArray, publicKey: ByteArray, extraInput32: ByteArray?): Pair<ByteArray, ByteArray>
|
||||
|
||||
/**
|
||||
*
|
||||
* threshold can be deduced from the size of the pubnonces array.
|
||||
*/
|
||||
public fun frostNonceProcess(publicNonces: Array<ByteArray>, msg32: ByteArray, publicKey: ByteArray, id33: ByteArray, ids33: Array<ByteArray>, tweakCache: ByteArray, adaptor: ByteArray?): ByteArray
|
||||
|
||||
public fun frostPartialSign(secnonce: ByteArray, share: ByteArray, session: ByteArray, tweakCache: ByteArray): ByteArray
|
||||
|
||||
public fun frostPartialSignatureVerify(partialSig: ByteArray, publicNonce: ByteArray, publicShare: ByteArray, session: ByteArray, tweakCache: ByteArray): Int
|
||||
|
||||
public fun frostPartialSignatureAggregate(session: ByteArray, partialSignatures: Array<ByteArray>): ByteArray
|
||||
|
||||
/**
|
||||
* Delete the secp256k1 context from dynamic memory.
|
||||
*/
|
||||
@ -285,6 +323,17 @@ public interface Secp256k1 {
|
||||
public const val MUSIG2_PUBLIC_NONCE_SIZE: Int = 66
|
||||
public const val MUSIG2_PUBLIC_KEYAGG_CACHE_SIZE: Int = 197
|
||||
public const val MUSIG2_PUBLIC_SESSION_SIZE: Int = 133
|
||||
|
||||
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
|
||||
// @formatter:on
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
package = secp256k1
|
||||
|
||||
headers = secp256k1.h secp256k1_ecdh.h secp256k1_recovery.h secp256k1_extrakeys.h secp256k1_schnorrsig.h secp256k1_musig.h
|
||||
headerFilter = secp256k1/** secp256k1_ecdh.h secp256k1_recovery.h secp256k1_extrakeys.h secp256k1_schnorrsig.h secp256k1_musig.h secp256k1.h
|
||||
headers = secp256k1.h secp256k1_ecdh.h secp256k1_recovery.h secp256k1_extrakeys.h secp256k1_schnorrsig.h secp256k1_musig.h secp256k1_frost.h
|
||||
headerFilter = secp256k1/** secp256k1_ecdh.h secp256k1_recovery.h secp256k1_extrakeys.h secp256k1_schnorrsig.h secp256k1_musig.h secp256k1_frost.h secp256k1.h
|
||||
|
||||
staticLibraries.linux = libsecp256k1.a
|
||||
libraryPaths.linux = c/secp256k1/build/linux/ native/build/linux/ native/build/darwin/
|
||||
|
@ -1,6 +1,7 @@
|
||||
package fr.acinq.secp256k1
|
||||
|
||||
import kotlinx.cinterop.*
|
||||
import kotlinx.cinterop.ptr
|
||||
import platform.posix.memcpy
|
||||
import platform.posix.size_tVar
|
||||
import secp256k1.*
|
||||
@ -41,6 +42,13 @@ public object Secp256k1Native : Secp256k1 {
|
||||
return pub
|
||||
}
|
||||
|
||||
private fun MemScope.allocXonlyPublicKey(pubkey: ByteArray): secp256k1_xonly_pubkey {
|
||||
val natPub = toNat(pubkey)
|
||||
val pub = alloc<secp256k1_xonly_pubkey>()
|
||||
secp256k1_xonly_pubkey_parse(ctx, pub.ptr, natPub).requireSuccess("secp256k1_xonly_pubkey_parse() failed")
|
||||
return pub
|
||||
}
|
||||
|
||||
private fun MemScope.allocPublicNonce(pubnonce: ByteArray): secp256k1_musig_pubnonce {
|
||||
val nat = toNat(pubnonce)
|
||||
val nPubnonce = alloc<secp256k1_musig_pubnonce>()
|
||||
@ -454,6 +462,413 @@ public object Secp256k1Native : Secp256k1 {
|
||||
}
|
||||
}
|
||||
|
||||
private fun MemScope.allocFrostShare(share: ByteArray): secp256k1_frost_share {
|
||||
val nat = toNat(share)
|
||||
val nFrostShare = alloc<secp256k1_frost_share>()
|
||||
secp256k1_frost_share_parse(ctx, nFrostShare.ptr, nat).requireSuccess("secp256k1_frost_share_parse() failed")
|
||||
return nFrostShare
|
||||
}
|
||||
|
||||
private fun MemScope.allocFrostPartialSignature(partialSignature: ByteArray): secp256k1_frost_partial_sig {
|
||||
val nat = toNat(partialSignature)
|
||||
val nPartialSignature = alloc<secp256k1_frost_partial_sig>()
|
||||
secp256k1_frost_partial_sig_parse(ctx, nPartialSignature.ptr, nat).requireSuccess("secp256k1_frost_partial_sig_parse() failed")
|
||||
return nPartialSignature
|
||||
}
|
||||
|
||||
private fun MemScope.allocFrostPublicNonce(pubnonce: ByteArray): secp256k1_frost_pubnonce {
|
||||
val nat = toNat(pubnonce)
|
||||
val nPublicNonce = alloc<secp256k1_frost_pubnonce>()
|
||||
secp256k1_frost_pubnonce_parse(ctx, nPublicNonce.ptr, nat).requireSuccess("secp256k1_frost_pubnonce_parse() failed")
|
||||
return nPublicNonce
|
||||
}
|
||||
|
||||
override fun frostSharesGen(
|
||||
vssCommitment: Array<ByteArray>,
|
||||
pok64: ByteArray,
|
||||
seed32: ByteArray,
|
||||
totalSigners: Int,
|
||||
ids33: Array<ByteArray>
|
||||
): Array<ByteArray> {
|
||||
val threshold = vssCommitment.size
|
||||
|
||||
TODO("Constraints not yet implemented")
|
||||
memScoped {
|
||||
val nShares = allocArray<secp256k1_frost_share>(ids33.size)
|
||||
|
||||
val nVssCommitment = vssCommitment.map {
|
||||
allocPublicKey(it).ptr
|
||||
}
|
||||
val nIds33s = ids33.map { toNat(it) }
|
||||
|
||||
secp256k1_frost_shares_gen(
|
||||
ctx = ctx,
|
||||
shares = nShares,
|
||||
vss_commitment = nVssCommitment.toCValues(),
|
||||
pok64 = toNat(pok64),
|
||||
seed32 = toNat(seed32),
|
||||
threshold = threshold.convert(),
|
||||
n_participants = ids33.size.convert(),
|
||||
ids33 = nIds33s.toCValues()
|
||||
)
|
||||
|
||||
// TODO: return serialized nShares
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private fun MemScope.serializeFrostShare(nFrostShare: secp256k1_frost_share): ByteArray {
|
||||
val natOutput = allocArray<UByteVar>(Secp256k1.FROST_SHARE_SIZE)
|
||||
secp256k1_frost_share_serialize(ctx, natOutput, nFrostShare.ptr).requireSuccess("secp256k1_frost_share_serialize() failed")
|
||||
return natOutput.readBytes(Secp256k1.FROST_SERIALIZED_SHARE_SIZE)
|
||||
}
|
||||
|
||||
override fun frostShareAggregate(
|
||||
totalShares: Array<ByteArray>,
|
||||
vssCommitments: Array<Array<ByteArray>>,
|
||||
id33: ByteArray
|
||||
): Pair<ByteArray, ByteArray> {
|
||||
val threshold = vssCommitments.first().size
|
||||
val totalShareCount = totalShares.size
|
||||
|
||||
TODO("Constraints not yet implemented")
|
||||
|
||||
memScoped {
|
||||
val nAggShare = alloc<secp256k1_frost_share>()
|
||||
val nAggPublicKey = alloc<secp256k1_xonly_pubkey>()
|
||||
|
||||
val nTotalShares = totalShares.map { allocFrostShare(it).ptr }
|
||||
val nVssCommitments = vssCommitments.map { vssCommitment ->
|
||||
vssCommitment.map {
|
||||
allocPublicKey(it).ptr
|
||||
}.toCValues()
|
||||
}
|
||||
|
||||
secp256k1_frost_share_agg(
|
||||
ctx = ctx,
|
||||
agg_share = nAggShare.ptr,
|
||||
agg_pk = nAggPublicKey.ptr,
|
||||
shares = nTotalShares.toCValues(),
|
||||
vss_commitments = nVssCommitments.toTypedArray(),
|
||||
n_shares = totalShareCount.convert(),
|
||||
threshold = threshold.convert(),
|
||||
id33 = toNat(id33)
|
||||
)
|
||||
|
||||
return Pair(
|
||||
serializeFrostShare(nAggShare),
|
||||
serializeXonlyPubkey(nAggPublicKey)
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun frostShareVerify(
|
||||
threshold: Int,
|
||||
id33: ByteArray,
|
||||
share: ByteArray,
|
||||
vssCommitment: Array<ByteArray>
|
||||
): Int {
|
||||
TODO("Constraints not yet implemented")
|
||||
|
||||
memScoped {
|
||||
|
||||
val nId33 = toNat(id33);
|
||||
val nFrostShare = allocFrostShare(share)
|
||||
val nPubkeys = vssCommitment.map { allocPublicKey(it).ptr }
|
||||
|
||||
return secp256k1_frost_share_verify(
|
||||
ctx = ctx,
|
||||
threshold = threshold.convert(),
|
||||
id33 = nId33,
|
||||
share = nFrostShare.ptr,
|
||||
vss_commitment = nPubkeys.toCValues()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun frostComputePublicShare(id33: ByteArray, vssCommitments: Array<Array<ByteArray>>): ByteArray {
|
||||
|
||||
TODO("Constraints not yet implemented")
|
||||
memScoped {
|
||||
val nPubshare = alloc<secp256k1_pubkey>()
|
||||
val totalSigners = vssCommitments.size
|
||||
val threshold = vssCommitments.first().size
|
||||
val nVssCommitments = vssCommitments.map { vssCommitment ->
|
||||
vssCommitment.map { allocPublicKey(it).ptr }
|
||||
}
|
||||
secp256k1_frost_compute_pubshare(
|
||||
ctx = ctx,
|
||||
pubshare = nPubshare.ptr,
|
||||
threshold = threshold.convert(),
|
||||
id33 = toNat(id33),
|
||||
vss_commitments = nVssCommitments,
|
||||
n_participants = totalSigners.convert()
|
||||
)
|
||||
|
||||
return serializePubkey(nPubshare)
|
||||
}
|
||||
}
|
||||
|
||||
override fun frostPublicKeyTweak(pk: ByteArray): ByteArray {
|
||||
TODO("Constraints not yet implemented")
|
||||
memScoped {
|
||||
val nTweakCache = alloc<secp256k1_frost_tweak_cache>()
|
||||
val nPublicKey = allocXonlyPublicKey(pk)
|
||||
|
||||
secp256k1_frost_pubkey_tweak(
|
||||
ctx = ctx,
|
||||
tweak_cache = nTweakCache.ptr,
|
||||
agg_pk = nPublicKey.ptr
|
||||
)
|
||||
|
||||
return serializeFrostTweakCache(nTweakCache)
|
||||
}
|
||||
}
|
||||
|
||||
override fun frostPublicKeyEcTweakAdd(tweakCache: ByteArray, tweak32: ByteArray): ByteArray {
|
||||
TODO("Constraints not yet implemented")
|
||||
|
||||
memScoped {
|
||||
val nTweakCache = alloc<secp256k1_frost_tweak_cache>()
|
||||
memcpy(nTweakCache.ptr, toNat(tweakCache), Secp256k1.FROST_TWEAK_CACHE_SIZE.toULong())
|
||||
val nPublicKey = alloc<secp256k1_pubkey>()
|
||||
|
||||
secp256k1_frost_pubkey_ec_tweak_add(
|
||||
ctx = ctx,
|
||||
output_pubkey = nPublicKey.ptr,
|
||||
tweak_cache = nTweakCache.ptr,
|
||||
tweak32 = toNat(tweak32)
|
||||
)
|
||||
return serializePubkey(nPublicKey)
|
||||
}
|
||||
}
|
||||
|
||||
private fun MemScope.serializeFrostTweakCache(nTweakCache: secp256k1_frost_tweak_cache): ByteArray {
|
||||
val natOutput = ByteArray(Secp256k1.FROST_TWEAK_CACHE_SIZE)
|
||||
memcpy(toNat(natOutput), nTweakCache.ptr, Secp256k1.FROST_TWEAK_CACHE_SIZE.toULong())
|
||||
return natOutput
|
||||
}
|
||||
|
||||
override fun frostPublicKeyXonlyTweakAdd(tweakCache: ByteArray, tweak32: ByteArray): Pair<ByteArray, ByteArray> {
|
||||
TODO("Constraints not yet implemented")
|
||||
|
||||
memScoped {
|
||||
val nPublicKey = alloc<secp256k1_pubkey>()
|
||||
|
||||
val nTweakCache = alloc<secp256k1_frost_tweak_cache>()
|
||||
memcpy(nTweakCache.ptr, toNat(tweakCache), Secp256k1.FROST_TWEAK_CACHE_SIZE.toULong())
|
||||
|
||||
secp256k1_frost_pubkey_xonly_tweak_add(
|
||||
ctx = ctx,
|
||||
output_pubkey = nPublicKey.ptr,
|
||||
tweak_cache = nTweakCache.ptr,
|
||||
tweak32 = toNat(tweak32)
|
||||
)
|
||||
|
||||
return Pair(
|
||||
serializePubkey(nPublicKey),
|
||||
serializeFrostTweakCache(nTweakCache)
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private fun MemScope.serializeFrostSecnonce(nTweakCache: secp256k1_frost_secnonce): ByteArray {
|
||||
val natOutput = ByteArray(Secp256k1.FROST_SECNONCE_SIZE)
|
||||
memcpy(toNat(natOutput), nTweakCache.ptr, Secp256k1.FROST_SECNONCE_SIZE.toULong())
|
||||
return natOutput
|
||||
}
|
||||
|
||||
private fun MemScope.serializeFrostPubnonce(nPubnonce: secp256k1_frost_pubnonce): ByteArray {
|
||||
val natOutput = allocArray<UByteVar>(Secp256k1.FROST_SERIALIZED_PUBNONCE_SIZE)
|
||||
secp256k1_frost_pubnonce_serialize(ctx, natOutput, nPubnonce.ptr).requireSuccess("secp256k1_frost_pubnonce_serialize() failed")
|
||||
return natOutput.readBytes(Secp256k1.FROST_SERIALIZED_PUBNONCE_SIZE)
|
||||
}
|
||||
|
||||
override fun frostNonceGen(
|
||||
sessionId32: ByteArray,
|
||||
share: ByteArray,
|
||||
msg32: ByteArray,
|
||||
publicKey: ByteArray,
|
||||
extraInput32: ByteArray?
|
||||
): Pair<ByteArray, ByteArray> {
|
||||
TODO("Constraints not yet implemented")
|
||||
|
||||
memScoped {
|
||||
val nForstSecnonce = alloc<secp256k1_frost_secnonce>()
|
||||
val nPubnonce = alloc<secp256k1_frost_pubnonce>()
|
||||
|
||||
val nShare = allocFrostShare(share)
|
||||
val nPublicKey = allocXonlyPublicKey(publicKey)
|
||||
val nExtraInput32 = extraInput32?.let {
|
||||
toNat(it)
|
||||
}
|
||||
|
||||
secp256k1_frost_nonce_gen(
|
||||
ctx = ctx,
|
||||
secnonce = nForstSecnonce.ptr,
|
||||
pubnonce = nPubnonce.ptr,
|
||||
session_id32 = toNat(sessionId32),
|
||||
agg_share = nShare.ptr,
|
||||
msg32 = toNat(msg32),
|
||||
agg_pk = nPublicKey.ptr,
|
||||
extra_input32 = nExtraInput32
|
||||
)
|
||||
|
||||
return Pair(
|
||||
serializeFrostSecnonce(nForstSecnonce),
|
||||
serializeFrostPubnonce(nPubnonce)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun MemScope.serializeFrostSession(nSession: secp256k1_frost_session): ByteArray {
|
||||
val natOutput = ByteArray(Secp256k1.FROST_SESSION_SIZE)
|
||||
memcpy(toNat(natOutput), nSession.ptr, Secp256k1.FROST_SESSION_SIZE.toULong())
|
||||
return natOutput
|
||||
}
|
||||
|
||||
override fun frostNonceProcess(
|
||||
publicNonces: Array<ByteArray>,
|
||||
msg32: ByteArray,
|
||||
publicKey: ByteArray,
|
||||
id33: ByteArray,
|
||||
ids33: Array<ByteArray>,
|
||||
tweakCache: ByteArray,
|
||||
adaptor: ByteArray?
|
||||
): ByteArray {
|
||||
TODO("Constraint not yet implemented")
|
||||
|
||||
memScoped {
|
||||
val nSession = alloc<secp256k1_frost_session>();
|
||||
|
||||
val nPublicNonces = publicNonces.map { allocFrostPublicNonce(it).ptr }
|
||||
|
||||
val nPublicKey = allocXonlyPublicKey(publicKey)
|
||||
|
||||
val nIds33 = ids33.map { toNat(it) }
|
||||
|
||||
val nTweakCache = alloc<secp256k1_frost_tweak_cache>()
|
||||
memcpy(nTweakCache.ptr, toNat(tweakCache), Secp256k1.FROST_TWEAK_CACHE_SIZE.toULong())
|
||||
|
||||
val nAdaptor = adaptor?.let {
|
||||
allocPublicKey(it).ptr
|
||||
}
|
||||
secp256k1_frost_nonce_process(
|
||||
ctx = ctx,
|
||||
session = nSession.ptr,
|
||||
pubnonces = nPublicNonces.toCValues(),
|
||||
n_pubnonces = publicNonces.size.convert(),
|
||||
msg32 = toNat(msg32),
|
||||
agg_pk = nPublicKey.ptr,
|
||||
my_id33 = toNat(id33),
|
||||
ids33 = nIds33.toCValues(),
|
||||
tweak_cache = nTweakCache.ptr,
|
||||
adaptor = nAdaptor
|
||||
)
|
||||
|
||||
return serializeFrostSession(
|
||||
nSession = nSession
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private fun MemScope.serializeFrostPartialSignature(nPartialSignature: secp256k1_frost_partial_sig): ByteArray {
|
||||
val natOutput = allocArray<UByteVar>(Secp256k1.FROST_SERIALIZED_PARTIAL_SIGNATURE_SIZE)
|
||||
secp256k1_frost_partial_sig_serialize(ctx, natOutput, nPartialSignature.ptr).requireSuccess("secp256k1_frost_partial_sig_serialize() failed")
|
||||
return natOutput.readBytes(Secp256k1.FROST_SERIALIZED_PARTIAL_SIGNATURE_SIZE)
|
||||
}
|
||||
|
||||
override fun frostPartialSign(
|
||||
secnonce: ByteArray,
|
||||
share: ByteArray,
|
||||
session: ByteArray,
|
||||
tweakCache: ByteArray
|
||||
): ByteArray {
|
||||
TODO("Constraints not yet implemented")
|
||||
|
||||
memScoped {
|
||||
val nPartialSignature = alloc<secp256k1_frost_partial_sig>();
|
||||
|
||||
val nSecnonce = alloc<secp256k1_frost_secnonce>()
|
||||
memcpy(nSecnonce.ptr, toNat(secnonce), Secp256k1.FROST_SECNONCE_SIZE.toULong())
|
||||
|
||||
val nShare = allocFrostShare(share)
|
||||
|
||||
val nSession = alloc<secp256k1_frost_session>()
|
||||
memcpy(nSession.ptr, toNat(session), Secp256k1.FROST_SESSION_SIZE.toULong())
|
||||
|
||||
val nTweakCache = alloc<secp256k1_frost_tweak_cache>()
|
||||
memcpy(nTweakCache.ptr, toNat(tweakCache), Secp256k1.FROST_TWEAK_CACHE_SIZE.toULong())
|
||||
|
||||
secp256k1_frost_partial_sign(
|
||||
ctx,
|
||||
nPartialSignature.ptr,
|
||||
nSecnonce.ptr,
|
||||
nShare.ptr,
|
||||
nSession.ptr,
|
||||
nTweakCache.ptr
|
||||
)
|
||||
|
||||
return serializeFrostPartialSignature(nPartialSignature)
|
||||
}
|
||||
}
|
||||
|
||||
override fun frostPartialSignatureVerify(
|
||||
partialSig: ByteArray,
|
||||
publicNonce: ByteArray,
|
||||
publicShare: ByteArray,
|
||||
session: ByteArray,
|
||||
tweakCache: ByteArray
|
||||
): Int {
|
||||
TODO("Constraints not yet implemented")
|
||||
|
||||
memScoped {
|
||||
val nPartialSignature = allocFrostPartialSignature(partialSig)
|
||||
val nPublicNonce = allocFrostPublicNonce(publicNonce)
|
||||
val nPublicShare = allocPublicKey(publicShare)
|
||||
val nSession = alloc<secp256k1_frost_session>()
|
||||
memcpy(nSession.ptr, toNat(session), Secp256k1.FROST_SESSION_SIZE.toULong())
|
||||
val nTweakCache = alloc<secp256k1_frost_tweak_cache>()
|
||||
memcpy(nTweakCache.ptr, toNat(tweakCache), Secp256k1.FROST_TWEAK_CACHE_SIZE.toULong())
|
||||
|
||||
return secp256k1_frost_partial_sig_verify(
|
||||
ctx,
|
||||
nPartialSignature.ptr,
|
||||
nPublicNonce.ptr,
|
||||
nPublicShare.ptr,
|
||||
nSession.ptr,
|
||||
nTweakCache.ptr
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun frostPartialSignatureAggregate(session: ByteArray, partialSignatures: Array<ByteArray>): ByteArray {
|
||||
TODO("Not yet implemented")
|
||||
|
||||
memScoped {
|
||||
val sig64 = ByteArray(64)
|
||||
|
||||
val nSession = alloc<secp256k1_frost_session>();
|
||||
memcpy(nSession.ptr, toNat(session), Secp256k1.FROST_SESSION_SIZE.toULong())
|
||||
val nPartialSignatures = partialSignatures.map { allocFrostPartialSignature(it).ptr }
|
||||
|
||||
secp256k1_frost_partial_sig_agg(
|
||||
ctx,
|
||||
toNat(sig64),
|
||||
nSession.ptr,
|
||||
nPartialSignatures.toCValues(),
|
||||
partialSignatures.size.convert()
|
||||
)
|
||||
|
||||
return sig64
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public override fun cleanup() {
|
||||
secp256k1_context_destroy(ctx)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user