UNPKG

exonum-client-cis

Version:

Light Client for Exonum CIS Blockchain

243 lines (202 loc) 7.73 kB
"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.hash = hash; exports.sign = sign; exports.verifySignature = verifySignature; exports.keyPair = keyPair; exports.fromSeed = fromSeed; exports.randomUint64 = randomUint64; exports.SIGNATURE_LENGTH = exports.HASH_LENGTH = exports.SECRET_KEY_LENGTH = exports.PUBLIC_KEY_LENGTH = void 0; var _bigInteger = _interopRequireDefault(require("big-integer")); var _tweetnacl = _interopRequireDefault(require("tweetnacl")); var _exonumWebcryptoGost = _interopRequireWildcard(require("../third-party/exonum-webcrypto-gost")); var _generic = require("../types/generic"); var _message = require("../types/message"); var validate = _interopRequireWildcard(require("../types/validate")); var convert = _interopRequireWildcard(require("../types/convert")); var PUBLIC_KEY_LENGTH = 64; exports.PUBLIC_KEY_LENGTH = PUBLIC_KEY_LENGTH; var SECRET_KEY_LENGTH = 32; exports.SECRET_KEY_LENGTH = SECRET_KEY_LENGTH; var HASH_LENGTH = 32; exports.HASH_LENGTH = HASH_LENGTH; var SIGNATURE_LENGTH = 64; /** * Get GOST R 34.11 hash * @param {Object|Array|Uint8Array} data - object of NewType type or array of 8-bit integers * @param {Type|Transaction} [type] - optional, used only if data of {Object} type is passed * @return {string} */ exports.SIGNATURE_LENGTH = SIGNATURE_LENGTH; function hash(data, type) { var buffer; var hasher = new _exonumWebcryptoGost.GostDigest({ name: 'GOST R 34.11', version: 2012 }); var digest; if ((0, _generic.isType)(type)) { buffer = type.serialize(data); } else if ((0, _message.isTransaction)(type)) { var payloadBuffer = data.schema.encode(data.payload).finish(); var chainIdBytesBuffer = data.chainIdBytes; var authorBuffer = convert.hexadecimalToUint8Array(data.author); var merged = new Uint8Array(chainIdBytesBuffer.length + payloadBuffer.length + authorBuffer.length); merged.set(chainIdBytesBuffer); merged.set(payloadBuffer, chainIdBytesBuffer.length); merged.set(authorBuffer, chainIdBytesBuffer.length + payloadBuffer.length); buffer = merged; } else { if (type !== undefined) { throw new TypeError('Wrong type of data.'); } if (data instanceof Uint8Array) { buffer = data; } else { if (!Array.isArray(data)) { throw new TypeError('Invalid data parameter.'); } buffer = new Uint8Array(data); } } digest = hasher.digest(new Uint8Array(buffer)); return convert.uint8ArrayToHexadecimal(new Uint8Array(digest)); } /** * Get GOST R 34.10 signature * @param {string} secretKey * @param {Object|Array} data - object of NewType type or array of 8-bit integers * @param {Type|Transaction} [type] - optional, used only if data of {Object} type is passed * @return {Promise<string>} */ function sign(secretKey, data, type) { var coding = new _exonumWebcryptoGost.GostCoding(); var buffer; if (!validate.validateHexadecimal(secretKey, SECRET_KEY_LENGTH)) { throw new TypeError('secretKey of wrong type is passed. Hexadecimal expected.'); } if ((0, _generic.isType)(type)) { buffer = new Uint8Array(type.serialize(data)); } else if ((0, _message.isTransaction)(type)) { var ser = new Uint8Array(type.serialize(data)); var chainIdBytesBuffer = new Uint8Array(type.chain_id_bytes); buffer = new Uint8Array(chainIdBytesBuffer.length + ser.length); buffer.set(chainIdBytesBuffer); buffer.set(ser, chainIdBytesBuffer.length); } else { if (type !== undefined) { throw new TypeError('Wrong type of data.'); } if (data instanceof Uint8Array) { buffer = data; } else { if (!Array.isArray(data)) { throw new TypeError('Invalid data parameter.'); } buffer = new Uint8Array(data); } } var secretKeyBuf = coding.Hex.decode(secretKey); return _exonumWebcryptoGost["default"].subtle.importKey('raw', secretKeyBuf, { id: 'id-tc26-gost3410-12-256', keySize: 32, length: 256, mode: 'SIGN', name: 'GOST R 34.10', namedCurve: 'S-256-A', procreator: 'CP', version: 2012 }, false, ['sign']).then(function (key) { return _exonumWebcryptoGost["default"].subtle.sign('GOST R 34.10/GOST R 34.11', key, buffer); }).then(function (signature) { return coding.Hex.encode(signature, 'big').split(/[^0-9a-f]+/).join(''); }); } /** * Verifies GOST R 34.10 signature * @param {string} signature * @param {string} publicKey * @param {Object|Array} data - object of NewType type or array of 8-bit integers * @param {Type|Transaction} [type] - optional, used only if data of {Object} type is passed * @return {Promise<boolean>} */ function verifySignature(signature, publicKey, data, type) { var buffer; if (!validate.validateHexadecimal(signature, SIGNATURE_LENGTH)) { throw new TypeError('Signature of wrong type is passed. Hexadecimal expected.'); } if (!validate.validateHexadecimal(publicKey, PUBLIC_KEY_LENGTH)) { throw new TypeError('publicKey of wrong type is passed. Hexadecimal expected.'); } if ((0, _generic.isType)(type)) { buffer = new Uint8Array(type.serialize(data)); } else if ((0, _message.isTransaction)(type)) { var ser = new Uint8Array(type.serialize(data)); var chainIdBytesBuffer = new Uint8Array(type.chain_id_bytes); buffer = new Uint8Array(chainIdBytesBuffer.length + ser.length); buffer.set(chainIdBytesBuffer); buffer.set(ser, chainIdBytesBuffer.length); } else if (type === undefined) { if (data instanceof Uint8Array) { buffer = data; } else if (Array.isArray(data)) { buffer = new Uint8Array(data); } } else { throw new TypeError('Wrong type of data.'); } var signatureBuf = _exonumWebcryptoGost["default"].coding.Hex.decode(signature, 'big'); var publicKeyBuf = _exonumWebcryptoGost["default"].coding.Hex.decode(publicKey); return _exonumWebcryptoGost["default"].subtle.importKey('raw', publicKeyBuf, { name: 'GOST R 34.10-256/VN', id: 'id-tc26-gost3410-12-256', namedCurve: 'S-256-A' }, true, ['verify']).then(function (key) { return _exonumWebcryptoGost["default"].subtle.verify('GOST R 34.10/GOST R 34.11', key, signatureBuf, new Uint8Array(buffer)); }); } /** * Generate random pair of publicKey and secretKey * @return {Promise<Object>} * publicKey {string} * secretKey {string} */ function keyPair() { return _exonumWebcryptoGost["default"].subtle.generateKey({ name: 'GOST R 34.10-256/VN' }, true, ['sign', 'verify']).then(function (pair) { return { publicKey: convert.uint8ArrayToHexadecimal(new Uint8Array(pair.publicKey.buffer)), secretKey: convert.uint8ArrayToHexadecimal(new Uint8Array(pair.privateKey.buffer)) }; }); } /** * Returns a new signing key pair generated deterministically from a 32-byte seed * @return {Object} * publicKey {string} * secretKey {Promise<string>} */ function fromSeed(seed) { var pair = _exonumWebcryptoGost["default"].subtle.generateKey(seed); var publicKey = convert.uint8ArrayToHexadecimal(pair.publicKey); var secretKey = convert.uint8ArrayToHexadecimal(pair.secretKey); return new Promise(function (resolve) { return resolve({ publicKey: publicKey, secretKey: secretKey }); }); } /** * Get random number of cryptographic quality * @returns {string} */ function randomUint64() { var buffer = _tweetnacl["default"].randomBytes(8); return _bigInteger["default"].fromArray(Array.from(buffer), 256).toString(); }