UNPKG

crypto-conditions

Version:

Implementation of crypto-conditions in JavaScript

248 lines (199 loc) 8.19 kB
"use strict"; var _Reflect$construct = require("@babel/runtime-corejs3/core-js-stable/reflect/construct"); var _Object$defineProperty = require("@babel/runtime-corejs3/core-js-stable/object/define-property"); var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault"); _Object$defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/createClass")); var _inherits2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/inherits")); var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/possibleConstructorReturn")); var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/getPrototypeOf")); var _tweetnacl = require("tweetnacl"); var _baseSha = _interopRequireDefault(require("./base-sha256")); var _missingDataError = _interopRequireDefault(require("../errors/missing-data-error")); var _validationError = _interopRequireDefault(require("../errors/validation-error")); var _bufferToUintArray = _interopRequireDefault(require("../util/buffer-to-uint-array")); var _fingerprint = require("../schemas/fingerprint"); function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = _Reflect$construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; } function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !_Reflect$construct) return false; if (_Reflect$construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(_Reflect$construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } var ed25519; try { ed25519 = require('ed25519'); } catch (err) {} /** * ED25519: Ed25519 signature condition. * * This condition implements Ed25519 signatures. * * ED25519 is assigned the type ID 4. It relies only on the ED25519 feature * suite which corresponds to a bitmask of 0x20. */ var Ed25519Sha256 = /*#__PURE__*/function (_BaseSha) { (0, _inherits2.default)(Ed25519Sha256, _BaseSha); var _super = _createSuper(Ed25519Sha256); function Ed25519Sha256() { var _this; (0, _classCallCheck2.default)(this, Ed25519Sha256); _this = _super.call(this); _this.publicKey = null; _this.signature = null; return _this; } /** * Set the public publicKey. * * This is the Ed25519 public key. It has to be provided as a buffer. * * @param {Buffer} publicKey Public Ed25519 publicKey */ (0, _createClass2.default)(Ed25519Sha256, [{ key: "setPublicKey", value: function setPublicKey(publicKey) { if (!Buffer.isBuffer(publicKey)) { throw new TypeError('Public key must be a Buffer, was: ' + publicKey); } if (publicKey.length !== 32) { throw new Error('Public key must be 32 bytes, was: ' + publicKey.length); } // TODO Validate public key this.publicKey = publicKey; } /** * Set the signature. * * Instead of using the private key to sign using the sign() method, we can * also generate the signature elsewhere and pass it in. * * @param {Buffer} signature 64-byte signature. */ }, { key: "setSignature", value: function setSignature(signature) { if (!Buffer.isBuffer(signature)) { throw new TypeError('Signature must be a Buffer, was: ' + signature); } if (signature.length !== 64) { throw new Error('Signature must be 64 bytes, was: ' + signature.length); } this.signature = signature; } /** * Sign a message. * * This method will take a message and an Ed25519 private key and store a * corresponding signature in this fulfillment. * * @param {Buffer} message Message to sign. * @param {Buffer} privateKey Ed25519 private key. */ }, { key: "sign", value: function sign(message, privateKey) { if (!Buffer.isBuffer(message)) { throw new _missingDataError.default('Message must be a Buffer'); } if (!Buffer.isBuffer(privateKey)) { throw new TypeError('Private key must be a Buffer, was: ' + privateKey); } if (privateKey.length !== 32) { throw new Error('Private key must be 32 bytes, was: ' + privateKey.length); } // This would be the Ed25519ph version: // message = crypto.createHash('sha512') // .update(message) // .digest() // Use native library if available (~65x faster) if (ed25519) { var keyPair = ed25519.MakeKeypair(privateKey); this.setPublicKey(keyPair.publicKey); this.signature = ed25519.Sign(message, keyPair); } else { var _keyPair = _tweetnacl.sign.keyPair.fromSeed((0, _bufferToUintArray.default)(privateKey)); this.setPublicKey(Buffer.from(_keyPair.publicKey)); this.signature = Buffer.from(_tweetnacl.sign.detached((0, _bufferToUintArray.default)(message), _keyPair.secretKey)); } } }, { key: "parseJson", value: function parseJson(json) { this.setPublicKey(Buffer.from(json.publicKey, 'base64')); this.setSignature(Buffer.from(json.signature, 'base64')); } /** * Produce the contents of the condition hash. * * This function is called internally by the `getCondition` method. * * @return {Buffer} Encoded contents of fingerprint hash. * * @private */ }, { key: "getFingerprintContents", value: function getFingerprintContents() { if (!this.publicKey) { throw new _missingDataError.default('Requires public key'); } return _fingerprint.Ed25519FingerprintContents.encode({ publicKey: this.publicKey }); } }, { key: "getAsn1JsonPayload", value: function getAsn1JsonPayload() { return { publicKey: this.publicKey, signature: this.signature }; } /** * Calculate the cost of fulfilling this condition. * * The cost of the Ed25519 condition is 2^17 = 131072. * * @return {Number} Expected maximum cost to fulfill this condition * @private */ }, { key: "calculateCost", value: function calculateCost() { return Ed25519Sha256.CONSTANT_COST; } /** * Verify the signature of this Ed25519 fulfillment. * * The signature of this Ed25519 fulfillment is verified against the provided * message and public key. * * @param {Buffer} message Message to validate against. * @return {Boolean} Whether this fulfillment is valid. */ }, { key: "validate", value: function validate(message) { if (!Buffer.isBuffer(message)) { throw new TypeError('Message must be a Buffer'); } // Use native library if available (~60x faster) var result; if (ed25519) { result = ed25519.Verify(message, this.signature, this.publicKey); } else { result = _tweetnacl.sign.detached.verify((0, _bufferToUintArray.default)(message), (0, _bufferToUintArray.default)(this.signature), (0, _bufferToUintArray.default)(this.publicKey)); } if (result !== true) { throw new _validationError.default('Invalid ed25519 signature'); } return true; } }]); return Ed25519Sha256; }(_baseSha.default); Ed25519Sha256.TYPE_ID = 4; Ed25519Sha256.TYPE_NAME = 'ed25519-sha-256'; Ed25519Sha256.TYPE_ASN1_CONDITION = 'ed25519Sha256Condition'; Ed25519Sha256.TYPE_ASN1_FULFILLMENT = 'ed25519Sha256Fulfillment'; Ed25519Sha256.TYPE_CATEGORY = 'simple'; Ed25519Sha256.CONSTANT_COST = 131072; var _default = Ed25519Sha256; exports.default = _default;