github.com/snowblossomcoin/go-ethereum@v1.9.25/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 http://www.opensource.org/licenses/mit-license.php.*
     5   **********************************************************************/
     6  
     7  #ifndef _SECP256K1_MODULE_RECOVERY_MAIN_
     8  #define _SECP256K1_MODULE_RECOVERY_MAIN_
     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      (void)ctx;
    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      (void)ctx;
    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      (void)ctx;
    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_ecmult_context *ctx, 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(&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(ctx, &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 *msg32, const unsigned char *seckey, secp256k1_nonce_function noncefp, const void* noncedata) {
   124      secp256k1_scalar r, s;
   125      secp256k1_scalar sec, non, msg;
   126      int recid;
   127      int ret = 0;
   128      int overflow = 0;
   129      VERIFY_CHECK(ctx != NULL);
   130      ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx));
   131      ARG_CHECK(msg32 != NULL);
   132      ARG_CHECK(signature != NULL);
   133      ARG_CHECK(seckey != NULL);
   134      if (noncefp == NULL) {
   135          noncefp = secp256k1_nonce_function_default;
   136      }
   137  
   138      secp256k1_scalar_set_b32(&sec, seckey, &overflow);
   139      /* Fail if the secret key is invalid. */
   140      if (!overflow && !secp256k1_scalar_is_zero(&sec)) {
   141          unsigned char nonce32[32];
   142          unsigned int count = 0;
   143          secp256k1_scalar_set_b32(&msg, msg32, NULL);
   144          while (1) {
   145              ret = noncefp(nonce32, msg32, seckey, NULL, (void*)noncedata, count);
   146              if (!ret) {
   147                  break;
   148              }
   149              secp256k1_scalar_set_b32(&non, nonce32, &overflow);
   150              if (!secp256k1_scalar_is_zero(&non) && !overflow) {
   151                  if (secp256k1_ecdsa_sig_sign(&ctx->ecmult_gen_ctx, &r, &s, &sec, &msg, &non, &recid)) {
   152                      break;
   153                  }
   154              }
   155              count++;
   156          }
   157          memset(nonce32, 0, 32);
   158          secp256k1_scalar_clear(&msg);
   159          secp256k1_scalar_clear(&non);
   160          secp256k1_scalar_clear(&sec);
   161      }
   162      if (ret) {
   163          secp256k1_ecdsa_recoverable_signature_save(signature, &r, &s, recid);
   164      } else {
   165          memset(signature, 0, sizeof(*signature));
   166      }
   167      return ret;
   168  }
   169  
   170  int secp256k1_ecdsa_recover(const secp256k1_context* ctx, secp256k1_pubkey *pubkey, const secp256k1_ecdsa_recoverable_signature *signature, const unsigned char *msg32) {
   171      secp256k1_ge q;
   172      secp256k1_scalar r, s;
   173      secp256k1_scalar m;
   174      int recid;
   175      VERIFY_CHECK(ctx != NULL);
   176      ARG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx));
   177      ARG_CHECK(msg32 != NULL);
   178      ARG_CHECK(signature != NULL);
   179      ARG_CHECK(pubkey != NULL);
   180  
   181      secp256k1_ecdsa_recoverable_signature_load(ctx, &r, &s, &recid, signature);
   182      VERIFY_CHECK(recid >= 0 && recid < 4);  /* should have been caught in parse_compact */
   183      secp256k1_scalar_set_b32(&m, msg32, NULL);
   184      if (secp256k1_ecdsa_sig_recover(&ctx->ecmult_ctx, &r, &s, &q, &m, recid)) {
   185          secp256k1_pubkey_save(pubkey, &q);
   186          return 1;
   187      } else {
   188          memset(pubkey, 0, sizeof(*pubkey));
   189          return 0;
   190      }
   191  }
   192  
   193  #endif