ECDSA secp256k1 проблема с подписью / проверкой на Swift - PullRequest
0 голосов
/ 09 января 2020

Мне нужно создать пару ключей, затем подписать сообщение закрытым ключом и затем проверить подпись.

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?

...