/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied.  See the License for the
specific language governing permissions and limitations
under the License.
*/

/*
   MIRACL JavaScript M-Pin Authentication Functions

   Provides these functions:

   calculateMPinToken     Calculates the MPin Token

   getLocalEntropy        Gets an entropy value from the client machine

   initializeRNG          Initialize the Random Number Generator

   addShares              Add two points on the curve that are originally in hex format

   pass1Request           Form the JSON request for pass one of the M-Pin protocol

   pass2Request           Form the JSON request for pass two of the M-Pin protocol

   passRequest      Form the JSON request for one pass M-Pin protocol

*/

/*

Run LINT tool;

jslint MPINAuth.js

expected output;

MPINAuth.js
 #1 Read only.
    MPINAuth = {}; // Line 61, Pos 1
 #2 Unexpected '('.
    if (typeof (window) === 'undefined') { // Line 134, Pos 16
 #3 Unexpected 'typeof'. Use '===' to compare directly with undefined.
    if (typeof (window) === 'undefined') { // Line 134, Pos 9
 #4 Unexpected '('.
    if (typeof (crypto) !== 'undefined') { // Line 139, Pos 16
 #5 Unexpected 'typeof'. Use '===' to compare directly with undefined.
    if (typeof (crypto) !== 'undefined') { // Line 139, Pos 9

*/


/*global MPIN */
/*global MPINAuth */
/*global RAND */
/*global Uint32Array */
/*jslint browser: true*/
/*jslint plusplus: true */

MPINAuth = {};

// Random Number Generator
MPINAuth.rng = new RAND();

// Pass 1 values
MPINAuth.SEC = [];
MPINAuth.X = [];

// Default value for debug output
MPINAuth.DEBUG = false;

// Errors
MPINAuth.BAD_HEX = -20;
MPINAuth.BAD_BYTES = -21;

/* Calculates the MPin Token

   This function convert mpin_id _hex to unicode. It then maps the mpin_id
   to a point on the curve, multiplies this value by PIN and then subtracts
   it from the client_secret curve point to generate the M-Pin token.

   Args:

     PIN: Four digit PIN
     client_secret_hex: Hex encoded client secret
     mpin_id_hex: Hex encoded M-Pin ID

   Returns:

     mpin_token_hex: Hex encoded M-Pin Token

*/
MPINAuth.calculateMPinToken = function (mpin_id_hex, PIN, client_secret_hex) {
    "use strict";
    var client_secret_bytes, mpin_id_bytes, token_hex, error_code;

    client_secret_bytes = [];
    mpin_id_bytes = [];

    if (MPINAuth.DEBUG) {console.log("MPINAuth.calculateMPinToken client_secret_hex: " + client_secret_hex); }
    if (MPINAuth.DEBUG) {console.log("MPINAuth.calculateMPinToken mpin_id_hex: " + mpin_id_hex); }
    if (MPINAuth.DEBUG) {console.log("MPINAuth.calculateMPinToken PIN: " + PIN); }

    client_secret_bytes = MPINAuth.hextobytes(client_secret_hex);
    mpin_id_bytes = MPINAuth.hextobytes(mpin_id_hex);

    error_code = MPIN.EXTRACT_PIN(mpin_id_bytes, PIN, client_secret_bytes);
    if (error_code !== 0) {
        console.log("MPINAuth.calculateMPinToken error_code: " + error_code);
        return error_code;
    }
    token_hex = MPIN.bytestostring(client_secret_bytes);
    if (MPINAuth.DEBUG) {console.log("MPINAuth.calculateMPinToken token_hex: " + token_hex); }
    return token_hex;
};

/* Get local entropy

   This function makes a call to /dev/urandom for a 256 bit value

   Args:

     NA

   Returns:

     entropy_val: 256 bit random value or null

*/
MPINAuth.getLocalEntropy = function () {
    "use strict";
    var crypto, array, entropy_val, i, hex_val;
    if (typeof (window) === 'undefined') {
        if (MPINAuth.DEBUG) {console.log("MPINAuth.getLocalEntropy Test mode without browser"); }
        return "";
    }
    crypto = (window.crypto || window.msCrypto);
    if (typeof (crypto) !== 'undefined') {
        array = new Uint32Array(8);
        crypto.getRandomValues(array);

        entropy_val = "";
        for (i = 0; i < array.length; i++) {
            hex_val = array[i].toString(16);
            entropy_val = entropy_val + hex_val;
        }
        if (MPINAuth.DEBUG) {console.log("MPINAuth.getLocalEntropy len(entropy_val): " + entropy_val.length + " entropy_val: " + entropy_val); }
        return entropy_val;
    }
    return "";
};

