/*
 * 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 codec = require('scytl-codec');

module.exports = ElGamalEncryptedElements;

/**
 * @class ElGamalEncryptedElements
 * @classdesc Encapsulates the components of the ElGamal encryption of some Zp
 *            group elements or the pre-computation of such an encryption. To
 *            instantiate this object, use the method {@link
 *            ElGamalCryptographyService.newEncryptedElements}.
 * @property {ZpGroupElement} gamma The gamma Zp group element that comprises
 *           the ElGamal encryption or pre-computation.
 * @property {ZpGroupElement[]} phis The phi Zp group elements that comprise the
 *           ElGamal encryption or pre-computation.
 * @property {Exponent} [secret=undefined] The secret exponent that comprises
 *           the encryption or pre-computation. <b>CAUTION:</b> Provide only
 *           when the secret is really needed later (e.g. for zero-knowledge
 *           proof generation).
 */
function ElGamalEncryptedElements(gamma, phis, secret) {
  this.gamma = gamma;
  Object.freeze(this.phis = phis);
  this.secret = secret;

  Object.freeze(this);
}

ElGamalEncryptedElements.prototype = {
  /**
   * 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.
   * <p>
   * <b>NOTE:</b> For security reasons, the secret exponent of the ElGamal
   * encryption or pre-computation is not included in this serialization.
   *
   * @function toJson
   * @memberof ElGamalEncryptedElements
   * @returns {string} The JSON string representation of this object.
   */
  toJson: function() {
    var pB64 = codec.base64Encode(this.gamma.p);
    var qB64 = codec.base64Encode(this.gamma.q);

    var gammaB64 = codec.base64Encode(this.gamma.value);

    var phisB64 = [];
    for (var i = 0; i < this.phis.length; i++) {
      phisB64[i] = codec.base64Encode(this.phis[i].value);
    }

    return JSON.stringify({
      ciphertext: {
        p: pB64,
        q: qB64,
        gamma: gammaB64,
        phis: phisB64,
      }
    });
  }
};
