123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262 |
- /*
- * 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 ZpSubgroup = require('./zp-subgroup');
- var ZpGroupElement = require('./zp-group-element');
- var Exponent = require('./exponent');
- var MathematicalArrayCompressor = require('./array-compressor');
- var MathematicalRandomGenerator = require('./random-generator');
- var MathematicalGroupHandler = require('./group-handler');
- var secureRandom = require('scytl-securerandom');
- var validator = require('./input-validator');
- var codec = require('scytl-codec');
- var forge = require('node-forge');
- var BigInteger = forge.jsbn.BigInteger;
- module.exports = MathematicalService;
- /**
- * @class MathematicalService
- * @classdesc The mathematical service API. To instantiate this object, use the
- * method {@link newService}.
- * @hideconstructor
- * @param {Object}
- * [options] An object containing optional arguments.
- * @param {SecureRandomService}
- * [options.secureRandomService=Created internally] The secure random
- * service to use.
- */
- function MathematicalService(options) {
- options = options || {};
- var secureRandomService;
- if (options.secureRandomService) {
- secureRandomService = options.secureRandomService;
- } else {
- secureRandomService = secureRandom.newService();
- }
- /**
- * Creates a new MathematicalRandomGenerator object for generating random
- * mathematical objects.
- *
- * @function newRandomGenerator
- * @memberof MathematicalService
- * @returns {MathematicalRandomGenerator} The new
- * MathematicalRandomGenerator object.
- */
- this.newRandomGenerator = function() {
- return new MathematicalRandomGenerator(secureRandomService);
- };
- }
- MathematicalService.prototype = {
- /**
- * Creates a new ZpSubgroup object, which encapsulates a Zp subgroup.
- *
- * @function newZpSubgroup
- * @memberof MathematicalService
- * @param {forge.jsbn.BigInteger|string}
- * pOrJson The modulus of the Zp subgroup <b>OR</b> a JSON
- * string representation of a ZpSubgroup object, compatible with
- * its <code>toJson</code> method. For the latter case, any
- * additional input arguments will be ignored.
- * @param {forge.jsbn.BigInteger}
- * q The order of the Zp subgroup. It must be within the range
- * <code>[1, p-1]</code>.
- * @param {forge.jsbn.BigInteger}
- * g The generator of the Zp subgroup. It must be within the
- * range <code>[2, p-1]</code>.
- * @returns {ZpSubgroup} The new ZpSubgroup object.
- * @throws {Error}
- * If the input data validation fails.
- */
- newZpSubgroup: function(pOrJson, q, g) {
- if (typeof pOrJson !== 'string') {
- validator.checkZpSubgroupModulus(
- pOrJson, 'Modulus p to create new ZpSubgroup object');
- validator.checkZpSubgroupOrder(
- q, 'Order q to create new ZpSubgroup object', pOrJson);
- validator.checkZpSubgroupGenerator(
- g, 'Generator to create new ZpSubgroup object', pOrJson);
- return new ZpSubgroup(pOrJson, q, g);
- } else {
- return jsonToZpSubgroup(pOrJson);
- }
- },
- /**
- * Creates a new ZpGroupElement object, which encapsulates a Zp group
- * element.
- *
- * @function newZpGroupElement
- * @memberof MathematicalService
- * @param {forge.jsbn.BigInteger|string}
- * pOrJson The modulus of the Zp subgroup to which the Zp group
- * element belongs <b>OR</b> a JSON string representation of a
- * ZpGroupElement object, compatible with its <code>toJson</code>
- * method. For the latter case, any additional input arguments
- * will be ignored.
- * @param {forge.jsbn.BigInteger}
- * q The order of the Zp subgroup to which the Zp group element
- * belongs. It must be within the range <code>[1, p-1]</code>.
- * @param {forge.jsbn.BigInteger}
- * value The value of the Zp group element. It must be within the
- * range <code>[1, p-1]</code>.
- * @returns {ZpGroupElement} The new ZpGroupElement object.
- * @throws {Error}
- * If the input data validation fails.
- */
- newZpGroupElement: function(pOrJson, q, value) {
- if (typeof pOrJson !== 'string') {
- validator.checkZpSubgroupModulus(
- pOrJson, 'Modulus p to create new ZpGroupElement object');
- validator.checkZpSubgroupOrder(
- q, 'Order q to create new ZpGroupElement object', pOrJson);
- validator.checkZpGroupElementValue(
- value, 'Value to create new ZpGroupElement object', pOrJson);
- return new ZpGroupElement(pOrJson, q, value);
- } else {
- return jsonToZpGroupElement(pOrJson);
- }
- },
- /**
- * Creates a new Exponent object, which encapsulates an exponent.
- *
- * @function newExponent
- * @memberof MathematicalService
- * @param {forge.jsbn.BigInteger|string}
- * qOrJson The order of the Zp subgroup to which the exponent is
- * associated <b>OR</b> a JSON string representation of an
- * Exponent object, compatible with its <code>toJson</code>
- * method. For the latter case, any additional input arguments
- * will be ignored.
- * @param {forge.jsbn.BigInteger}
- * value The value of the exponent. If this value is greater than
- * or equal to <code>q</code> it will be adjusted to be less
- * then <code>q</code>, via the <code>mod(q)</code>
- * operation.
- * @returns {Exponent} The new Exponent object.
- * @throws {Error}
- * If the input data validation fails.
- */
- newExponent: function(qOrJson, value) {
- if (typeof qOrJson !== 'string') {
- validator.checkZpSubgroupOrder(
- qOrJson, 'Order q to create new Exponent object');
- validator.checkExponentValue(
- value, 'Value to create new Exponent object');
- return new Exponent(qOrJson, value);
- } else {
- return jsonToExponent(qOrJson);
- }
- },
- /**
- * Creates a new quadratic residue Zp subgroup from the modulus
- * <code>p</code> and <code>generator</code> provided as input.
- * <p>
- * <b>NOTE</b>: This method creates a particular type of Zp subgroup, with
- * the following property:
- * <p>
- * <code>p = 2q + 1</code>
- *
- * @function newQuadraticResidueGroup
- * @memberof MathematicalService
- * @param {forge.jsbn.BigInteger}
- * p The modulus of the quadratic residue group.
- * @param {forge.jsbn.BigInteger}
- * g The generator of the quadratic residue group.
- * @returns {ZpSubgroup} The quadratic residue group.
- * @throws {Error}
- * If the input validation fails.
- */
- newQuadraticResidueGroup: function(p, g) {
- validator.checkZpSubgroupModulus(
- p, 'Modulus p for quadratic residue group generation');
- validator.checkZpSubgroupGenerator(
- g, 'Generator for quadratic residue group generation', p);
- var q = p.subtract(BigInteger.ONE).divide(new BigInteger('2'));
- return new ZpSubgroup(p, q, g);
- },
- /**
- * Creates a new MathematicalArrayCompressor object for reducing the size of
- * arrays containing mathematical objects.
- *
- * @function newArrayCompressor
- * @memberof MathematicalService
- * @returns {MathematicalArrayCompressor} The new
- * MathematicalArrayCompressor object.
- */
- newArrayCompressor: function() {
- return new MathematicalArrayCompressor();
- },
- /**
- * Creates a new MathematicalGroupHandler object for performing operations
- * involving mathematical groups.
- *
- * @function newGroupHandler
- * @memberof MathematicalService
- * @returns {MathematicalGroupHandler} The new MathematicalGroupHandler
- * object.
- */
- newGroupHandler: function() {
- return new MathematicalGroupHandler();
- }
- };
- function jsonToZpSubgroup(json) {
- validator.checkIsJsonString(
- json, 'JSON string representation of ZpSubgroup object');
- var parsed = JSON.parse(json);
- var p = codec.bytesToBigInteger(codec.base64Decode(parsed.zpSubgroup.p));
- var q = codec.bytesToBigInteger(codec.base64Decode(parsed.zpSubgroup.q));
- var g = codec.bytesToBigInteger(codec.base64Decode(parsed.zpSubgroup.g));
- return new ZpSubgroup(p, q, g);
- }
- function jsonToZpGroupElement(json) {
- validator.checkIsJsonString(
- json, 'JSON string representation of ZpGroupElement object');
- var parsed = JSON.parse(json);
- var p = codec.bytesToBigInteger(codec.base64Decode(parsed.zpGroupElement.p));
- var q = codec.bytesToBigInteger(codec.base64Decode(parsed.zpGroupElement.q));
- var value =
- codec.bytesToBigInteger(codec.base64Decode(parsed.zpGroupElement.value));
- return new ZpGroupElement(p, q, value);
- }
- function jsonToExponent(json) {
- validator.checkIsJsonString(
- json, 'JSON string representation of Exponent object');
- var parsed = JSON.parse(json);
- var q = codec.bytesToBigInteger(codec.base64Decode(parsed.exponent.q));
- var value =
- codec.bytesToBigInteger(codec.base64Decode(parsed.exponent.value));
- return new Exponent(q, value);
- }
|