/* Initialize the Random Number Generator (RNG)

   This function uses an external and, where available, a
   local entropy source to initialize a RNG.

   Args:

     seed_value: External seed value for RNGTurn on generation of local entropy

   Returns:

*/
MPINAuth.initializeRNG = function (seed_hex) {
    "use strict";
    var local_entropy_hex, entropy_hex, entropy_bytes;
    local_entropy_hex = MPINAuth.getLocalEntropy();
    entropy_hex = local_entropy_hex + seed_hex;
    if (MPINAuth.DEBUG) {console.log("MPINAuth.initializeRNG seed_val_hex: " + seed_hex); }
    if (MPINAuth.DEBUG) {console.log("MPINAuth.initializeRNG local_entropy_hex: " + local_entropy_hex); }
    if (MPINAuth.DEBUG) {console.log("MPINAuth.initializeRNG entropy_hex: " + entropy_hex); }

    entropy_bytes = MPINAuth.hextobytes(entropy_hex);

    MPINAuth.rng.clean();
    MPINAuth.rng.seed(entropy_bytes.length, entropy_bytes);
};

/* Add two points on the curve that are originally in hex format

   This function is used to add client secret or time permits shares.

   Args:

     share1_hex: Hex encoded point on the curve which represents
                 a time permit or client secret share
     share2_hex: Hex encoded point on the curve which represents
                 a time permit or client secret share

   Returns:

     sum_hex: Hex encoded sum of the shares

*/
MPINAuth.addShares = function (share1_hex, share2_hex) {
    "use strict";
    var share1_bytes, share2_bytes, sum_bytes, error_code, sum_hex;

    share1_bytes = [];
    share2_bytes = [];
    sum_bytes = [];

    if (MPINAuth.DEBUG) {console.log("MPINAuth.addShares share1_hex: " + share1_hex); }
    if (MPINAuth.DEBUG) {console.log("MPINAuth.addShares share2_hex: " + share2_hex); }

    share1_bytes = MPINAuth.hextobytes(share1_hex);
    share2_bytes = MPINAuth.hextobytes(share2_hex);

    error_code = MPIN.RECOMBINE_G1(share1_bytes, share2_bytes, sum_bytes);
    if (error_code !== 0) {
        console.log("MPINAuth.addShares error_code: " + error_code);
        return error_code;
    }
    sum_hex = MPIN.bytestostring(sum_bytes);
    if (MPINAuth.DEBUG) {console.log("MPINAuth.addShares sum_hex: " + sum_hex); }
    return sum_hex;
};


