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 }