Export Schnorr signature API (#32)
Implement Schnorr signatures (BIP 340)
This commit is contained in:
@@ -38,6 +38,24 @@ public interface Secp256k1 {
|
||||
public fun sign(message: ByteArray, privkey: ByteArray): ByteArray
|
||||
|
||||
/**
|
||||
* Verify a Schnorr signature.
|
||||
*
|
||||
* @param signature 64 bytes signature.
|
||||
* @param message message signed.
|
||||
* @param pubkey signer's x-only public key (32 bytes).
|
||||
*/
|
||||
public fun verifySchnorr(signature: ByteArray, data: ByteArray, pub: ByteArray): Boolean
|
||||
|
||||
/**
|
||||
* Create a Schnorr signature.
|
||||
*
|
||||
* @param message message to sign.
|
||||
* @param privkey signer's private key.
|
||||
* @param auxrand32 32 bytes of fresh randomness (optional).
|
||||
*/
|
||||
public fun signSchnorr(data: ByteArray, sec: ByteArray, auxrand32: ByteArray?): ByteArray
|
||||
|
||||
/**
|
||||
* Convert an ECDSA signature to a normalized lower-S form (bitcoin standardness rule).
|
||||
* Returns the normalized signature and a boolean set to true if the input signature was not normalized.
|
||||
*
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package = secp256k1
|
||||
|
||||
headers = secp256k1.h secp256k1_ecdh.h secp256k1_recovery.h
|
||||
headerFilter = secp256k1/** secp256k1_ecdh.h secp256k1_recovery.h secp256k1.h
|
||||
headers = secp256k1.h secp256k1_ecdh.h secp256k1_recovery.h secp256k1_extrakeys.h secp256k1_schnorrsig.h
|
||||
headerFilter = secp256k1/** secp256k1_ecdh.h secp256k1_recovery.h secp256k1_extrakeys.h secp256k1_schnorrsig.h secp256k1.h
|
||||
|
||||
libraryPaths.linux = c/secp256k1/build/linux/
|
||||
linkerOpts.linux = -L/usr/lib64 -L/usr/lib/x86_64-linux-gnu -L/usr/local/lib
|
||||
|
||||
@@ -222,9 +222,41 @@ public object Secp256k1Native : Secp256k1 {
|
||||
}
|
||||
}
|
||||
|
||||
override fun verifySchnorr(signature: ByteArray, data: ByteArray, pub: ByteArray): Boolean {
|
||||
require(signature.size == 64)
|
||||
require(data.size == 32)
|
||||
require(pub.size == 32)
|
||||
memScoped {
|
||||
val nPub = toNat(pub)
|
||||
val pubkey = alloc<secp256k1_xonly_pubkey>()
|
||||
secp256k1_xonly_pubkey_parse(ctx, pubkey.ptr, nPub).requireSuccess("secp256k1_xonly_pubkey_parse() failed")
|
||||
val nData = toNat(data)
|
||||
val nSig = toNat(signature)
|
||||
return secp256k1_schnorrsig_verify(ctx, nSig, nData, 32, pubkey.ptr) == 1
|
||||
}
|
||||
}
|
||||
|
||||
override fun signSchnorr(data: ByteArray, sec: ByteArray, auxrand32: ByteArray?): ByteArray {
|
||||
require(sec.size == 32)
|
||||
require(data.size == 32)
|
||||
auxrand32?.let { require(it.size == 32) }
|
||||
memScoped {
|
||||
val nSec = toNat(sec)
|
||||
val nData = toNat(data)
|
||||
val nAuxrand32 = auxrand32?.let { toNat(it) }
|
||||
val nSig = allocArray<UByteVar>(64)
|
||||
val keypair = alloc<secp256k1_keypair>()
|
||||
secp256k1_keypair_create(ctx, keypair.ptr, nSec).requireSuccess("secp256k1_keypair_create() failed")
|
||||
secp256k1_schnorrsig_sign(ctx, nSig, nData, keypair.ptr, nAuxrand32).requireSuccess("secp256k1_ecdsa_sign() failed")
|
||||
return nSig.readBytes(64)
|
||||
}
|
||||
}
|
||||
|
||||
public override fun cleanup() {
|
||||
secp256k1_context_destroy(ctx)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
internal actual fun getSecpk256k1(): Secp256k1 = Secp256k1Native
|
||||
|
||||
Reference in New Issue
Block a user