123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149 |
- /*
- * 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 ZpGroupElement = require('./zp-group-element');
- var validator = require('./input-validator');
- var codec = require('scytl-codec');
- var forge = require('node-forge');
- module.exports = ZpSubgroup;
- var BigInteger = forge.jsbn.BigInteger;
- /**
- * Encapsulates a Zp subgroup. To instantiate this object, use the method {@link
- * MathematicalService.newZpSubgroup}.
- * <p>
- * Given a prime <code>p</code>, the Zp group is defined as the set of all
- * <code>Integers (mod p)</code>. A Zp subgroup is a subset of the Zp group,
- * of order <code>q</code>, defined as a set of <code>Primes (mod p)</code>.
- * <p>
- * Both the Zp group and the Zp subgroup are finite cyclic groups, which means
- * that all of their elements can be generated by exponentiating a special Zp
- * group element called the <code>generator</code>.
- * <p>
- * When the modulus <code>p</code> and the order <code>q</code> are related
- * by the restriction, <code>p = 2q + 1</code>, then the Zp subgroup can also
- * be referred to as a quadratic residue group.
- *
- * @class ZpSubgroup
- * @property {forge.jsbn.BigInteger} p The modulus of the Zp subgroup.
- * @property {forge.jsbn.BigInteger} q The order of the Zp subgroup.
- * @property {ZpGroupElement} generator The generator element of the Zp
- * subgroup.
- * @property {ZpGroupElement} identity The identity element of the Zp subgroup.
- */
- function ZpSubgroup(p, q, g) {
- this.p = p;
- this.q = q;
- this.generator = new ZpGroupElement(p, q, g);
- this.identity = new ZpGroupElement(p, q, BigInteger.ONE);
- Object.freeze(this);
- }
- ZpSubgroup.prototype = {
- /**
- * Checks whether a Zp group element provided as input is a member of this
- * Zp subgroup.
- *
- * An element is a member of the Zp subgroup if its value satisfies the
- * following conditions:
- * <ul>
- * <li><code>0 < value < p</code></li>
- * <li><code>value<sup>q</sup> mod p = 1</code></li>
- * </ul>
- *
- * @function isGroupMember
- * @memberof ZpSubgroup
- * @param {ZpGroupElement}
- * element The Zp group element whose group membership is to be
- * checked.
- * @returns {boolean} <code>true</code> if the element provided as input
- * is a member of the subgroup, <code>false</false> otherwise.
- * @throws {Error}
- * If the input data validation fails.
- */
- isGroupMember: function(element) {
- checkZpGroupElement(
- element, 'Zp group element to check for group membership');
- if (element.p.equals(this.p)) {
- return element.value.modPow(this.q, this.p).equals(BigInteger.ONE);
- } else {
- return false;
- }
- },
- /**
- * Checks if this Zp subgroup is equal to the Zp subgroup provided as input.
- *
- * @function equals
- * @memberof ZpSubgroup
- * @param {ZpSubgroup}
- * group The Zp subgroup to compare with this Zp subgroup.
- * @returns {boolean} True if the equality holds, false otherwise.
- * @throws {Error}
- * If the input data validation fails.
- */
- equals: function(group) {
- validator.checkIsInstanceOf(
- group, ZpSubgroup, 'ZpSubgroup',
- 'Zp subgroup to compare with this Zp subgroup');
- if (group.p.equals(this.p) && group.q.equals(this.q) &&
- group.generator.equals(this.generator)) {
- return true;
- } else {
- return false;
- }
- },
- /**
- * Check whether this Zp subgroup is a quadratic residue group, which is
- * defined such that <code>p = 2q + 1</code>.
- *
- * @function isQuadraticResidueGroup
- * @memberof ZpSubgroup
- * @returns {boolean} <code>true</code> if the given group is a quadratic
- * residue group, <code>false</code> otherwise.
- */
- isQuadraticResidueGroup: function() {
- return this.p.equals(
- new BigInteger('2').multiply(this.q).add(BigInteger.ONE));
- },
- /**
- * 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 ZpSubgroup
- * @returns {string} The JSON string representation of this object.
- */
- toJson: function() {
- return JSON.stringify({
- zpSubgroup: {
- p: codec.base64Encode(this.p),
- q: codec.base64Encode(this.q),
- g: codec.base64Encode(this.generator.value)
- }
- });
- }
- };
- function checkZpGroupElement(element, label) {
- validator.checkZpGroupElement(element, label);
- validator.checkIsInstanceOf(element, ZpGroupElement, 'ZpGroupElement', label);
- }
|