Clarify public key encoding and enrich tests (#37)

Don't throw in `seckey_verify`: it's inconsistent to have this function throw
for some invalid inputs and return false for other invalid inputs.

Document public key compression and add tests.
This commit is contained in:
Bastien Teinturier
2021-11-05 10:45:49 +01:00
committed by GitHub
parent f695e7453d
commit 2ae6abcf93
4 changed files with 73 additions and 26 deletions

View File

@@ -52,11 +52,13 @@ public interface Secp256k1 {
/**
* Get the public key corresponding to the given private key.
* Returns the uncompressed public key (65 bytes).
*/
public fun pubkeyCreate(privkey: ByteArray): ByteArray
/**
* Parse a serialized public key.
* Returns the uncompressed public key (65 bytes).
*/
public fun pubkeyParse(pubkey: ByteArray): ByteArray
@@ -77,21 +79,25 @@ public interface Secp256k1 {
/**
* Negate the given public key.
* Returns the uncompressed public key (65 bytes).
*/
public fun pubKeyNegate(pubkey: ByteArray): ByteArray
/**
* Tweak a public key by adding tweak times the generator to it.
* Returns the uncompressed public key (65 bytes).
*/
public fun pubKeyTweakAdd(pubkey: ByteArray, tweak: ByteArray): ByteArray
/**
* Tweak a public key by multiplying it by a tweak value.
* Returns the uncompressed public key (65 bytes).
*/
public fun pubKeyTweakMul(pubkey: ByteArray, tweak: ByteArray): ByteArray
/**
* Add a number of public keys together.
* Returns the uncompressed public key (65 bytes).
*/
public fun pubKeyCombine(pubkeys: Array<ByteArray>): ByteArray
@@ -121,9 +127,9 @@ public interface Secp256k1 {
return when {
pubkey.size == 33 && (pubkey[0] == 2.toByte() || pubkey[0] == 3.toByte()) -> pubkey
pubkey.size == 65 && pubkey[0] == 4.toByte() -> {
val pub1 = pubkey.copyOf(33)
pub1[0] = if (pubkey.last() % 2 == 0) 2.toByte() else 3.toByte()
pub1
val compressed = pubkey.copyOf(33)
compressed[0] = if (pubkey.last() % 2 == 0) 2.toByte() else 3.toByte()
compressed
}
else -> throw Secp256k1Exception("invalid public key")
}

View File

@@ -88,7 +88,7 @@ public object Secp256k1Native : Secp256k1 {
}
public override fun secKeyVerify(privkey: ByteArray): Boolean {
require(privkey.size == 32)
if (privkey.size != 32) return false
memScoped {
val nPrivkey = toNat(privkey)
return secp256k1_ec_seckey_verify(ctx, nPrivkey) == 1