Мне нужно создать пару ключей, затем подписать сообщение закрытым ключом и затем проверить подпись.
1) E CC Имя кривой: secp256k1
2) ключ publi c должен быть несжатым (с префиксом 04)
3) подпись должна начинаться с 30 (формат DER)
4) Алгоритм подписи: SHA256 с ECDSA
Поэтому я выбираю эту библиотеку (и CryptoSwift
) - https://github.com/LanfordCai/Secp256k1Swift
И мой код довольно прост и выглядит так:
let (privkey, pubkey) = try! Secp256k1.keyPair()
let priv = privkey.toHexString()
let pub = pubkey.toHexString()
print(type(of: privkey), type(of: priv))
print(priv, " ------ PRIVATE ", priv.count)
print(pub, " ------ PUBLIC ", pub.count)
//Verify a private key
let resultPriv = Secp256k1.isValidPrivateKey(privkey)
print(resultPriv)
//Sign a message
let message = "Test message string"
let arr = message.bytes
let sig = try! Secp256k1.sign(msg: arr, with: privkey, nonceFunction: .rfc6979)
let sig2 = sig.toHexString()
print(sig2, " ------ SIGNATURE ", sig2.count)
//Verify a signature
let resultSig = Secp256k1.verify(msg: arr, sig: sig, pubkey: pubkey)
print(resultSig)
И вывод будет
9b77bfe3b3c9437272a6b870be90fe461f5e37046958aec991a17c0773f3722c ------ PRIVATE 64
047e0705c40dc36898e87e3de45d245ecfd2161f000ed5a01b7159e76056d0323dd3b78b1e7ce40784cdc6f00bbcaeb9b37d1a2db9ee442a9831b6e44636d048b4 ------ PUBLIC 130
true
304402207681a8bd0881605c023df04044d9ccfffde66107f6ba71010ea9f5590c046fab022018e73db77a87840b427cf399839b2ac3629399682991b0e50023f65569e51c31 ------ SIGNATURE 140
true
Так что это должно означать, что все правильно. НО. Когда я пытаюсь проверить ключи и подпись на https://kjur.github.io/jsrsasign/sample/sample-ecdsa.html, она всегда терпит неудачу.
Функция подписи:
public static func sign(msg: [UInt8], with privkey: PrivateKey, nonceFunction: NonceFunction) throws -> Signature {
guard isValidPrivateKey(privkey) else {
throw Error.invalidPrivateKey
}
let context = secp256k1_context_create(UInt32(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY))!
defer {
secp256k1_context_destroy(context)
}
var cSignature = secp256k1_ecdsa_signature()
guard secp256k1_ecdsa_sign(context, &cSignature, msg, privkey, nonceFunction.function, nil) == 1 else {
throw Error.internalError
}
var sigLen = 74
var signature = [UInt8](repeating: 0, count: sigLen)
guard secp256k1_ecdsa_signature_serialize_der(context, &signature, &sigLen, &cSignature) == 1,
secp256k1_ecdsa_signature_parse_der(context, &cSignature, &signature, sigLen) == 1 else {
throw Error.internalError
}
return Array(signature[..<sigLen])
}
и может быть только 2 случая отсутствия возможности:
/** An implementation of RFC6979 (using HMAC-SHA256) as nonce generation function.
* If a data pointer is passed, it is assumed to be a pointer to 32 bytes of
* extra entropy.
*/
SECP256K1_API extern const secp256k1_nonce_function secp256k1_nonce_function_rfc6979;
/** A default safe nonce generation function (currently equal to secp256k1_nonce_function_rfc6979). */
SECP256K1_API extern const secp256k1_nonce_function secp256k1_nonce_function_default;
Я довольно новичок в парных ключах и прочем, поэтому надеюсь, что кто-нибудь поможет мне с моими недействительными подписями.
И, может быть, есть какой-то способ соответствовать моим целям, кроме Swift-обертки C lib?