/* Form the JSON request for pass one of the M-Pin protocol

   This function assigns to the property X a random value. It assigns to
   the property SEC the sum of the client secret and time permit. It also
   calculates the values U and UT which are required for M-Pin authentication,
   where U = X.(map_to_curve(MPIN_ID)) and UT = X.(map_to_curve(MPIN_ID) + map_to_curve(DATE|sha256(MPIN_ID))
   UT is called the commitment. U is the required for finding the PIN error.

   Args:

     mpin_id_hex: Hex encoded M-Pin ID
     token_hex: Hex encoded M-Pin Token
     timePermit_hex: Hex encoded Time Permit
     PIN: PIN for authentication
     epoch_days: The number of epoch days.
     X_hex: X value generated externally. This is used for test.

   Returns:

    {
      mpin_id: mpin_id_hex,
      UT: UT_hex,
      U: U_hex,
      pass: 1
    }

    where;

    mpin_id: Hex encoded M-Pin ID
    UT: Hex encoded X.(map_to_curve(MPIN_ID) + map_to_curve(DATE|sha256(MPIN_ID))
    U: Hex encoded X.(map_to_curve(MPIN_ID))
    pass: Protocol first pass

*/
MPINAuth.pass1Request = function (mpin_id_hex, token_hex, timePermit_hex, PIN, epoch_days, X_hex) {
    "use strict";
    var UT_hex, U_hex, date, error_code, mpin_id_bytes, token_bytes, timePermit_bytes, U, UT, request;

    mpin_id_bytes = [];
    token_bytes = [];
    timePermit_bytes = [];
    U = [];
    UT = [];
    request = {};

    if (MPINAuth.DEBUG) {console.log("MPINAuth.pass1Request mpin_id_hex: " + mpin_id_hex); }
    if (MPINAuth.DEBUG) {console.log("MPINAuth.pass1Request token_hex: " + token_hex); }
    if (MPINAuth.DEBUG) {console.log("MPINAuth.pass1Request timePermit_hex: " + timePermit_hex); }
    if (MPINAuth.DEBUG) {console.log("MPINAuth.pass1Request PIN: " + PIN); }
    if (MPINAuth.DEBUG) {console.log("mpinAuth.pass1Request epoch_days: " + epoch_days); }

    // The following is used for test
    if (X_hex !== null) {
        if (MPINAuth.DEBUG) {console.log("MPINAuth.pass1Request X: " + X_hex); }
        MPINAuth.X = MPINAuth.hextobytes(X_hex);
        MPINAuth.rng = null;
    }

    mpin_id_bytes = MPINAuth.hextobytes(mpin_id_hex);
    token_bytes = MPINAuth.hextobytes(token_hex);
    timePermit_bytes = MPINAuth.hextobytes(timePermit_hex);

    error_code = MPIN.CLIENT_1(epoch_days, mpin_id_bytes, MPINAuth.rng, MPINAuth.X, PIN, token_bytes, MPINAuth.SEC, U, UT, timePermit_bytes);
    if (error_code !== 0) {
        console.log("MPINAuth.pass1Request error_code: " + error_code);
        return error_code;
    }
    UT_hex = MPIN.bytestostring(UT);
    U_hex = MPIN.bytestostring(U);

    if (MPINAuth.DEBUG) {console.log("MPINAuth.pass1Request MPINAuth.rng: " + MPINAuth.rng); }
    if (MPINAuth.DEBUG) {console.log("MPINAuth.pass1Request MPINAuth.X: " + MPIN.bytestostring(MPINAuth.X)); }
    if (MPINAuth.DEBUG) {console.log("MPINAuth.pass1Request MPINAuth.SEC: " + MPIN.bytestostring(MPINAuth.SEC)); }

    // Form request
    request = {
        mpin_id: mpin_id_hex,
        UT: UT_hex,
        U: U_hex,
        pass: 1
    };
    if (MPINAuth.DEBUG) {console.log("MPINAuth.pass1Request request: "); }
    if (MPINAuth.DEBUG) {console.dir(request); }

    return request;
};


/* Form the JSON request for pass two of the M-Pin protocol

   This function uses the random value y from the server, property X
   and the combined client secret and time permit to calculate
   the value V which is sent to the M-Pin server.

   Args:

     y_hex: Random value supplied by server

   Returns:

    {
      V: V_hex,
      OTP: requestOTP,
      WID: accessNumber,
      pass: 2
    }

    where;

    V: Value required by the server to authenticate user
    OTP: Request OTP: 1 = required
    WID: Number required for mobile authentication
    pass: Protocol second pass

*/
MPINAuth.pass2Request = function (y_hex, requestOTP, accessNumber) {
    "use strict";

    var y_bytes, x_hex, SEC_hex, error_code, V_hex, request;

    request = {};

    y_bytes = MPINAuth.hextobytes(y_hex);
    x_hex = MPIN.bytestostring(MPINAuth.X);
    SEC_hex = MPIN.bytestostring(MPINAuth.SEC);

    if (MPINAuth.DEBUG) {console.log("MPINAuth.pass2Request x_hex: " + x_hex); }
    if (MPINAuth.DEBUG) {console.log("MPINAuth.pass2Request y_hex: " + y_hex); }
    if (MPINAuth.DEBUG) {console.log("MPINAuth.pass2Request SEC_hex: " + SEC_hex); }

    // Compute V
    error_code = MPIN.CLIENT_2(MPINAuth.X, y_bytes, MPINAuth.SEC);
    if (error_code !== 0) {
        console.log("MPINAuth.pass2Request error_code: " + error_code);
        return error_code;
    }
    V_hex = MPIN.bytestostring(MPINAuth.SEC);

    // Form reuest
    request = {
        V: V_hex,
        OTP: requestOTP,
        WID: accessNumber,
        pass: 2
    };
    if (MPINAuth.DEBUG) {console.log("MPINAuth.pass2Request request: "); }
    if (MPINAuth.DEBUG) {console.dir(request); }

    return request;
};


/* Convert a hex representation of a Point to bytes

   This function converts a hex value to a bytes array

   Args:

     hex_value: Hex encoded byte value

   Returns:

     byte_value: Input value in bytes

*/
MPINAuth.hextobytes = function (value_hex) {
    "use strict";
    var len, byte_value, i;

    len = value_hex.length;
    byte_value = [];

    for (i = 0; i < len; i += 2) {
        byte_value[(i / 2)] = parseInt(value_hex.substr(i, 2), 16);
    }
    return byte_value;
};


