<commit_before>import KeyPair from './keyPair';
import convert from '../utils/convert';
import Address from '../model/address';
import nacl from '../external/nacl-fast';
import Network from '../model/network';
import CryptoJS from 'crypto-js';
import Helpers from '../utils/helpers';

/**
 * Encrypt a private key for mobile apps (AES_PBKF2)
 *
 * @param {string} password - A wallet password
 * @param {string} privateKey - An account private key
 *
 * @return {object} - The encrypted data
 */
let toMobileKey = function(password, privateKey) {
    // Errors
    if (!password || !privateKey) throw new Error('Missing argument !');
    if (!Helpers.isPrivateKeyValid(privateKey)) throw new Error('Private key is not valid !');
    // Processing
    let salt = CryptoJS.lib.WordArray.random(256 / 8);
    let key = CryptoJS.PBKDF2(password, salt, {
        keySize: 256 / 32,
        iterations: 2000
    });
    let iv = nacl.randomBytes(16)
    let encIv = {
        iv: convert.ua2words(iv, 16)
    };
    let encrypted = CryptoJS.AES.encrypt(CryptoJS.enc.Hex.parse(privateKey), key, encIv);
    // Result
    return {
        encrypted: convert.ua2hex(iv) + encrypted.ciphertext,
        salt:  salt.toString()
    }
};

/**
 * Derive a private key from a password using count iterations of SHA3-256
 *
 * @param {string} password - A wallet password
 * @param {number} count - A number of iterations above 0
 *
 * @return {object} - The derived private key
 */
let derivePassSha = function(password, count) {
    // Errors
    if(!password) throw new Error('Missing argument !');
    if(!count || count <= 0) throw new Error('Please provide a count number above 0');
    // Processing
    let data = password;
    console.time('sha3^n generation time');
    for (let i = 0; i < count; ++i) {
        data = CryptoJS.SHA3(data, {
            outputLength: 256
        });
    }
    console.timeEnd('sha3^n generation time');
    // Result
    return {
        'priv': CryptoJS.enc.Hex.stringify(data)
    };
};

/**
 * Reveal the private key of an account or derive it from the wallet password
 *
 * @param {object} common- An object containing password and privateKey field
 * @param {object} walletAccount - A wallet account object
 * @param {string} algo - A wallet algorithm
 *
 * @return {object|boolean} - The account private key in and object or false
 */
let passwordToPrivatekey = function(common, walletAccount, algo) {
    // Errors
    if(!common || !common.password || !walletAccount || !algo) throw new Error('Missing argument !');
    // Processing
    let r = undefined;
    if (algo === "pass:6k") { // Brain wallets
        if (!walletAccount.encrypted && !walletAccount.iv) {
            // Account private key is generated simply using a passphrase so it has no encrypted and iv
            r = derivePassSha(common.password, 6000);
        } else if (!walletAccount.encrypted || !walletAccount.iv) {
            // Else if one is missing there is a problem
            //console.log("Account might be compromised, missing encrypted or iv");
            return false;
        } else {
            // Else child accounts have encrypted and iv so we decrypt
            let pass = derivePassSha(common.password, 20);
            let obj = {
                ciphertext: CryptoJS.enc.Hex.parse(walletAccount.encrypted),
                iv: convert.hex2ua(walletAccount.iv),
                key: convert.hex2ua(pass.priv)
            };
            let d = decrypt(obj);
            r = {
                'priv': d
            };
        }
    } else if (algo === "pass:bip32") { // Wallets from PRNG
        let pass = derivePassSha(common.password, 20);
        let obj = {
            ciphertext: CryptoJS.enc.Hex.parse(walletAccount.encrypted),
            iv: convert.hex2ua(walletAccount.iv),
            key: convert.hex2ua(pass.priv)
        };
        let d = decrypt(obj);
        r = {
            'priv': d
        };
    } else if (algo === "pass:enc") { // Private Key wallets
        let pass = derivePassSha(common.password, 20);
        let obj = {
            ciphertext: CryptoJS.enc.Hex.parse(walletAccount.encrypted),
            iv: convert.hex2ua(walletAccount.iv),
            key: convert.hex2ua(pass.priv)
        };
        let d = decrypt(obj);
        r = {
            'priv': d
        };
    } else {
        //console.log("Unknown wallet encryption method");
        return false;
    }
    // Result
    common.privateKey = r.priv;
    return true;
}

/**
 * Check if a private key correspond to an account address
 *
 * @param {string} priv - An account private key
 * @param {number} network - A network id
 * @param {string} _expectedAddress - The expected NEM address
 *
 * @return {boolean} - True if valid, false otherwise
 */
