2020-06-26 13:48:50 +02:00
|
|
|
/*
|
|
|
|
* Copyright 2020 ACINQ SAS
|
|
|
|
*
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*/
|
|
|
|
|
|
|
|
package fr.acinq.secp256k1
|
|
|
|
|
|
|
|
import kotlin.jvm.JvmStatic
|
|
|
|
|
2020-07-01 12:46:04 +02:00
|
|
|
public interface Secp256k1 {
|
2020-06-26 13:48:50 +02:00
|
|
|
|
2021-10-26 17:16:36 +02:00
|
|
|
/**
|
|
|
|
* Verify an ECDSA signature.
|
|
|
|
*
|
|
|
|
* @param signature signature using either compact encoding (64 bytes) or der-encoding.
|
|
|
|
* @param message message signed.
|
|
|
|
* @param pubkey signer's public key.
|
|
|
|
*/
|
|
|
|
public fun verify(signature: ByteArray, message: ByteArray, pubkey: ByteArray): Boolean
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Create a normalized ECDSA signature.
|
|
|
|
*
|
|
|
|
* @param message message to sign.
|
|
|
|
* @param privkey signer's private key.
|
|
|
|
*/
|
|
|
|
public fun sign(message: ByteArray, privkey: ByteArray): ByteArray
|
|
|
|
|
|
|
|
/**
|
2021-11-23 17:38:46 +01:00
|
|
|
* Verify a Schnorr signature.
|
|
|
|
*
|
|
|
|
* @param signature 64 bytes signature.
|
2022-09-21 16:00:19 +02:00
|
|
|
* @param data message signed.
|
|
|
|
* @param pub signer's x-only public key (32 bytes).
|
2021-11-23 17:38:46 +01:00
|
|
|
*/
|
|
|
|
public fun verifySchnorr(signature: ByteArray, data: ByteArray, pub: ByteArray): Boolean
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Create a Schnorr signature.
|
|
|
|
*
|
2022-09-21 16:00:19 +02:00
|
|
|
* @param data message to sign.
|
|
|
|
* @param sec signer's private key.
|
2021-11-23 17:38:46 +01:00
|
|
|
* @param auxrand32 32 bytes of fresh randomness (optional).
|
|
|
|
*/
|
|
|
|
public fun signSchnorr(data: ByteArray, sec: ByteArray, auxrand32: ByteArray?): ByteArray
|
|
|
|
|
|
|
|
/**
|
2021-10-26 17:16:36 +02:00
|
|
|
* 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.
|
|
|
|
*
|
|
|
|
* @param sig signature that should be normalized.
|
|
|
|
*/
|
2020-07-02 17:52:21 +02:00
|
|
|
public fun signatureNormalize(sig: ByteArray): Pair<ByteArray, Boolean>
|
2020-06-26 13:48:50 +02:00
|
|
|
|
2021-10-26 17:16:36 +02:00
|
|
|
/**
|
|
|
|
* Verify the validity of a private key.
|
|
|
|
*/
|
|
|
|
public fun secKeyVerify(privkey: ByteArray): Boolean
|
2020-06-26 13:48:50 +02:00
|
|
|
|
2021-10-26 17:16:36 +02:00
|
|
|
/**
|
|
|
|
* Get the public key corresponding to the given private key.
|
2021-11-05 10:45:49 +01:00
|
|
|
* Returns the uncompressed public key (65 bytes).
|
2021-10-26 17:16:36 +02:00
|
|
|
*/
|
|
|
|
public fun pubkeyCreate(privkey: ByteArray): ByteArray
|
2020-06-26 13:48:50 +02:00
|
|
|
|
2021-10-26 17:16:36 +02:00
|
|
|
/**
|
|
|
|
* Parse a serialized public key.
|
2021-11-05 10:45:49 +01:00
|
|
|
* Returns the uncompressed public key (65 bytes).
|
2021-10-26 17:16:36 +02:00
|
|
|
*/
|
2020-07-02 17:52:21 +02:00
|
|
|
public fun pubkeyParse(pubkey: ByteArray): ByteArray
|
2020-06-26 13:48:50 +02:00
|
|
|
|
2021-10-26 17:16:36 +02:00
|
|
|
/**
|
|
|
|
* Negate the given private key.
|
|
|
|
*/
|
2020-06-26 13:48:50 +02:00
|
|
|
public fun privKeyNegate(privkey: ByteArray): ByteArray
|
|
|
|
|
2021-10-26 17:16:36 +02:00
|
|
|
/**
|
|
|
|
* Tweak a private key by adding tweak to it.
|
|
|
|
*/
|
2020-06-26 13:48:50 +02:00
|
|
|
public fun privKeyTweakAdd(privkey: ByteArray, tweak: ByteArray): ByteArray
|
|
|
|
|
2021-10-26 17:16:36 +02:00
|
|
|
/**
|
|
|
|
* Tweak a private key by multiplying it by a tweak.
|
|
|
|
*/
|
|
|
|
public fun privKeyTweakMul(privkey: ByteArray, tweak: ByteArray): ByteArray
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Negate the given public key.
|
2021-11-05 10:45:49 +01:00
|
|
|
* Returns the uncompressed public key (65 bytes).
|
2021-10-26 17:16:36 +02:00
|
|
|
*/
|
2020-06-26 13:48:50 +02:00
|
|
|
public fun pubKeyNegate(pubkey: ByteArray): ByteArray
|
|
|
|
|
2021-10-26 17:16:36 +02:00
|
|
|
/**
|
|
|
|
* Tweak a public key by adding tweak times the generator to it.
|
2021-11-05 10:45:49 +01:00
|
|
|
* Returns the uncompressed public key (65 bytes).
|
2021-10-26 17:16:36 +02:00
|
|
|
*/
|
2020-06-26 13:48:50 +02:00
|
|
|
public fun pubKeyTweakAdd(pubkey: ByteArray, tweak: ByteArray): ByteArray
|
|
|
|
|
2021-10-26 17:16:36 +02:00
|
|
|
/**
|
|
|
|
* Tweak a public key by multiplying it by a tweak value.
|
2021-11-05 10:45:49 +01:00
|
|
|
* Returns the uncompressed public key (65 bytes).
|
2021-10-26 17:16:36 +02:00
|
|
|
*/
|
2020-06-26 13:48:50 +02:00
|
|
|
public fun pubKeyTweakMul(pubkey: ByteArray, tweak: ByteArray): ByteArray
|
|
|
|
|
2021-10-26 17:16:36 +02:00
|
|
|
/**
|
|
|
|
* Add a number of public keys together.
|
2021-11-05 10:45:49 +01:00
|
|
|
* Returns the uncompressed public key (65 bytes).
|
2021-10-26 17:16:36 +02:00
|
|
|
*/
|
|
|
|
public fun pubKeyCombine(pubkeys: Array<ByteArray>): ByteArray
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Compute an elliptic curve Diffie-Hellman secret.
|
|
|
|
*/
|
|
|
|
public fun ecdh(privkey: ByteArray, pubkey: ByteArray): ByteArray
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Recover a public key from an ECDSA signature.
|
|
|
|
*
|
|
|
|
* @param sig ecdsa compact signature (64 bytes).
|
|
|
|
* @param message message signed.
|
|
|
|
* @param recid recoveryId (should have been provided with the signature to allow recovery).
|
|
|
|
*/
|
2020-07-02 17:52:21 +02:00
|
|
|
public fun ecdsaRecover(sig: ByteArray, message: ByteArray, recid: Int): ByteArray
|
2020-06-26 13:48:50 +02:00
|
|
|
|
2021-10-26 17:16:36 +02:00
|
|
|
/**
|
|
|
|
* Convert a compact ECDSA signature (64 bytes) to a der-encoded ECDSA signature.
|
|
|
|
*/
|
2020-07-02 21:39:33 +02:00
|
|
|
public fun compact2der(sig: ByteArray): ByteArray
|
|
|
|
|
2021-10-26 17:16:36 +02:00
|
|
|
/**
|
|
|
|
* Serialize a public key to compact form (33 bytes).
|
|
|
|
*/
|
|
|
|
public fun pubKeyCompress(pubkey: ByteArray): ByteArray {
|
2020-07-02 17:52:21 +02:00
|
|
|
return when {
|
|
|
|
pubkey.size == 33 && (pubkey[0] == 2.toByte() || pubkey[0] == 3.toByte()) -> pubkey
|
|
|
|
pubkey.size == 65 && pubkey[0] == 4.toByte() -> {
|
2021-11-05 10:45:49 +01:00
|
|
|
val compressed = pubkey.copyOf(33)
|
|
|
|
compressed[0] = if (pubkey.last() % 2 == 0) 2.toByte() else 3.toByte()
|
|
|
|
compressed
|
2020-07-02 17:52:21 +02:00
|
|
|
}
|
2020-07-02 18:07:28 +02:00
|
|
|
else -> throw Secp256k1Exception("invalid public key")
|
2020-07-02 17:52:21 +02:00
|
|
|
}
|
|
|
|
}
|
2020-07-01 12:46:04 +02:00
|
|
|
|
2021-10-26 17:16:36 +02:00
|
|
|
/**
|
|
|
|
* Delete the secp256k1 context from dynamic memory.
|
|
|
|
*/
|
|
|
|
public fun cleanup()
|
|
|
|
|
2020-07-01 12:46:04 +02:00
|
|
|
public companion object : Secp256k1 by getSecpk256k1() {
|
2021-10-26 17:16:36 +02:00
|
|
|
@JvmStatic
|
|
|
|
public fun get(): Secp256k1 = this
|
2020-07-01 12:46:04 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
internal expect fun getSecpk256k1(): Secp256k1
|
2020-07-02 17:52:21 +02:00
|
|
|
|
2023-12-11 15:55:22 +01:00
|
|
|
public open class Secp256k1Exception : RuntimeException {
|
|
|
|
public constructor() : super()
|
|
|
|
public constructor(message: String?) : super(message)
|
|
|
|
}
|
|
|
|
|
|
|
|
public class Secp256k1ErrorCallbackException : Secp256k1Exception {
|
|
|
|
public constructor() : super()
|
|
|
|
public constructor(message: String?) : super(message)
|
|
|
|
}
|
|
|
|
|
|
|
|
public class Secp256k1IllegalCallbackException : Secp256k1Exception {
|
2021-10-26 17:16:36 +02:00
|
|
|
public constructor() : super()
|
|
|
|
public constructor(message: String?) : super(message)
|
2020-07-02 17:52:21 +02:00
|
|
|
}
|