github.com/igggame/nebulas-go@v2.1.0+incompatible/nf/nvm/v8/lib/crypto.cc (about)

     1  // Copyright (C) 2018 go-nebulas authors
     2  // 
     3  // This file is part of the go-nebulas library.
     4  // 
     5  // the go-nebulas library is free software: you can redistribute it and/or modify
     6  // it under the terms of the GNU General Public License as published by
     7  // the Free Software Foundation, either version 3 of the License, or
     8  // (at your option) any later version.
     9  // 
    10  // the go-nebulas library is distributed in the hope that it will be useful,
    11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13  // GNU General Public License for more details.
    14  // 
    15  // You should have received a copy of the GNU General Public License
    16  // along with the go-nebulas library.  If not, see <http://www.gnu.org/licenses/>.
    17  // 
    18  
    19  #include "crypto.h"
    20  #include "../engine.h"
    21  #include "instruction_counter.h"
    22  
    23  static Sha256Func sSha256 = NULL;
    24  static Sha3256Func sSha3256 = NULL;
    25  static Ripemd160Func sRipemd160 = NULL;
    26  static RecoverAddressFunc sRecoverAddress = NULL;
    27  static Md5Func sMd5 = NULL;
    28  static Base64Func sBase64 = NULL;
    29  
    30  void InitializeCrypto(Sha256Func sha256,
    31                                   Sha3256Func sha3256,
    32                                   Ripemd160Func ripemd160,
    33                                   RecoverAddressFunc recoverAddress,
    34                                   Md5Func md5,
    35                                   Base64Func base64) {
    36      sSha256 = sha256;
    37      sSha3256 = sha3256;
    38      sRipemd160 = ripemd160;
    39      sRecoverAddress = recoverAddress;
    40      sMd5 = md5;
    41      sBase64 = base64;
    42  }
    43  
    44  void NewCryptoInstance(Isolate *isolate, Local<Context> context) {
    45    Local<ObjectTemplate> cryptoTpl = ObjectTemplate::New(isolate);
    46  
    47    cryptoTpl->Set(String::NewFromUtf8(isolate, "sha256"),
    48                  FunctionTemplate::New(isolate, Sha256Callback),
    49                  static_cast<PropertyAttribute>(PropertyAttribute::DontDelete |
    50                                                 PropertyAttribute::ReadOnly));
    51  
    52    cryptoTpl->Set(String::NewFromUtf8(isolate, "sha3256"),
    53                  FunctionTemplate::New(isolate, Sha3256Callback),
    54                  static_cast<PropertyAttribute>(PropertyAttribute::DontDelete |
    55                                                 PropertyAttribute::ReadOnly));
    56  
    57    cryptoTpl->Set(String::NewFromUtf8(isolate, "ripemd160"),
    58                  FunctionTemplate::New(isolate, Ripemd160Callback),
    59                  static_cast<PropertyAttribute>(PropertyAttribute::DontDelete |
    60                                                 PropertyAttribute::ReadOnly));
    61  
    62    cryptoTpl->Set(String::NewFromUtf8(isolate, "recoverAddress"),
    63                  FunctionTemplate::New(isolate, RecoverAddressCallback),
    64                  static_cast<PropertyAttribute>(PropertyAttribute::DontDelete |
    65                                                 PropertyAttribute::ReadOnly));
    66    
    67    cryptoTpl->Set(String::NewFromUtf8(isolate, "md5"),
    68                  FunctionTemplate::New(isolate, Md5Callback),
    69                  static_cast<PropertyAttribute>(PropertyAttribute::DontDelete |
    70                                                 PropertyAttribute::ReadOnly));
    71  
    72    cryptoTpl->Set(String::NewFromUtf8(isolate, "base64"),
    73                  FunctionTemplate::New(isolate, Base64Callback),
    74                  static_cast<PropertyAttribute>(PropertyAttribute::DontDelete |
    75                                                 PropertyAttribute::ReadOnly));
    76  
    77    Local<Object> instance = cryptoTpl->NewInstance(context).ToLocalChecked();
    78  
    79    context->Global()->DefineOwnProperty(
    80        context, String::NewFromUtf8(isolate, "_native_crypto"), instance,
    81        static_cast<PropertyAttribute>(PropertyAttribute::DontDelete |
    82                                       PropertyAttribute::ReadOnly));
    83  }
    84  
    85  // Sha256Callback
    86  void Sha256Callback(const FunctionCallbackInfo<Value> &info) {
    87    Isolate *isolate = info.GetIsolate();
    88  
    89    if (info.Length() != 1) {
    90      isolate->ThrowException(String::NewFromUtf8(
    91          isolate, "sha256() requires only 1 argument"));
    92      return;
    93    }
    94  
    95    Local<Value> data = info[0];
    96    if (!data->IsString()) {
    97      isolate->ThrowException(String::NewFromUtf8(isolate, "sha256() requires a string argument"));
    98      return;
    99    }
   100  
   101    size_t cnt = 0;
   102  
   103    char *value = sSha256(*String::Utf8Value(data->ToString()), &cnt);
   104    if (value == NULL) {
   105      info.GetReturnValue().SetNull();
   106    } else {
   107      info.GetReturnValue().Set(String::NewFromUtf8(isolate, value));
   108      free(value);
   109    }
   110  
   111    // record storage usage.
   112    IncrCounter(isolate, isolate->GetCurrentContext(), cnt);
   113  }
   114  
   115  // Sha3256Callback
   116  void Sha3256Callback(const FunctionCallbackInfo<Value> &info) {
   117    Isolate *isolate = info.GetIsolate();
   118  
   119    if (info.Length() != 1) {
   120      isolate->ThrowException(String::NewFromUtf8(
   121          isolate, "sha3256() requires only 1 argument"));
   122      return;
   123    }
   124  
   125    Local<Value> data = info[0];
   126    if (!data->IsString()) {
   127      isolate->ThrowException(String::NewFromUtf8(isolate, "sha3256() requires a string argument"));
   128      return;
   129    }
   130  
   131    size_t cnt = 0;
   132  
   133    char *value = sSha3256(*String::Utf8Value(data->ToString()), &cnt);
   134    if (value == NULL) {
   135      info.GetReturnValue().SetNull();
   136    } else {
   137      info.GetReturnValue().Set(String::NewFromUtf8(isolate, value));
   138      free(value);
   139    }
   140  
   141    // record storage usage.
   142    IncrCounter(isolate, isolate->GetCurrentContext(), cnt);
   143  }
   144  
   145  // Ripemd160Callback
   146  void Ripemd160Callback(const FunctionCallbackInfo<Value> &info) {
   147    Isolate *isolate = info.GetIsolate();
   148  
   149    if (info.Length() != 1) {
   150      isolate->ThrowException(String::NewFromUtf8(
   151          isolate, "ripemd160() requires only 1 argument"));
   152      return;
   153    }
   154  
   155    Local<Value> data = info[0];
   156    if (!data->IsString()) {
   157      isolate->ThrowException(String::NewFromUtf8(isolate, "ripemd160() requires a string argument"));
   158      return;
   159    }
   160  
   161    size_t cnt = 0;
   162  
   163    char *value = sRipemd160(*String::Utf8Value(data->ToString()), &cnt);
   164    if (value == NULL) {
   165      info.GetReturnValue().SetNull();
   166    } else {
   167      info.GetReturnValue().Set(String::NewFromUtf8(isolate, value));
   168      free(value);
   169    }
   170  
   171    // record storage usage.
   172    IncrCounter(isolate, isolate->GetCurrentContext(), cnt);
   173  }
   174  
   175  // RecoverAddressCallback
   176  void RecoverAddressCallback(const FunctionCallbackInfo<Value> &info) {
   177    Isolate *isolate = info.GetIsolate();
   178  
   179    if (info.Length() != 3) {
   180      isolate->ThrowException(String::NewFromUtf8(
   181          isolate, "recoverAddress() requires 3 arguments"));
   182      return;
   183    }
   184  
   185    Local<Value> alg = info[0];
   186    if (!alg->IsInt32()) {
   187      isolate->ThrowException(
   188          String::NewFromUtf8(isolate, "recoverAddress(): 1st arg should be integer"));
   189      return;
   190    }
   191  
   192    Local<Value> data = info[1];
   193    if (!data->IsString()) {
   194      isolate->ThrowException(
   195          String::NewFromUtf8(isolate, "recoverAddress(): 2nd arg should be string"));
   196      return;
   197    }
   198  
   199    Local<Value> sign = info[2];
   200    if (!sign->IsString()) {
   201      isolate->ThrowException(
   202          String::NewFromUtf8(isolate, "recoverAddress(): 3rd arg should be string"));
   203      return;
   204    }
   205  
   206    size_t cnt = 0;
   207  
   208    char *value = sRecoverAddress(alg->ToInt32()->Int32Value(), *String::Utf8Value(data->ToString()), 
   209                                 *String::Utf8Value(sign->ToString()), &cnt);
   210    if (value == NULL) {
   211      info.GetReturnValue().SetNull();
   212    } else {
   213      info.GetReturnValue().Set(String::NewFromUtf8(isolate, value));
   214      free(value);
   215    }
   216  
   217    // record storage usage.
   218    IncrCounter(isolate, isolate->GetCurrentContext(), cnt);
   219  }
   220  
   221  // Md5Callback
   222  void Md5Callback(const FunctionCallbackInfo<Value> &info) {
   223    Isolate *isolate = info.GetIsolate();
   224  
   225    if (info.Length() != 1) {
   226      isolate->ThrowException(String::NewFromUtf8(
   227          isolate, "md5() requires only 1 argument"));
   228      return;
   229    }
   230  
   231    Local<Value> data = info[0];
   232    if (!data->IsString()) {
   233      isolate->ThrowException(String::NewFromUtf8(isolate, "md5() requires a string argument"));
   234      return;
   235    }
   236  
   237    size_t cnt = 0;
   238  
   239    char *value = sMd5(*String::Utf8Value(data->ToString()), &cnt);
   240    if (value == NULL) {
   241      info.GetReturnValue().SetNull();
   242    } else {
   243      info.GetReturnValue().Set(String::NewFromUtf8(isolate, value));
   244      free(value);
   245    }
   246  
   247    // record storage usage.
   248    IncrCounter(isolate, isolate->GetCurrentContext(), cnt);
   249  }
   250  
   251  // Base64Callback
   252  void Base64Callback(const FunctionCallbackInfo<Value> &info) {
   253    Isolate *isolate = info.GetIsolate();
   254  
   255    if (info.Length() != 1) {
   256      isolate->ThrowException(String::NewFromUtf8(
   257          isolate, "base64() requires only 1 argument"));
   258      return;
   259    }
   260  
   261    Local<Value> data = info[0];
   262    if (!data->IsString()) {
   263      isolate->ThrowException(String::NewFromUtf8(isolate, "base64() requires a string argument"));
   264      return;
   265    }
   266  
   267    size_t cnt = 0;
   268  
   269    char *value = sBase64(*String::Utf8Value(data->ToString()), &cnt);
   270    if (value == NULL) {
   271      info.GetReturnValue().SetNull();
   272    } else {
   273      info.GetReturnValue().Set(String::NewFromUtf8(isolate, value));
   274      free(value);
   275    }
   276  
   277    // record storage usage.
   278    IncrCounter(isolate, isolate->GetCurrentContext(), cnt);
   279  }