/* Form the JSON request for single pass M-Pin protocol

   This function performs the client side M-Pin protocol
   It also  calculates the values U and UT which are required for M-Pin authentication,
   where U = X.(map_to_curve(MPIN_ID)) and UT = X.(map_to_curve(MPIN_ID) + map_to_curve(DATE|sha256(MPIN_ID))
   UT is called the commitment. U is the required for finding the PIN error.

   Args:

     mpin_id_hex: Hex encoded M-Pin ID
     token_hex: Hex encoded M-Pin Token
     timePermit_hex: Hex encoded Time Permit
     PIN: PIN for authentication
     requestOTP: Reqeuest a One Time Password
     accessNumber: Access number for desktop authentication
     timeValue: Epoch time

   Returns:

    {
      mpin_id: mpin_id_hex,
      U: U_hex,
      UT: UT_hex,
      V: V_hex,
      T: timeValue,
      OTP: requestOTP,
      WID: accessNumber
    }

    where;

    mpin_id: Hex encoded M-Pin ID
    U: Hex encoded X.(map_to_curve(MPIN_ID))
    UT: Hex encoded X.(map_to_curve(MPIN_ID) + map_to_curve(DATE|sha256(MPIN_ID))
    V: Value required by the server to authenticate user
    T: Epoch time
    OTP: Request OTP: 1 = required
    WID: Number required for mobile authentication

*/
MPINAuth.passRequest = function (mpin_id_hex, token_hex, timePermit_hex, PIN, requestOTP, accessNumber, epoch_days, timeValue, X_hex) {
    "use strict";
    var X, Y, SEC, UT_hex, U_hex, date, error_code, mpin_id_bytes, token_bytes, timePermit_bytes, U, UT, V_hex, request;

    X = [];
    Y = [];
    SEC = [];
    mpin_id_bytes = [];
    token_bytes = [];
    timePermit_bytes = [];
    U = [];
    UT = [];
    request = {};

    if (MPINAuth.DEBUG) {console.log("MPINAuth.passRequest mpin_id_hex: " + mpin_id_hex); }
    if (MPINAuth.DEBUG) {console.log("MPINAuth.passRequest token_hex: " + token_hex); }
    if (MPINAuth.DEBUG) {console.log("MPINAuth.passRequest timePermit_hex: " + timePermit_hex); }
    if (MPINAuth.DEBUG) {console.log("MPINAuth.passRequest PIN: " + PIN); }
    if (MPINAuth.DEBUG) {console.log("mpinAuth.passRequest timeValue: " + timeValue); }

    mpin_id_bytes = MPINAuth.hextobytes(mpin_id_hex);
    token_bytes = MPINAuth.hextobytes(token_hex);

    if (timePermit_hex === null) {
        date = 0;
    } else {
        timePermit_bytes = MPINAuth.hextobytes(timePermit_hex);
        date = epoch_days;
    }
    if (MPINAuth.DEBUG) {console.log("MPINAuth.passRequest date: " + date); }

    // The following is used for test
    if (MPINAuth.DEBUG) {console.log("MPINAuth.passRequest X: " + X_hex); }
    if (X_hex !== null) {
        X = MPINAuth.hextobytes(X_hex);
        MPINAuth.rng = null;
    }

    error_code = MPIN.CLIENT(date, mpin_id_bytes, MPINAuth.rng, X, PIN, token_bytes, SEC, U, UT, timePermit_bytes, timeValue, Y);
    if (error_code !== 0) {
        console.log("MPINAuth.passRequest error_code: " + error_code);
        return error_code;
    }
    UT_hex = MPIN.bytestostring(UT);
    U_hex = MPIN.bytestostring(U);
    V_hex = MPIN.bytestostring(SEC);

    if (MPINAuth.DEBUG) {console.log("MPINAuth.passRequest MPINAuth.rng: " + MPINAuth.rng); }
    if (MPINAuth.DEBUG) {console.log("MPINAuth.passRequest X: " + MPIN.bytestostring(X)); }
    if (MPINAuth.DEBUG) {console.log("MPINAuth.passRequest Y: " + MPIN.bytestostring(Y)); }

    // Form request
    request = {
        mpin_id: mpin_id_hex,
        U: U_hex,
        UT: UT_hex,
        V: V_hex,
        T: timeValue,
        OTP: requestOTP,
        WID: accessNumber
    };
    if (MPINAuth.DEBUG) {console.log("MPINAuth.passRequest request: "); }
    if (MPINAuth.DEBUG) {console.dir(request); }

    return request;
};

