123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175 |
- /*
- * Copyright 2018 Scytl Secure Electronic Voting SA
- *
- * All rights reserved
- *
- * See our extended copyright notice in *file 'Copyright.txt' which is part of this source code package
- */
- /* jshint node:true */
- 'use strict';
- var Exponent = require('./exponent');
- var validator = require('./input-validator');
- var codec = require('scytl-codec');
- module.exports = ZpGroupElement;
- /**
- * @class ZpGroupElement
- * @classdesc Encapsulates a Zp group element. To instantiate this object, use
- * the method {@link MathematicalService.newZpGroupElement}.
- * @property {forge.jsbn.BigInteger} p The modulus of the Zp subgroup to which
- * this Zp group element belongs.
- * @property {forge.jsbn.BigInteger} q The order of the Zp subgroup to which
- * this Zp group element belongs.
- * @property {forge.jsbn.BigInteger} value The value of this Zp group element.
- */
- function ZpGroupElement(p, q, value) {
- this.p = p;
- this.q = q;
- this.value = value;
- Object.freeze(this);
- }
- ZpGroupElement.prototype = {
- /**
- * Multiplies this Zp group element by the Zp group element provided as
- * input, using the formula:
- * <p>
- * <code>(this * element) mod p</code>
- *
- * @function multiply
- * @memberof ZpGroupElement
- * @param {ZpGroupElement}
- * element The element to be multiplied with this element.
- * @returns {ZpGroupElement} The result of the multiplication operation.
- * @throws {Error}
- * If the input data validation fails.
- */
- multiply: function(element) {
- checkZpGroupElement(
- element, 'Zp group element to multiply with this Zp group element',
- this.p, this.q);
- var newValue = this.value.multiply(element.value).mod(this.p);
- return new ZpGroupElement(this.p, this.q, newValue);
- },
- /**
- * Exponentiates this Zp group element with the exponent provided as input,
- * using the formula:
- * <p>
- * <code>(this<sup>exponent</sup>) mod p</code>
- *
- * @function exponentiate
- * @memberof ZpGroupElement
- * @param {Exponent}
- * exponent The exponent to use in the exponentiation.
- * @returns {ZpGroupElement} The result of the exponentiation operation.
- * @throws {Error}
- * If the input data validation fails.
- */
- exponentiate: function(exponent) {
- checkExponent(
- exponent, 'exponent with which to exponentiate this Zp group element',
- this.q);
- var newValue = this.value.modPow(exponent.value, this.p);
- return new ZpGroupElement(this.p, this.q, newValue);
- },
- /**
- * Calculates the inverse of this Zp group element, using the formula:
- * <p>
- * <code>(this<sup>-1</sup>) mod p</code>
- *
- * @function invert
- * @memberof ZpGroupElement
- * @returns {ZpGroupElement} The result of the inverse operation.
- */
- invert: function() {
- var newValue = this.value.modInverse(this.p);
- return new ZpGroupElement(this.p, this.q, newValue);
- },
- /**
- * Checks if this Zp group element is equal to the Zp group element provided
- * as input.
- * <p>
- * Elements are considered equal if:
- * <ul>
- * <li>They belong to the same Zp subgroup.</li>
- * <li>They have the same value.</li>
- * </ul>
- *
- * @function equals
- * @memberof ZpGroupElement
- * @param {ZpGroupElement}
- * element The Zp group element to compare with this Zp group
- * element.
- * @returns {boolean} True if the equality holds, false otherwise.
- * @throws {Error}
- * If the input data validation fails.
- */
- equals: function(element) {
- validator.checkZpGroupElement(
- element, 'Zp group element to compare with this Zp group element');
- if (element.p.equals(this.p) && element.q.equals(this.q) &&
- element.value.equals(this.value)) {
- return true;
- } else {
- return false;
- }
- },
- /**
- * Serializes this object into a JSON string representation.
- * <p>
- * <b>IMPORTANT:</b> This serialization must be exactly the same as the
- * corresponding serialization in the library <code>cryptoLib</code>,
- * implemented in Java, since the two libraries are expected to communicate
- * with each other via these serializations.
- *
- * @function toJson
- * @memberof ZpGroupElement
- * @returns {string} The JSON string representation of this object.
- */
- toJson: function() {
- return JSON.stringify({
- zpGroupElement: {
- p: codec.base64Encode(this.p),
- q: codec.base64Encode(this.q),
- value: codec.base64Encode(this.value)
- }
- });
- }
- };
- function checkZpGroupElement(element, label, p, q) {
- validator.checkZpGroupElement(element, label);
- validator.checkIsInstanceOf(element, ZpGroupElement, 'ZpGroupElement', label);
- var pFound = element.p;
- if (!pFound.equals(p)) {
- throw new Error(
- 'Expected ' + label + ' to belong to Zp subgroup with modulus p: ' + p +
- ' ; Found p: ' + pFound);
- }
- var qFound = element.q;
- if (!qFound.equals(q)) {
- throw new Error(
- 'Expected ' + label + ' to belong to Zp subgroup of order q: ' + q +
- ' ; Found q: ' + qFound);
- }
- }
- function checkExponent(exponent, label, q) {
- validator.checkExponent(exponent, label, q);
- validator.checkIsInstanceOf(exponent, Exponent, 'Exponent', label);
- }
|