let checkAddress = function(priv, network, _expectedAddress) {
    // Errors
    if (!priv || !network || !_expectedAddress) throw new Error('Missing argument !');
    if (!Helpers.isPrivateKeyValid(priv)) throw new Error('Private key is not valid !');
    //Processing<commit_msg>Add trezor wallet type to passwordToPrivateKey<commit_after>import KeyPair from './keyPair';
import convert from '../utils/convert';
import Address from '../model/address';
import nacl from '../external/nacl-fast';
import Network from '../model/network';
import CryptoJS from 'crypto-js';
import Helpers from '../utils/helpers';

/**
 * Encrypt a private key for mobile apps (AES_PBKF2)
 *
 * @param {string} password - A wallet password
 * @param {string} privateKey - An account private key
 *
 * @return {object} - The encrypted data
 */
let toMobileKey = function(password, privateKey) {
    // Errors
    if (!password || !privateKey) throw new Error('Missing argument !');
    if (!Helpers.isPrivateKeyValid(privateKey)) throw new Error('Private key is not valid !');
    // Processing
    let salt = CryptoJS.lib.WordArray.random(256 / 8);
    let key = CryptoJS.PBKDF2(password, salt, {
        keySize: 256 / 32,
        iterations: 2000
    });
    let iv = nacl.randomBytes(16)
    let encIv = {
        iv: convert.ua2words(iv, 16)
    };
    let encrypted = CryptoJS.AES.encrypt(CryptoJS.enc.Hex.parse(privateKey), key, encIv);
    // Result
    return {
        encrypted: convert.ua2hex(iv) + encrypted.ciphertext,
        salt:  salt.toString()
    }
};

/**
 * Derive a private key from a password using count iterations of SHA3-256
 *
 * @param {string} password - A wallet password
 * @param {number} count - A number of iterations above 0
 *
 * @return {object} - The derived private key
 */
let derivePassSha = function(password, count) {
    // Errors
    if(!password) throw new Error('Missing argument !');
    if(!count || count <= 0) throw new Error('Please provide a count number above 0');
    // Processing
    let data = password;
    console.time('sha3^n generation time');
    for (let i = 0; i < count; ++i) {
        data = CryptoJS.SHA3(data, {
            outputLength: 256
        });
    }
    console.timeEnd('sha3^n generation time');
    // Result
    return {
        'priv': CryptoJS.enc.Hex.stringify(data)
    };
};

/**
 * Reveal the private key of an account or derive it from the wallet password
 *
 * @param {object} common- An object containing password and privateKey field
 * @param {object} walletAccount - A wallet account object
 * @param {string} algo - A wallet algorithm
 *
 * @return {object|boolean} - The account private key in and object or false
 */
let passwordToPrivatekey = function(common, walletAccount, algo) {
    // Errors
    if(!common || !common.password || !walletAccount || !algo) throw new Error('Missing argument !');
    // Processing
    let r = undefined;
    if (algo === "pass:6k") { // Brain wallets
        if (!walletAccount.encrypted && !walletAccount.iv) {
            // Account private key is generated simply using a passphrase so it has no encrypted and iv
            r = derivePassSha(common.password, 6000);
        } else if (!walletAccount.encrypted || !walletAccount.iv) {
            // Else if one is missing there is a problem
            //console.log("Account might be compromised, missing encrypted or iv");
            return false;
        } else {
            // Else child accounts have encrypted and iv so we decrypt
            let pass = derivePassSha(common.password, 20);
            let obj = {
                ciphertext: CryptoJS.enc.Hex.parse(walletAccount.encrypted),
                iv: convert.hex2ua(walletAccount.iv),
                key: convert.hex2ua(pass.priv)
            };
            let d = decrypt(obj);
            r = { 'priv': d };
        }
    } else if (algo === "pass:bip32") { // Wallets from PRNG
        let pass = derivePassSha(common.password, 20);
        let obj = {
            ciphertext: CryptoJS.enc.Hex.parse(walletAccount.encrypted),
            iv: convert.hex2ua(walletAccount.iv),
            key: convert.hex2ua(pass.priv)
        };
        let d = decrypt(obj);
        r = { 'priv': d };
    } else if (algo === "pass:enc") { // Private Key wallets
        let pass = derivePassSha(common.password, 20);
        let obj = {
            ciphertext: CryptoJS.enc.Hex.parse(walletAccount.encrypted),
            iv: convert.hex2ua(walletAccount.iv),
            key: convert.hex2ua(pass.priv)
        };
        let d = decrypt(obj);
        r = { 'priv': d };
    } else if (algo === "trezor") { // HW wallet
        r = { 'priv': '' };
        common.isHW = true;
    } else {
        //console.log("Unknown wallet encryption method");
        return false;
    }
    // Result
    common.privateKey = r.priv;
    return true;
}

/**
 * Check if a private key correspond to an account address
 *
 * @param {string} priv - An account private key
 * @param {number} network - A network id
 * @param {string} _expectedAddress - The expected NEM address
 *
 * @return {boolean} - True if valid, false otherwise
 */
let checkAddress = function(priv, network, _expectedAddress) {
    // Errors
    if (!priv || !network || !_expectedAddress) throw new Error('Missing argument !');
    if (!Helpers.isPrivateKeyValid(priv)) throw new Error('Private key is not valid !');
    //Processing
{'fraction_non_alphanumeric': 0.12355477170291986, 'fraction_numerical': 0.010582010582010581, 'mean_word_length': 2.455314827352742, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5689646', 'n_tokens_mistral': 3028, 'n_tokens_neox': 2935, 'n_words': 928}