csecp256k1

Haskell FFI bindings to bitcoin-core/secp256k1 (docs.ppad.tech/csecp256k1).
git clone git://git.ppad.tech/csecp256k1.git
Log | Files | Refs | README | LICENSE

main_impl.h (7325B)


      1 /***********************************************************************
      2  * Copyright (c) 2013-2015 Pieter Wuille                               *
      3  * Distributed under the MIT software license, see the accompanying    *
      4  * file COPYING or https://www.opensource.org/licenses/mit-license.php.*
      5  ***********************************************************************/
      6 
      7 #ifndef SECP256K1_MODULE_RECOVERY_MAIN_H
      8 #define SECP256K1_MODULE_RECOVERY_MAIN_H
      9 
     10 #include "../../../include/secp256k1_recovery.h"
     11 
     12 static void haskellsecp256k1_v0_1_0_ecdsa_recoverable_signature_load(const haskellsecp256k1_v0_1_0_context* ctx, haskellsecp256k1_v0_1_0_scalar* r, haskellsecp256k1_v0_1_0_scalar* s, int* recid, const haskellsecp256k1_v0_1_0_ecdsa_recoverable_signature* sig) {
     13     (void)ctx;
     14     if (sizeof(haskellsecp256k1_v0_1_0_scalar) == 32) {
     15         /* When the haskellsecp256k1_v0_1_0_scalar type is exactly 32 byte, use its
     16          * representation inside haskellsecp256k1_v0_1_0_ecdsa_signature, as conversion is very fast.
     17          * Note that haskellsecp256k1_v0_1_0_ecdsa_signature_save must use the same representation. */
     18         memcpy(r, &sig->data[0], 32);
     19         memcpy(s, &sig->data[32], 32);
     20     } else {
     21         haskellsecp256k1_v0_1_0_scalar_set_b32(r, &sig->data[0], NULL);
     22         haskellsecp256k1_v0_1_0_scalar_set_b32(s, &sig->data[32], NULL);
     23     }
     24     *recid = sig->data[64];
     25 }
     26 
     27 static void haskellsecp256k1_v0_1_0_ecdsa_recoverable_signature_save(haskellsecp256k1_v0_1_0_ecdsa_recoverable_signature* sig, const haskellsecp256k1_v0_1_0_scalar* r, const haskellsecp256k1_v0_1_0_scalar* s, int recid) {
     28     if (sizeof(haskellsecp256k1_v0_1_0_scalar) == 32) {
     29         memcpy(&sig->data[0], r, 32);
     30         memcpy(&sig->data[32], s, 32);
     31     } else {
     32         haskellsecp256k1_v0_1_0_scalar_get_b32(&sig->data[0], r);
     33         haskellsecp256k1_v0_1_0_scalar_get_b32(&sig->data[32], s);
     34     }
     35     sig->data[64] = recid;
     36 }
     37 
     38 int haskellsecp256k1_v0_1_0_ecdsa_recoverable_signature_parse_compact(const haskellsecp256k1_v0_1_0_context* ctx, haskellsecp256k1_v0_1_0_ecdsa_recoverable_signature* sig, const unsigned char *input64, int recid) {
     39     haskellsecp256k1_v0_1_0_scalar r, s;
     40     int ret = 1;
     41     int overflow = 0;
     42 
     43     VERIFY_CHECK(ctx != NULL);
     44     ARG_CHECK(sig != NULL);
     45     ARG_CHECK(input64 != NULL);
     46     ARG_CHECK(recid >= 0 && recid <= 3);
     47 
     48     haskellsecp256k1_v0_1_0_scalar_set_b32(&r, &input64[0], &overflow);
     49     ret &= !overflow;
     50     haskellsecp256k1_v0_1_0_scalar_set_b32(&s, &input64[32], &overflow);
     51     ret &= !overflow;
     52     if (ret) {
     53         haskellsecp256k1_v0_1_0_ecdsa_recoverable_signature_save(sig, &r, &s, recid);
     54     } else {
     55         memset(sig, 0, sizeof(*sig));
     56     }
     57     return ret;
     58 }
     59 
     60 int haskellsecp256k1_v0_1_0_ecdsa_recoverable_signature_serialize_compact(const haskellsecp256k1_v0_1_0_context* ctx, unsigned char *output64, int *recid, const haskellsecp256k1_v0_1_0_ecdsa_recoverable_signature* sig) {
     61     haskellsecp256k1_v0_1_0_scalar r, s;
     62 
     63     VERIFY_CHECK(ctx != NULL);
     64     ARG_CHECK(output64 != NULL);
     65     ARG_CHECK(sig != NULL);
     66     ARG_CHECK(recid != NULL);
     67 
     68     haskellsecp256k1_v0_1_0_ecdsa_recoverable_signature_load(ctx, &r, &s, recid, sig);
     69     haskellsecp256k1_v0_1_0_scalar_get_b32(&output64[0], &r);
     70     haskellsecp256k1_v0_1_0_scalar_get_b32(&output64[32], &s);
     71     return 1;
     72 }
     73 
     74 int haskellsecp256k1_v0_1_0_ecdsa_recoverable_signature_convert(const haskellsecp256k1_v0_1_0_context* ctx, haskellsecp256k1_v0_1_0_ecdsa_signature* sig, const haskellsecp256k1_v0_1_0_ecdsa_recoverable_signature* sigin) {
     75     haskellsecp256k1_v0_1_0_scalar r, s;
     76     int recid;
     77 
     78     VERIFY_CHECK(ctx != NULL);
     79     ARG_CHECK(sig != NULL);
     80     ARG_CHECK(sigin != NULL);
     81 
     82     haskellsecp256k1_v0_1_0_ecdsa_recoverable_signature_load(ctx, &r, &s, &recid, sigin);
     83     haskellsecp256k1_v0_1_0_ecdsa_signature_save(sig, &r, &s);
     84     return 1;
     85 }
     86 
     87 static int haskellsecp256k1_v0_1_0_ecdsa_sig_recover(const haskellsecp256k1_v0_1_0_scalar *sigr, const haskellsecp256k1_v0_1_0_scalar* sigs, haskellsecp256k1_v0_1_0_ge *pubkey, const haskellsecp256k1_v0_1_0_scalar *message, int recid) {
     88     unsigned char brx[32];
     89     haskellsecp256k1_v0_1_0_fe fx;
     90     haskellsecp256k1_v0_1_0_ge x;
     91     haskellsecp256k1_v0_1_0_gej xj;
     92     haskellsecp256k1_v0_1_0_scalar rn, u1, u2;
     93     haskellsecp256k1_v0_1_0_gej qj;
     94     int r;
     95 
     96     if (haskellsecp256k1_v0_1_0_scalar_is_zero(sigr) || haskellsecp256k1_v0_1_0_scalar_is_zero(sigs)) {
     97         return 0;
     98     }
     99 
    100     haskellsecp256k1_v0_1_0_scalar_get_b32(brx, sigr);
    101     r = haskellsecp256k1_v0_1_0_fe_set_b32_limit(&fx, brx);
    102     (void)r;
    103     VERIFY_CHECK(r); /* brx comes from a scalar, so is less than the order; certainly less than p */
    104     if (recid & 2) {
    105         if (haskellsecp256k1_v0_1_0_fe_cmp_var(&fx, &haskellsecp256k1_v0_1_0_ecdsa_const_p_minus_order) >= 0) {
    106             return 0;
    107         }
    108         haskellsecp256k1_v0_1_0_fe_add(&fx, &haskellsecp256k1_v0_1_0_ecdsa_const_order_as_fe);
    109     }
    110     if (!haskellsecp256k1_v0_1_0_ge_set_xo_var(&x, &fx, recid & 1)) {
    111         return 0;
    112     }
    113     haskellsecp256k1_v0_1_0_gej_set_ge(&xj, &x);
    114     haskellsecp256k1_v0_1_0_scalar_inverse_var(&rn, sigr);
    115     haskellsecp256k1_v0_1_0_scalar_mul(&u1, &rn, message);
    116     haskellsecp256k1_v0_1_0_scalar_negate(&u1, &u1);
    117     haskellsecp256k1_v0_1_0_scalar_mul(&u2, &rn, sigs);
    118     haskellsecp256k1_v0_1_0_ecmult(&qj, &xj, &u2, &u1);
    119     haskellsecp256k1_v0_1_0_ge_set_gej_var(pubkey, &qj);
    120     return !haskellsecp256k1_v0_1_0_gej_is_infinity(&qj);
    121 }
    122 
    123 int haskellsecp256k1_v0_1_0_ecdsa_sign_recoverable(const haskellsecp256k1_v0_1_0_context* ctx, haskellsecp256k1_v0_1_0_ecdsa_recoverable_signature *signature, const unsigned char *msghash32, const unsigned char *seckey, haskellsecp256k1_v0_1_0_nonce_function noncefp, const void* noncedata) {
    124     haskellsecp256k1_v0_1_0_scalar r, s;
    125     int ret, recid;
    126     VERIFY_CHECK(ctx != NULL);
    127     ARG_CHECK(haskellsecp256k1_v0_1_0_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx));
    128     ARG_CHECK(msghash32 != NULL);
    129     ARG_CHECK(signature != NULL);
    130     ARG_CHECK(seckey != NULL);
    131 
    132     ret = haskellsecp256k1_v0_1_0_ecdsa_sign_inner(ctx, &r, &s, &recid, msghash32, seckey, noncefp, noncedata);
    133     haskellsecp256k1_v0_1_0_ecdsa_recoverable_signature_save(signature, &r, &s, recid);
    134     return ret;
    135 }
    136 
    137 int haskellsecp256k1_v0_1_0_ecdsa_recover(const haskellsecp256k1_v0_1_0_context* ctx, haskellsecp256k1_v0_1_0_pubkey *pubkey, const haskellsecp256k1_v0_1_0_ecdsa_recoverable_signature *signature, const unsigned char *msghash32) {
    138     haskellsecp256k1_v0_1_0_ge q;
    139     haskellsecp256k1_v0_1_0_scalar r, s;
    140     haskellsecp256k1_v0_1_0_scalar m;
    141     int recid;
    142     VERIFY_CHECK(ctx != NULL);
    143     ARG_CHECK(msghash32 != NULL);
    144     ARG_CHECK(signature != NULL);
    145     ARG_CHECK(pubkey != NULL);
    146 
    147     haskellsecp256k1_v0_1_0_ecdsa_recoverable_signature_load(ctx, &r, &s, &recid, signature);
    148     VERIFY_CHECK(recid >= 0 && recid < 4);  /* should have been caught in parse_compact */
    149     haskellsecp256k1_v0_1_0_scalar_set_b32(&m, msghash32, NULL);
    150     if (haskellsecp256k1_v0_1_0_ecdsa_sig_recover(&r, &s, &q, &m, recid)) {
    151         haskellsecp256k1_v0_1_0_pubkey_save(pubkey, &q);
    152         return 1;
    153     } else {
    154         memset(pubkey, 0, sizeof(*pubkey));
    155         return 0;
    156     }
    157 }
    158 
    159 #endif /* SECP256K1_MODULE_RECOVERY_MAIN_H */