zp-group-element.js 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  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 Exponent = require('./exponent');
  11. var validator = require('./input-validator');
  12. var codec = require('scytl-codec');
  13. module.exports = ZpGroupElement;
  14. /**
  15. * @class ZpGroupElement
  16. * @classdesc Encapsulates a Zp group element. To instantiate this object, use
  17. * the method {@link MathematicalService.newZpGroupElement}.
  18. * @property {forge.jsbn.BigInteger} p The modulus of the Zp subgroup to which
  19. * this Zp group element belongs.
  20. * @property {forge.jsbn.BigInteger} q The order of the Zp subgroup to which
  21. * this Zp group element belongs.
  22. * @property {forge.jsbn.BigInteger} value The value of this Zp group element.
  23. */
  24. function ZpGroupElement(p, q, value) {
  25. this.p = p;
  26. this.q = q;
  27. this.value = value;
  28. Object.freeze(this);
  29. }
  30. ZpGroupElement.prototype = {
  31. /**
  32. * Multiplies this Zp group element by the Zp group element provided as
  33. * input, using the formula:
  34. * <p>
  35. * <code>(this * element) mod p</code>
  36. *
  37. * @function multiply
  38. * @memberof ZpGroupElement
  39. * @param {ZpGroupElement}
  40. * element The element to be multiplied with this element.
  41. * @returns {ZpGroupElement} The result of the multiplication operation.
  42. * @throws {Error}
  43. * If the input data validation fails.
  44. */
  45. multiply: function(element) {
  46. checkZpGroupElement(
  47. element, 'Zp group element to multiply with this Zp group element',
  48. this.p, this.q);
  49. var newValue = this.value.multiply(element.value).mod(this.p);
  50. return new ZpGroupElement(this.p, this.q, newValue);
  51. },
  52. /**
  53. * Exponentiates this Zp group element with the exponent provided as input,
  54. * using the formula:
  55. * <p>
  56. * <code>(this<sup>exponent</sup>) mod p</code>
  57. *
  58. * @function exponentiate
  59. * @memberof ZpGroupElement
  60. * @param {Exponent}
  61. * exponent The exponent to use in the exponentiation.
  62. * @returns {ZpGroupElement} The result of the exponentiation operation.
  63. * @throws {Error}
  64. * If the input data validation fails.
  65. */
  66. exponentiate: function(exponent) {
  67. checkExponent(
  68. exponent, 'exponent with which to exponentiate this Zp group element',
  69. this.q);
  70. var newValue = this.value.modPow(exponent.value, this.p);
  71. return new ZpGroupElement(this.p, this.q, newValue);
  72. },
  73. /**
  74. * Calculates the inverse of this Zp group element, using the formula:
  75. * <p>
  76. * <code>(this<sup>-1</sup>) mod p</code>
  77. *
  78. * @function invert
  79. * @memberof ZpGroupElement
  80. * @returns {ZpGroupElement} The result of the inverse operation.
  81. */
  82. invert: function() {
  83. var newValue = this.value.modInverse(this.p);
  84. return new ZpGroupElement(this.p, this.q, newValue);
  85. },
  86. /**
  87. * Checks if this Zp group element is equal to the Zp group element provided
  88. * as input.
  89. * <p>
  90. * Elements are considered equal if:
  91. * <ul>
  92. * <li>They belong to the same Zp subgroup.</li>
  93. * <li>They have the same value.</li>
  94. * </ul>
  95. *
  96. * @function equals
  97. * @memberof ZpGroupElement
  98. * @param {ZpGroupElement}
  99. * element The Zp group element to compare with this Zp group
  100. * element.
  101. * @returns {boolean} True if the equality holds, false otherwise.
  102. * @throws {Error}
  103. * If the input data validation fails.
  104. */
  105. equals: function(element) {
  106. validator.checkZpGroupElement(
  107. element, 'Zp group element to compare with this Zp group element');
  108. if (element.p.equals(this.p) && element.q.equals(this.q) &&
  109. element.value.equals(this.value)) {
  110. return true;
  111. } else {
  112. return false;
  113. }
  114. },
  115. /**
  116. * Serializes this object into a JSON string representation.
  117. * <p>
  118. * <b>IMPORTANT:</b> This serialization must be exactly the same as the
  119. * corresponding serialization in the library <code>cryptoLib</code>,
  120. * implemented in Java, since the two libraries are expected to communicate
  121. * with each other via these serializations.
  122. *
  123. * @function toJson
  124. * @memberof ZpGroupElement
  125. * @returns {string} The JSON string representation of this object.
  126. */
  127. toJson: function() {
  128. return JSON.stringify({
  129. zpGroupElement: {
  130. p: codec.base64Encode(this.p),
  131. q: codec.base64Encode(this.q),
  132. value: codec.base64Encode(this.value)
  133. }
  134. });
  135. }
  136. };
  137. function checkZpGroupElement(element, label, p, q) {
  138. validator.checkZpGroupElement(element, label);
  139. validator.checkIsInstanceOf(element, ZpGroupElement, 'ZpGroupElement', label);
  140. var pFound = element.p;
  141. if (!pFound.equals(p)) {
  142. throw new Error(
  143. 'Expected ' + label + ' to belong to Zp subgroup with modulus p: ' + p +
  144. ' ; Found p: ' + pFound);
  145. }
  146. var qFound = element.q;
  147. if (!qFound.equals(q)) {
  148. throw new Error(
  149. 'Expected ' + label + ' to belong to Zp subgroup of order q: ' + q +
  150. ' ; Found q: ' + qFound);
  151. }
  152. }
  153. function checkExponent(exponent, label, q) {
  154. validator.checkExponent(exponent, label, q);
  155. validator.checkIsInstanceOf(exponent, Exponent, 'Exponent', label);
  156. }