github.com/muhammedhassanm/blockchain@v0.0.0-20200120143007-697261defd4d/sawtooth-core-master/sdk/javascript/signing/secp256k1.js (about)

     1  /**
     2   * Copyright 2017 Intel Corporation
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   *     http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   * ------------------------------------------------------------------------------
    16   */
    17  
    18  'use strict'
    19  
    20  const secp256k1 = require('secp256k1')
    21  const { createHash, randomBytes } = require('crypto')
    22  
    23  const { PrivateKey, PublicKey, Context, ParseError } = require('./core')
    24  
    25  class Secp256k1PrivateKey extends PrivateKey {
    26    /**
    27     * @param {Buffer} privateKeyBytes - the bytes of the private key
    28     */
    29    constructor (privateKeyBytes) {
    30      super()
    31      this.privateKeyBytes = privateKeyBytes
    32    }
    33  
    34    getAlgorithmName () {
    35      return 'secp256k1'
    36    }
    37  
    38    /**
    39     * @return {Buffer} the key in bytes
    40     */
    41    asBytes () {
    42      return Buffer.from(this.privateKeyBytes)
    43    }
    44  
    45    /**
    46     * Creates a private key from a hex encode set of bytes.
    47     *
    48     * @param {string} privateKeyHex - the key in hex
    49     * @return {PrivateKey} a private key instance
    50     * @throws {ParseError} if the private key is not valid
    51     */
    52    static fromHex (privateKeyHex) {
    53      let buffer = Buffer.from(privateKeyHex, 'hex')
    54      // verify that it is either a proper compressed or uncompressed key
    55      if (!secp256k1.privateKeyVerify(buffer) &&
    56          !secp256k1.privateKeyVerify(buffer, false)) {
    57        throw new ParseError('Unable to parse a private key from the given hex')
    58      }
    59      return new Secp256k1PrivateKey(buffer)
    60    }
    61  
    62    static newRandom () {
    63      let privKey
    64      do {
    65        privKey = randomBytes(32)
    66      } while (!secp256k1.privateKeyVerify(privKey))
    67  
    68      return new Secp256k1PrivateKey(privKey)
    69    }
    70  }
    71  
    72  class Secp256k1PublicKey extends PublicKey {
    73    constructor (publicKeyBytes) {
    74      super()
    75      this.publicKeyBytes = publicKeyBytes
    76    }
    77  
    78    getAlgorithmName () {
    79      return 'secp256k1'
    80    }
    81  
    82    /**
    83     * @return {Buffer} the key in bytes
    84     */
    85    asBytes () {
    86      return Buffer.from(this.publicKeyBytes)
    87    }
    88  
    89    /**
    90     * Creates a public key from a hex encode set of bytes.
    91     *
    92     * @param {string} publicKeyHex - the key in hex
    93     * @return {PublicKey} a public key instance
    94     * @throws {ParseError} if the public key is not valid
    95     */
    96    static fromHex (publicKeyHex) {
    97      let buffer = Buffer.from(publicKeyHex, 'hex')
    98      if (!secp256k1.publicKeyVerify(buffer)) {
    99        throw new ParseError('Unable to parse a private key from the given hex')
   100      }
   101      return new Secp256k1PublicKey(buffer)
   102    }
   103  }
   104  
   105  class Secp256k1Context extends Context {
   106    getAlgorithmName () {
   107      return 'secp256k1'
   108    }
   109  
   110    verify (signature, message, publicKey) {
   111      const dataHash = createHash('sha256').update(message).digest()
   112      const sigBytes = Buffer.from(signature, 'hex')
   113  
   114      return secp256k1.verify(dataHash, sigBytes, publicKey.publicKeyBytes)
   115    }
   116  
   117    sign (message, privateKey) {
   118      const dataHash = createHash('sha256').update(message).digest()
   119  
   120      const result = secp256k1.sign(dataHash, privateKey.privateKeyBytes)
   121      return result.signature.toString('hex')
   122    }
   123  
   124    getPublicKey (privateKey) {
   125      return new Secp256k1PublicKey(
   126        secp256k1.publicKeyCreate(privateKey.privateKeyBytes)
   127      )
   128    }
   129  
   130    newRandomPrivateKey () {
   131      return Secp256k1PrivateKey.newRandom()
   132    }
   133  }
   134  
   135  module.exports = {
   136    Secp256k1PrivateKey,
   137    Secp256k1PublicKey,
   138    Secp256k1Context
   139  }