UNPKG

pqp

Version:
191 lines (152 loc) 5.86 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _public_key = require('./public_key'); var _public_key2 = _interopRequireDefault(_public_key); var _randomgen = require('../operations/randomgen'); var _randomgen2 = _interopRequireDefault(_randomgen); var _arithmetic = require('../operations/arithmetic'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var McEliece = function () { function McEliece() { _classCallCheck(this, McEliece); this.randgen = new _randomgen2.default(); } _createClass(McEliece, [{ key: 'set_private_key', value: function set_private_key(priv_key) { this.H_0 = priv_key.H_0; this.H_1 = priv_key.H_1; this.G = (0, _arithmetic.mul_poly)(priv_key.H_0, priv_key.H_1inv); // compute public key this.block_length = priv_key.block_length; this.block_error = priv_key.block_error; this.block_weight = priv_key.block_weight; } }, { key: 'get_public_key', value: function get_public_key() { var pub_key = new _public_key2.default(); pub_key.G = this.G; pub_key.block_error = this.block_error; return pub_key; } }, { key: 'encrypt', value: function encrypt(pub_key, m) { // non-constant weight to achieve cipertext indistinguishability var temp = (0, _arithmetic.mul_poly)(pub_key.G, m.clone()); var t = this.randgen.get_random_weight_vector(pub_key.block_length, pub_key.block_error + this.randgen.flip_coin()); var v = temp.add(t).mod(2); t = this.randgen.get_random_weight_vector(pub_key.block_length, pub_key.block_error + this.randgen.flip_coin()); var u = m.add(t).mod(2); return [u, v]; } }, { key: 'syndrome', value: function syndrome(c_0, c_1) { return (0, _arithmetic.mul_poly)(this.H_0, c_0).add((0, _arithmetic.mul_poly)(this.H_1, c_1)).mod(2); } }, { key: 'decrypt', value: function decrypt(c_0, c_1) { var synd = this.syndrome(c_0, c_1); // compute correlations with syndrome var H0_ind = this.H_0.nonzero(); var H1_ind = this.H_1.nonzero(); var kBL = this.block_length; var unsat_H0 = Float32Array.createZero(kBL); H0_ind.forEach(function (i) { for (var j = 0; j < synd.length; ++j) { if (synd[j]) { var idx = (j + kBL - i) % kBL; unsat_H0[idx] += 1; } } }); var unsat_H1 = Float32Array.createZero(kBL); H1_ind.forEach(function (i) { for (var j = 0; j < synd.length; ++j) { if (synd[j]) { var idx = (j + kBL - i) % kBL; unsat_H1[idx] += 1; } } }); var rounds = 10; var delta = 5; var threshold = 100; var r = 0; while (true) { var max_unsat = Math.max(unsat_H0.max(), unsat_H1.max()); // if so, we are done decoding if (max_unsat == 0) { break; } // we have reach the upper bound on rounds if (r >= rounds) { throw new Error('Decryption error'); break; } r += 1; // update threshold if (max_unsat > delta) { threshold = max_unsat - delta; } var round_unsat_H0 = unsat_H0.clone(); var round_unsat_H1 = unsat_H1.clone(); // first block sweep var _loop = function _loop(i) { if (round_unsat_H0[i] <= threshold) { return 'continue'; } H0_ind.forEach(function (j) { var increase = synd[(i + j) % kBL] == 0; H0_ind.forEach(function (k) { var m = (i + j - k + kBL) % kBL; if (increase) unsat_H0[m] += 1;else unsat_H0[m] += -1; }); H1_ind.forEach(function (k) { var m = (i + j - k + kBL) % kBL; if (increase) unsat_H1[m] += 1;else unsat_H1[m] += -1; }); synd[(i + j) % kBL] ^= 1; }); c_0[i] ^= 1; }; for (var i = 0; i < kBL; ++i) { var _ret = _loop(i); if (_ret === 'continue') continue; } // second block sweep var _loop2 = function _loop2(i) { if (round_unsat_H1[i] <= threshold) { return 'continue'; } H1_ind.forEach(function (j) { var increase = synd[(i + j) % kBL] == 0; H0_ind.forEach(function (k) { var m = (i + j - k + kBL) % kBL; if (increase) unsat_H0[m] += 1;else unsat_H0[m] += -1; }); H1_ind.forEach(function (k) { var m = (i + j - k + kBL) % kBL; if (increase) unsat_H1[m] += 1;else unsat_H1[m] += -1; }); synd[(i + j) % kBL] ^= 1; }); c_1[i] ^= 1; }; for (var i = 0; i < kBL; ++i) { var _ret2 = _loop2(i); if (_ret2 === 'continue') continue; } } return c_0; } }]); return McEliece; }(); exports.default = McEliece;