<commit_before>var crypto = require("crypto");
var chacha20poly1305 = require("./chacha20poly1305");
var curve25519 = require("curve25519-n");
var assert = require('assert');
var bufferShim = require('buffer-shims');

module.exports = {
  generateCurve25519SecretKey: generateCurve25519SecretKey,
  generateCurve25519PublicKeyFromSecretKey: generateCurve25519PublicKeyFromSecretKey,
  generateCurve25519SharedSecKey: generateCurve25519SharedSecKey,
  layerEncrypt: layerEncrypt,
  layerDecrypt: layerDecrypt,
  verifyAndDecrypt: verifyAndDecrypt,
  encryptAndSeal: encryptAndSeal
};

function fromHex(h) {
  h.replace(/([^0-9a-f])/g, '');
  var out = [], len = h.length, w = '';
  for (var i = 0; i < len; i += 2) {
    w = h[i];
    if (((i+1) >= len) || typeof h[i+1] === 'undefined') {
        w += '0';
    } else {
        w += h[i+1];
    }
    out.push(parseInt(w, 16));
  }
  return out;
}

function generateCurve25519SecretKey() {
  var secretKey = bufferShim.alloc(32);
  curve25519.makeSecretKey(secretKey);
  return secretKey;
}

function generateCurve25519PublicKeyFromSecretKey(secKey) {
  var publicKey = curve25519.derivePublicKey(secKey);
  return publicKey;
}

function generateCurve25519SharedSecKey(secKey, pubKey) {
  var sharedSec = curve25519.deriveSharedSecret(secKey, pubKey);
  return sharedSec;
}

//Security Layer Enc/Dec

function layerEncrypt(data, count, key) {
  var result = bufferShim.alloc(0);
  var total = data.length;
  for (var offset = 0; offset < total; ) {
    var length = Math.min(total - offset, 0x400);
    var leLength = bufferShim.alloc(2);
    leLength.writeUInt16LE(length,0);

    var nonce = bufferShim.alloc(8);
    writeUInt64LE(count.value++, nonce, 0);

    var result_Buffer = bufferShim.alloc(length);
    var result_mac = bufferShim.alloc(16);
    encryptAndSeal(key, nonce, data.slice(offset, offset + length),
      leLength,result_Buffer, result_mac);

    offset += length;

    result = Buffer.concat([result,leLength,result_Buffer,result_mac]);
  }
  return result;
}

function layerDecrypt(packet, count, key) {
  var result = bufferShim.alloc(0);
  var total = packet.length;

  for (var offset = 0; offset < total;) {
    var realDataLength = packet.slice(offset,offset+2).readUInt16LE(0);

    var nonce = bufferShim.alloc(8);
    writeUInt64LE(count.value++, nonce, 0);

    var result_Buffer = bufferShim.alloc(realDataLength);

    if (verifyAndDecrypt(key, nonce, packet.slice(offset + 2, offset + 2 + realDataLength),
      packet.slice(offset + 2 + realDataLength, offset + 2 + realDataLength + 16),
      packet.slice(offset,offset+2),result_Buffer)) {
      result = Buffer.concat([result,result_Buffer]);
      offset += (18 + realDataLength);
    } else {
      console.log("Layer Decrypt fail!");
      return 0;
    }
  };

  return result;
}

