exonum-client-cis
Version:
Light Client for Exonum CIS Blockchain
243 lines (202 loc) • 7.73 kB
JavaScript
"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();
}