github.com/ethereumproject/go-ethereum@v5.5.2+incompatible/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  
    67      secp256k1_ecdsa_recoverable_signature_load(ctx, &r, &s, recid, sig);
    68      secp256k1_scalar_get_b32(&output64[0], &r);
    69      secp256k1_scalar_get_b32(&output64[32], &s);
    70      return 1;
    71  }
    72  
    73  int secp256k1_ecdsa_recoverable_signature_convert(const secp256k1_context* ctx, secp256k1_ecdsa_signature* sig, const secp256k1_ecdsa_recoverable_signature* sigin) {
    74      secp256k1_scalar r, s;
    75      int recid;
    76  
    77      (void)ctx;
    78      ARG_CHECK(sig != NULL);
    79      ARG_CHECK(sigin != NULL);
    80  
    81      secp256k1_ecdsa_recoverable_signature_load(ctx, &r, &s, &recid, sigin);
    82      secp256k1_ecdsa_signature_save(sig, &r, &s);
    83      return 1;
    84  }
    85  
    86  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) {
    87      secp256k1_scalar r, s;
    88      secp256k1_scalar sec, non, msg;
    89      int recid;
    90      int ret = 0;
    91      int overflow = 0;
    92      VERIFY_CHECK(ctx != NULL);
    93      ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx));
    94      ARG_CHECK(msg32 != NULL);
    95      ARG_CHECK(signature != NULL);
    96      ARG_CHECK(seckey != NULL);
    97      if (noncefp == NULL) {
    98          noncefp = secp256k1_nonce_function_default;
    99      }
   100  
   101      secp256k1_scalar_set_b32(&sec, seckey, &overflow);
   102      /* Fail if the secret key is invalid. */
   103      if (!overflow && !secp256k1_scalar_is_zero(&sec)) {
   104          unsigned int count = 0;
   105          secp256k1_scalar_set_b32(&msg, msg32, NULL);
   106          while (1) {
   107              unsigned char nonce32[32];
   108              ret = noncefp(nonce32, seckey, msg32, NULL, (void*)noncedata, count);
   109              if (!ret) {
   110                  break;
   111              }
   112              secp256k1_scalar_set_b32(&non, nonce32, &overflow);
   113              memset(nonce32, 0, 32);
   114              if (!secp256k1_scalar_is_zero(&non) && !overflow) {
   115                  if (secp256k1_ecdsa_sig_sign(&ctx->ecmult_gen_ctx, &r, &s, &sec, &msg, &non, &recid)) {
   116                      break;
   117                  }
   118              }
   119              count++;
   120          }
   121          secp256k1_scalar_clear(&msg);
   122          secp256k1_scalar_clear(&non);
   123          secp256k1_scalar_clear(&sec);
   124      }
   125      if (ret) {
   126          secp256k1_ecdsa_recoverable_signature_save(signature, &r, &s, recid);
   127      } else {
   128          memset(signature, 0, sizeof(*signature));
   129      }
   130      return ret;
   131  }
   132  
   133  int secp256k1_ecdsa_recover(const secp256k1_context* ctx, secp256k1_pubkey *pubkey, const secp256k1_ecdsa_recoverable_signature *signature, const unsigned char *msg32) {
   134      secp256k1_ge q;
   135      secp256k1_scalar r, s;
   136      secp256k1_scalar m;
   137      int recid;
   138      VERIFY_CHECK(ctx != NULL);
   139      ARG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx));
   140      ARG_CHECK(msg32 != NULL);
   141      ARG_CHECK(signature != NULL);
   142      ARG_CHECK(pubkey != NULL);
   143  
   144      secp256k1_ecdsa_recoverable_signature_load(ctx, &r, &s, &recid, signature);
   145      ARG_CHECK(recid >= 0 && recid < 4);
   146      secp256k1_scalar_set_b32(&m, msg32, NULL);
   147      if (secp256k1_ecdsa_sig_recover(&ctx->ecmult_ctx, &r, &s, &q, &m, recid)) {
   148          secp256k1_pubkey_save(pubkey, &q);
   149          return 1;
   150      } else {
   151          memset(pubkey, 0, sizeof(*pubkey));
   152          return 0;
   153      }
   154  }
   155  
   156  #endif