//General Enc/Dec
function verifyAndDecrypt(key,nonce,ciphertext,mac,addData,plaintext) {
  var ctx = new chacha20poly1305.Chacha20Ctx();
  chacha20poly1305.chacha20_keysetup(ctx, key);
  chacha20poly1305.chacha20_ivsetup(ctx, nonce);
  var poly1305key = bufferShim.alloc(64);
  var zeros = bufferShim.alloc(64);
  chacha20poly1305.chacha20_update(ctx,poly1305key,zeros,zeros.length);

  var poly1305_contxt = new chacha20poly1305.Poly1305Ctx();
  chacha20poly1305.poly1305_init(poly1305_contxt, poly1305key);

  var addDataLength = 0;
  if (addData != undefined) {
    addDataLength = addData.length;
    chacha20poly1305.poly1305_update(poly1305_contxt, addData, addData.length);
    if ((addData.length % 16) != 0) {
      chacha20poly1305.poly1305_update(poly1305_contxt, bufferShim.alloc(16-(addData.length%16)), 16-(addData.length%16));
    }
  }<commit_msg>add extra log to debug decrypt corruption.<commit_after>var crypto = require("crypto");
var chacha20poly1305 = require("./chacha20poly1305");
var curve25519 = require("curve25519-n");
var assert = require('assert');
var bufferShim = require('buffer-shims');

module.exports = {
  generateCurve25519SecretKey: generateCurve25519SecretKey,
  generateCurve25519PublicKeyFromSecretKey: generateCurve25519PublicKeyFromSecretKey,
  generateCurve25519SharedSecKey: generateCurve25519SharedSecKey,
  layerEncrypt: layerEncrypt,
  layerDecrypt: layerDecrypt,
  verifyAndDecrypt: verifyAndDecrypt,
  encryptAndSeal: encryptAndSeal
};

function fromHex(h) {
  h.replace(/([^0-9a-f])/g, '');
  var out = [], len = h.length, w = '';
  for (var i = 0; i < len; i += 2) {
    w = h[i];
    if (((i+1) >= len) || typeof h[i+1] === 'undefined') {
        w += '0';
    } else {
        w += h[i+1];
    }
    out.push(parseInt(w, 16));
  }
  return out;
}

function generateCurve25519SecretKey() {
  var secretKey = bufferShim.alloc(32);
  curve25519.makeSecretKey(secretKey);
  return secretKey;
}

function generateCurve25519PublicKeyFromSecretKey(secKey) {
  var publicKey = curve25519.derivePublicKey(secKey);
  return publicKey;
}

function generateCurve25519SharedSecKey(secKey, pubKey) {
  var sharedSec = curve25519.deriveSharedSecret(secKey, pubKey);
  return sharedSec;
}

//Security Layer Enc/Dec

function layerEncrypt(data, count, key) {
  var result = bufferShim.alloc(0);
  var total = data.length;
  for (var offset = 0; offset < total; ) {
    var length = Math.min(total - offset, 0x400);
    var leLength = bufferShim.alloc(2);
    leLength.writeUInt16LE(length,0);

    var nonce = bufferShim.alloc(8);
    writeUInt64LE(count.value++, nonce, 0);

    var result_Buffer = bufferShim.alloc(length);
    var result_mac = bufferShim.alloc(16);
    encryptAndSeal(key, nonce, data.slice(offset, offset + length),
      leLength,result_Buffer, result_mac);

    offset += length;

    result = Buffer.concat([result,leLength,result_Buffer,result_mac]);
  }
  return result;
}

function layerDecrypt(packet, count, key) {
  var result = bufferShim.alloc(0);
  var total = packet.length;

  for (var offset = 0; offset < total;) {
    var realDataLength = packet.slice(offset,offset+2).readUInt16LE(0);

    var nonce = bufferShim.alloc(8);
    writeUInt64LE(count.value++, nonce, 0);

    var result_Buffer = bufferShim.alloc(realDataLength);

    if (verifyAndDecrypt(key, nonce, packet.slice(offset + 2, offset + 2 + realDataLength),
      packet.slice(offset + 2 + realDataLength, offset + 2 + realDataLength + 16),
      packet.slice(offset,offset+2),result_Buffer)) {
      result = Buffer.concat([result,result_Buffer]);
      offset += (18 + realDataLength);
    } else {
      console.log("Layer Decrypt fail!");
      console.log("Packet: %s", packet.toString('hex'));
      return 0;
    }
  };

  return result;
}

//General Enc/Dec
function verifyAndDecrypt(key,nonce,ciphertext,mac,addData,plaintext) {
  var ctx = new chacha20poly1305.Chacha20Ctx();
  chacha20poly1305.chacha20_keysetup(ctx, key);
  chacha20poly1305.chacha20_ivsetup(ctx, nonce);
  var poly1305key = bufferShim.alloc(64);
  var zeros = bufferShim.alloc(64);
  chacha20poly1305.chacha20_update(ctx,poly1305key,zeros,zeros.length);

  var poly1305_contxt = new chacha20poly1305.Poly1305Ctx();
  chacha20poly1305.poly1305_init(poly1305_contxt, poly1305key);

  var addDataLength = 0;
  if (addData != undefined) {
    addDataLength = addData.length;
    chacha20poly1305.poly1305_update(poly1305_contxt, addData, addData.length);
    if ((addData.length % 16) != 0) {
      chacha20poly1305.poly1305_update(poly1305_contxt, bufferShim.alloc(16-(addData.length%16)), 16-(addData.length%16));
    }
  }
{'fraction_non_alphanumeric': 0.13035905680600215, 'fraction_numerical': 0.06591639871382636, 'mean_word_length': 4.493009565857248, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 5, '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': '6502087', 'n_tokens_mistral': 2893, 'n_tokens_neox': 2589, 'n_words': 489}