var AuthenticationHelper = function()

in MultiRegion/2_UI/src/assets/js/aws/amazon-cognito-identity.js [157:408]


	var AuthenticationHelper = function () {
	  /**
	   * Constructs a new AuthenticationHelper object
	   * @param {string} PoolName Cognito user pool name.
	   */
	  function AuthenticationHelper(PoolName) {
	    _classCallCheck(this, AuthenticationHelper);

	    this.N = new _BigInteger2.default(initN, 16);
	    this.g = new _BigInteger2.default('2', 16);
	    this.k = new _BigInteger2.default(this.hexHash('00' + this.N.toString(16) + '0' + this.g.toString(16)), 16);

	    this.smallAValue = this.generateRandomSmallA();
	    this.largeAValue = this.calculateA(this.smallAValue);

	    this.infoBits = new _global.util.Buffer('Caldera Derived Key', 'utf8');

	    this.poolName = PoolName;
	  }

	  /**
	   * @returns {BigInteger} small A, a random number
	   */


	  AuthenticationHelper.prototype.getSmallAValue = function getSmallAValue() {
	    return this.smallAValue;
	  };

	  /**
	   * @returns {BigInteger} large A, a value generated from small A
	   */


	  AuthenticationHelper.prototype.getLargeAValue = function getLargeAValue() {
	    return this.largeAValue;
	  };

	  /**
	   * helper function to generate a random big integer
	   * @returns {BigInteger} a random value.
	   * @private
	   */


	  AuthenticationHelper.prototype.generateRandomSmallA = function generateRandomSmallA() {
	    var hexRandom = _global.util.crypto.lib.randomBytes(128).toString('hex');

	    var randomBigInt = new _BigInteger2.default(hexRandom, 16);
	    var smallABigInt = randomBigInt.mod(this.N);

	    return smallABigInt;
	  };

	  /**
	   * helper function to generate a random string
	   * @returns {string} a random value.
	   * @private
	   */


	  AuthenticationHelper.prototype.generateRandomString = function generateRandomString() {
	    return _global.util.crypto.lib.randomBytes(40).toString('base64');
	  };

	  /**
	   * @returns {string} Generated random value included in password hash.
	   */


	  AuthenticationHelper.prototype.getRandomPassword = function getRandomPassword() {
	    return this.randomPassword;
	  };

	  /**
	   * @returns {string} Generated random value included in devices hash.
	   */


	  AuthenticationHelper.prototype.getSaltDevices = function getSaltDevices() {
	    return this.SaltToHashDevices;
	  };

	  /**
	   * @returns {string} Value used to verify devices.
	   */


	  AuthenticationHelper.prototype.getVerifierDevices = function getVerifierDevices() {
	    return this.verifierDevices;
	  };

	  /**
	   * Generate salts and compute verifier.
	   * @param {string} deviceGroupKey Devices to generate verifier for.
	   * @param {string} username User to generate verifier for.
	   * @returns {void}
	   */


	  AuthenticationHelper.prototype.generateHashDevice = function generateHashDevice(deviceGroupKey, username) {
	    this.randomPassword = this.generateRandomString();
	    var combinedString = '' + deviceGroupKey + username + ':' + this.randomPassword;
	    var hashedString = this.hash(combinedString);

	    var hexRandom = _global.util.crypto.lib.randomBytes(16).toString('hex');
	    this.SaltToHashDevices = this.padHex(new _BigInteger2.default(hexRandom, 16));

	    var verifierDevicesNotPadded = this.g.modPow(new _BigInteger2.default(this.hexHash(this.SaltToHashDevices + hashedString), 16), this.N);

	    this.verifierDevices = this.padHex(verifierDevicesNotPadded);
	  };

	  /**
	   * Calculate the client's public value A = g^a%N
	   * with the generated random number a
	   * @param {BigInteger} a Randomly generated small A.
	   * @returns {BigInteger} Computed large A.
	   * @private
	   */


	  AuthenticationHelper.prototype.calculateA = function calculateA(a) {
	    var A = this.g.modPow(a, this.N);

	    if (A.mod(this.N).equals(_BigInteger2.default.ZERO)) {
	      throw new Error('Illegal paramater. A mod N cannot be 0.');
	    }
	    return A;
	  };

	  /**
	   * Calculate the client's value U which is the hash of A and B
	   * @param {BigInteger} A Large A value.
	   * @param {BigInteger} B Server B value.
	   * @returns {BigInteger} Computed U value.
	   * @private
	   */


	  AuthenticationHelper.prototype.calculateU = function calculateU(A, B) {
	    this.UHexHash = this.hexHash(this.padHex(A) + this.padHex(B));
	    var finalU = new _BigInteger2.default(this.UHexHash, 16);

	    return finalU;
	  };

	  /**
	   * Calculate a hash from a bitArray
	   * @param {Buffer} buf Value to hash.
	   * @returns {String} Hex-encoded hash.
	   * @private
	   */


	  AuthenticationHelper.prototype.hash = function hash(buf) {
	    var hashHex = _global.util.crypto.sha256(buf, 'hex');
	    return new Array(64 - hashHex.length).join('0') + hashHex;
	  };

	  /**
	   * Calculate a hash from a hex string
	   * @param {String} hexStr Value to hash.
	   * @returns {String} Hex-encoded hash.
	   * @private
	   */


	  AuthenticationHelper.prototype.hexHash = function hexHash(hexStr) {
	    return this.hash(new _global.util.Buffer(hexStr, 'hex'));
	  };

	  /**
	   * Standard hkdf algorithm
	   * @param {Buffer} ikm Input key material.
	   * @param {Buffer} salt Salt value.
	   * @returns {Buffer} Strong key material.
	   * @private
	   */


	  AuthenticationHelper.prototype.computehkdf = function computehkdf(ikm, salt) {
	    var prk = _global.util.crypto.hmac(salt, ikm, 'buffer', 'sha256');
	    var infoBitsUpdate = _global.util.buffer.concat([this.infoBits, new _global.util.Buffer(String.fromCharCode(1), 'utf8')]);
	    var hmac = _global.util.crypto.hmac(prk, infoBitsUpdate, 'buffer', 'sha256');
	    return hmac.slice(0, 16);
	  };

	  /**
	   * Calculates the final hkdf based on computed S value, and computed U value and the key
	   * @param {String} username Username.
	   * @param {String} password Password.
	   * @param {BigInteger} serverBValue Server B value.
	   * @param {BigInteger} salt Generated salt.
	   * @returns {Buffer} Computed HKDF value.
	   */


	  AuthenticationHelper.prototype.getPasswordAuthenticationKey = function getPasswordAuthenticationKey(username, password, serverBValue, salt) {
	    if (serverBValue.mod(this.N).equals(_BigInteger2.default.ZERO)) {
	      throw new Error('B cannot be zero.');
	    }

	    this.UValue = this.calculateU(this.largeAValue, serverBValue);

	    if (this.UValue.equals(_BigInteger2.default.ZERO)) {
	      throw new Error('U cannot be zero.');
	    }

	    var usernamePassword = '' + this.poolName + username + ':' + password;
	    var usernamePasswordHash = this.hash(usernamePassword);

	    var xValue = new _BigInteger2.default(this.hexHash(this.padHex(salt) + usernamePasswordHash), 16);

	    var gModPowXN = this.g.modPow(xValue, this.N);
	    var intValue2 = serverBValue.subtract(this.k.multiply(gModPowXN));
	    var sValue = intValue2.modPow(this.smallAValue.add(this.UValue.multiply(xValue)), this.N).mod(this.N);

	    var hkdf = this.computehkdf(new _global.util.Buffer(this.padHex(sValue), 'hex'), new _global.util.Buffer(this.padHex(this.UValue.toString(16)), 'hex'));

	    return hkdf;
	  };

	  /**
	  * Return constant newPasswordRequiredChallengeUserAttributePrefix
	  * @return {newPasswordRequiredChallengeUserAttributePrefix} constant prefix value
	  */


	  AuthenticationHelper.prototype.getNewPasswordRequiredChallengeUserAttributePrefix = function getNewPasswordRequiredChallengeUserAttributePrefix() {
	    return newPasswordRequiredChallengeUserAttributePrefix;
	  };

	  /**
	   * Converts a BigInteger (or hex string) to hex format padded with zeroes for hashing
	   * @param {BigInteger|String} bigInt Number or string to pad.
	   * @returns {String} Padded hex string.
	   */


	  AuthenticationHelper.prototype.padHex = function padHex(bigInt) {
	    var hashStr = bigInt.toString(16);
	    if (hashStr.length % 2 === 1) {
	      hashStr = '0' + hashStr;
	    } else if ('89ABCDEFabcdef'.indexOf(hashStr[0]) !== -1) {
	      hashStr = '00' + hashStr;
	    }
	    return hashStr;
	  };

	  return AuthenticationHelper;
	}();