github.com/ethereum/go-ethereum@v1.16.1/crypto/secp256k1/libsecp256k1/src/modules/recovery/main_impl.h (about)

     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 secp256k1_ecdsa_recoverable_signature_load(const secp256k1_context* ctx, secp256k1_scalar* r, secp256k1_scalar* s, int* recid, const secp256k1_ecdsa_recoverable_signature* sig) {
    13      (void)ctx;
    14      if (sizeof(secp256k1_scalar) == 32) {
    15          /* When the secp256k1_scalar type is exactly 32 byte, use its
    16           * representation inside secp256k1_ecdsa_signature, as conversion is very fast.
    17           * Note that secp256k1_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          secp256k1_scalar_set_b32(r, &sig->data[0], NULL);
    22          secp256k1_scalar_set_b32(s, &sig->data[32], NULL);
    23      }
    24      *recid = sig->data[64];
    25  }
    26  
    27  static void secp256k1_ecdsa_recoverable_signature_save(secp256k1_ecdsa_recoverable_signature* sig, const secp256k1_scalar* r, const secp256k1_scalar* s, int recid) {
    28      if (sizeof(secp256k1_scalar) == 32) {
    29          memcpy(&sig->data[0], r, 32);
    30          memcpy(&sig->data[32], s, 32);
    31      } else {
    32          secp256k1_scalar_get_b32(&sig->data[0], r);
    33          secp256k1_scalar_get_b32(&sig->data[32], s);
    34      }
    35      sig->data[64] = recid;
    36  }
    37  
    38  int secp256k1_ecdsa_recoverable_signature_parse_compact(const secp256k1_context* ctx, secp256k1_ecdsa_recoverable_signature* sig, const unsigned char *input64, int recid) {
    39      secp256k1_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      secp256k1_scalar_set_b32(&r, &input64[0], &overflow);
    49      ret &= !overflow;
    50      secp256k1_scalar_set_b32(&s, &input64[32], &overflow);
    51      ret &= !overflow;
    52      if (ret) {
    53          secp256k1_ecdsa_recoverable_signature_save(sig, &r, &s, recid);
    54      } else {
    55          memset(sig, 0, sizeof(*sig));
    56      }
    57      return ret;
    58  }
    59  
    60  int secp256k1_ecdsa_recoverable_signature_serialize_compact(const secp256k1_context* ctx, unsigned char *output64, int *recid, const secp256k1_ecdsa_recoverable_signature* sig) {
    61      secp256k1_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      secp256k1_ecdsa_recoverable_signature_load(ctx, &r, &s, recid, sig);
    69      secp256k1_scalar_get_b32(&output64[0], &r);
    70      secp256k1_scalar_get_b32(&output64[32], &s);
    71      return 1;
    72  }
    73  
    74  int secp256k1_ecdsa_recoverable_signature_convert(const secp256k1_context* ctx, secp256k1_ecdsa_signature* sig, const secp256k1_ecdsa_recoverable_signature* sigin) {
    75      secp256k1_scalar r, s;
    76      int recid;
    77  
    78      VERIFY_CHECK(ctx != NULL);
    79      ARG_CHECK(sig != NULL);
    80      ARG_CHECK(sigin != NULL);
    81  
    82      secp256k1_ecdsa_recoverable_signature_load(ctx, &r, &s, &recid, sigin);
    83      secp256k1_ecdsa_signature_save(sig, &r, &s);
    84      return 1;
    85  }
    86  
    87  static int secp256k1_ecdsa_sig_recover(const secp256k1_scalar *sigr, const secp256k1_scalar* sigs, secp256k1_ge *pubkey, const secp256k1_scalar *message, int recid) {
    88      unsigned char brx[32];
    89      secp256k1_fe fx;
    90      secp256k1_ge x;
    91      secp256k1_gej xj;
    92      secp256k1_scalar rn, u1, u2;
    93      secp256k1_gej qj;
    94      int r;
    95  
    96      if (secp256k1_scalar_is_zero(sigr) || secp256k1_scalar_is_zero(sigs)) {
    97          return 0;
    98      }
    99  
   100      secp256k1_scalar_get_b32(brx, sigr);
   101      r = secp256k1_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 (secp256k1_fe_cmp_var(&fx, &secp256k1_ecdsa_const_p_minus_order) >= 0) {
   106              return 0;
   107          }
   108          secp256k1_fe_add(&fx, &secp256k1_ecdsa_const_order_as_fe);
   109      }
   110      if (!secp256k1_ge_set_xo_var(&x, &fx, recid & 1)) {
   111          return 0;
   112      }
   113      secp256k1_gej_set_ge(&xj, &x);
   114      secp256k1_scalar_inverse_var(&rn, sigr);
   115      secp256k1_scalar_mul(&u1, &rn, message);
   116      secp256k1_scalar_negate(&u1, &u1);
   117      secp256k1_scalar_mul(&u2, &rn, sigs);
   118      secp256k1_ecmult(&qj, &xj, &u2, &u1);
   119      secp256k1_ge_set_gej_var(pubkey, &qj);
   120      return !secp256k1_gej_is_infinity(&qj);
   121  }
   122  
   123  int secp256k1_ecdsa_sign_recoverable(const secp256k1_context* ctx, secp256k1_ecdsa_recoverable_signature *signature, const unsigned char *msghash32, const unsigned char *seckey, secp256k1_nonce_function noncefp, const void* noncedata) {
   124      secp256k1_scalar r, s;
   125      int ret, recid;
   126      VERIFY_CHECK(ctx != NULL);
   127      ARG_CHECK(secp256k1_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 = secp256k1_ecdsa_sign_inner(ctx, &r, &s, &recid, msghash32, seckey, noncefp, noncedata);
   133      secp256k1_ecdsa_recoverable_signature_save(signature, &r, &s, recid);
   134      return ret;
   135  }
   136  
   137  int secp256k1_ecdsa_recover(const secp256k1_context* ctx, secp256k1_pubkey *pubkey, const secp256k1_ecdsa_recoverable_signature *signature, const unsigned char *msghash32) {
   138      secp256k1_ge q;
   139      secp256k1_scalar r, s;
   140      secp256k1_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      secp256k1_ecdsa_recoverable_signature_load(ctx, &r, &s, &recid, signature);
   148      VERIFY_CHECK(recid >= 0 && recid < 4);  /* should have been caught in parse_compact */
   149      secp256k1_scalar_set_b32(&m, msghash32, NULL);
   150      if (secp256k1_ecdsa_sig_recover(&r, &s, &q, &m, recid)) {
   151          secp256k1_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 */