array-compressor.js 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. /*
  2. * Copyright 2018 Scytl Secure Electronic Voting SA
  3. *
  4. * All rights reserved
  5. *
  6. * See our extended copyright notice in *file 'Copyright.txt' which is part of this source code package
  7. */
  8. /* jshint node:true */
  9. 'use strict';
  10. var ZpGroupElement = require('./zp-group-element');
  11. var Exponent = require('./exponent');
  12. var validator = require('./input-validator');
  13. module.exports = MathematicalArrayCompressor;
  14. /**
  15. * @class MathematicalArrayCompressor
  16. * @classdesc The mathematical array compressor API. To instantiate this object,
  17. * use the method {@link MathematicalService.newArrayCompressor}.
  18. * @hideconstructor
  19. */
  20. function MathematicalArrayCompressor() {}
  21. MathematicalArrayCompressor.prototype = {
  22. /**
  23. * Compresses an array of Zp group elements into a single element.
  24. *
  25. * @function compressZpGroupElements
  26. * @memberof MathematicalArrayCompressor
  27. * @param {ZpGroupElement[]}
  28. * elements The array of Zp group elements to compress.
  29. * @returns {ZpGroupElement} The Zp group element into which all of the Zp
  30. * group elements have been compressed.
  31. * @throws {Error}
  32. * If the input validation fails.
  33. */
  34. compressZpGroupElements: function(elements) {
  35. checkZpGroupElements(elements, 'Zp group elements to compress');
  36. var element = elements[0];
  37. for (var i = 1; i < elements.length; i++) {
  38. element = element.multiply(elements[i]);
  39. }
  40. return element;
  41. },
  42. /**
  43. * Compresses a specified number of trailing elements of an array of Zp
  44. * group elements into a single Zp group element.
  45. *
  46. * @function compressTrailingZpGroupElements
  47. * @memberof MathematicalArrayCompressor
  48. * @param {ZpGroupElement[]}
  49. * elements The array of Zp group elements to compress.
  50. * @param {number}
  51. * numOutputElements The number of output elements required.
  52. * @returns {ZpGroupElement[]} The array of Zp group elements resulting from
  53. * the compression.
  54. * @throws {Error}
  55. * If the input validation fails.
  56. */
  57. compressTrailingZpGroupElements: function(elements, numOutputElements) {
  58. checkZpGroupElements(
  59. elements,
  60. 'Zp group element array for which to compress trailing elements');
  61. validator.checkIsPositiveNumber(
  62. numOutputElements,
  63. 'Number of elements to remain after compressing trailing elements');
  64. var offset = numOutputElements - 1;
  65. var outputElements = elements.slice(0, offset);
  66. var lastElement =
  67. this.compressZpGroupElements(elements.slice(offset, elements.length));
  68. outputElements.push(lastElement);
  69. return outputElements;
  70. },
  71. /**
  72. * Compresses an array of exponents into a single exponent.
  73. *
  74. * @function compressExponents
  75. * @memberof MathematicalArrayCompressor
  76. * @param {Exponent[]}
  77. * exponents The array of exponents to compress.
  78. * @returns {Exponent} The exponent into which all of the exponents have
  79. * been compressed.
  80. * @throws {Error}
  81. * If the input validation fails.
  82. */
  83. compressExponents: function(exponents) {
  84. checkExponents(exponents, 'Exponents to compress');
  85. var exponent = exponents[0];
  86. for (var i = 1; i < exponents.length; i++) {
  87. exponent = exponent.add(exponents[i]);
  88. }
  89. return exponent;
  90. },
  91. /**
  92. * Compresses a specified number of trailing exponents of an array of
  93. * exponents into a single exponent.
  94. *
  95. * @function compressTrailingExponents
  96. * @memberof MathematicalArrayCompressor
  97. * @param {Exponent[]}
  98. * exponents The array of exponents to compress.
  99. * @param {number}
  100. * numOutputExponents The number of output exponents required.
  101. * @returns {Exponent[]} The array of exponents resulting from the
  102. * compression.
  103. * @throws {Error}
  104. * If the input validation fails.
  105. */
  106. compressTrailingExponents: function(exponents, numOutputExponents) {
  107. checkExponents(
  108. exponents, 'Exponent array for which to compress trailing exponents');
  109. validator.checkIsPositiveNumber(
  110. numOutputExponents,
  111. 'Number of exponents to remain after compressing trailing exponents');
  112. var offset = numOutputExponents - 1;
  113. var outputExponents = exponents.slice(0, offset);
  114. var lastExponent =
  115. this.compressExponents(exponents.slice(offset, exponents.length));
  116. outputExponents.push(lastExponent);
  117. return outputExponents;
  118. }
  119. };
  120. function checkZpGroupElements(elements, label) {
  121. validator.checkZpGroupElements(elements, label);
  122. for (var i = 0; i < elements.length; i++) {
  123. validator.checkIsInstanceOf(
  124. elements[i], ZpGroupElement, 'ZpGroupElement',
  125. 'element ' + i + ' of ' + label);
  126. }
  127. }
  128. function checkExponents(exponents, label, q) {
  129. validator.checkExponents(exponents, label, q);
  130. for (var i = 0; i < exponents.length; i++) {
  131. validator.checkIsInstanceOf(
  132. exponents[i], Exponent, 'Exponent', 'exponent ' + i + ' of ' + label);
  133. }
  134. }