nodejs/ece.js
function encrypt(buffer, params, keyLookupCallback) {  
  if (!Buffer.isBuffer(buffer)) {
    throw new Error('buffer argument must be a Buffer');
  }
  var header = parseParams(params);
  if (!header.salt) {
    header.salt = crypto.randomBytes(KEY_LENGTH);
  }

  var result;
  if (header.version === 'aes128gcm') {
    // Save the DH public key in the header unless keyid is set.
    if (header.privateKey && !header.keyid) {
      header.keyid = header.privateKey.getPublicKey();
    }
    result = writeHeader(header);
  } else {
    // No header on other versions
    result = new Buffer(0);
  }

  var key = deriveKeyAndNonce(header, MODE_ENCRYPT, keyLookupCallback);
  var start = 0;
  var padSize = PAD_SIZE[header.version];
  var overhead = padSize;
  if (header.version === 'aes128gcm') {
    overhead += TAG_LENGTH;
  }
  var pad = isNaN(parseInt(params.pad, 10)) ? 0 : parseInt(params.pad, 10);

  var counter = 0;
  var last = false;
  while (!last) {
    // Pad so that at least one data byte is in a block.
    var recordPad = Math.min(header.rs - overhead - 1, pad);
    if (header.version !== 'aes128gcm') {
      recordPad = Math.min((1 << (padSize * 8)) - 1, recordPad);
    }
    if (pad > 0 && recordPad === 0) {
      ++recordPad; // Deal with perverse case of rs=overhead+1 with padding.
    }
    pad -= recordPad;

    var end = start + header.rs - overhead - recordPad;
    if (header.version !== 'aes128gcm') {
      // The > here ensures that we write out a padding-only block at the end
      // of a buffer.
      last = end > buffer.length;
    } else {
      last = end >= buffer.length;
    }
    last = last && pad <= 0;
    var block = encryptRecord(key, counter, buffer.slice(start, end),
                              recordPad, header, last);
    result = Buffer.concat([result, block]);

    start = end;
    ++counter;
  }
  return result;
}
function encrypt(buffer, params, keyLookupCallback) {  
  if (!Buffer.isBuffer(buffer)) {
    throw new Error('buffer argument must be a Buffer');
  }
  var header = parseParams(params);
  if (!header.salt) {
    header.salt = crypto.randomBytes(KEY_LENGTH);
  }

  var result;
  if (header.version === 'aes128gcm') {
    // Save the DH public key in the header unless keyid is set.
    if (header.privateKey && !header.keyid) {
      header.keyid = header.privateKey.getPublicKey();
    }
    result = writeHeader(header);
  } else {
    // No header on other versions
    result = new Buffer(0);
  }

  var key = deriveKeyAndNonce(header, MODE_ENCRYPT, keyLookupCallback);
  var start = 0;
  var padSize = PAD_SIZE[header.version];
  var overhead = padSize;
  if (header.version === 'aes128gcm') {
    overhead += TAG_LENGTH;
  }
  var pad = isNaN(parseInt(params.pad, 10)) ? 0 : parseInt(params.pad, 10);

  var counter = 0;
  var last = false;
  while (!last) {
    // Pad so that at least one data byte is in a block.
    var recordPad = Math.min(header.rs - overhead - 1, pad);
    if (header.version !== 'aes128gcm') {
      recordPad = Math.min((1 << (padSize * 8)) - 1, recordPad);
    }
    if (pad > 0 && recordPad === 0) {
      ++recordPad; // Deal with perverse case of rs=overhead+1 with padding.
    }
    pad -= recordPad;

    var end = start + header.rs - overhead - recordPad;
    if (header.version !== 'aes128gcm') {
      // The > here ensures that we write out a padding-only block at the end
      // of a buffer.
      last = end > buffer.length;
    } else {
      last = end >= buffer.length;
    }
    last = last && pad <= 0;
    var block = encryptRecord(key, counter, buffer.slice(start, end),
                              recordPad, header, last);
    result = Buffer.concat([result, block]);

    start = end;
    ++counter;
  }
  return result;
}
function encrypt ( buffer , params , keyLookupCallback ) { if ( ! Buffer . isBuffer ( buffer ) ) { throw new Error ( 'buffer argument must be a Buffer' ) ; } var header = parseParams ( params ) ; if ( ! header . salt ) { header . salt = crypto . randomBytes ( KEY_LENGTH ) ; } var result ; if ( header . version === 'aes128gcm' ) { // Save the DH public key in the header unless keyid is set. if ( header . privateKey && ! header . keyid ) { header . keyid = header . privateKey . getPublicKey ( ) ; } result = writeHeader ( header ) ; } else { // No header on other versions result = new Buffer ( 0 ) ; } var key = deriveKeyAndNonce ( header , MODE_ENCRYPT , keyLookupCallback ) ; var start = 0 ; var padSize = PAD_SIZE [ header . version ] ; var overhead = padSize ; if ( header . version === 'aes128gcm' ) { overhead += TAG_LENGTH ; } var pad = isNaN ( parseInt ( params . pad , 10 ) ) ? 0 : parseInt ( params . pad , 10 ) ; var counter = 0 ; var last = false ; while ( ! last ) { // Pad so that at least one data byte is in a block. var recordPad = Math . min ( header . rs - overhead - 1 , pad ) ; if ( header . version !== 'aes128gcm' ) { recordPad = Math . min ( ( 1 << ( padSize * 8 ) ) - 1 , recordPad ) ; } if ( pad > 0 && recordPad === 0 ) { ++ recordPad ; // Deal with perverse case of rs=overhead+1 with padding. } pad -= recordPad ; var end = start + header . rs - overhead - recordPad ; if ( header . version !== 'aes128gcm' ) { // The > here ensures that we write out a padding-only block at the end // of a buffer. last = end > buffer . length ; } else { last = end >= buffer . length ; } last = last && pad <= 0 ; var block = encryptRecord ( key , counter , buffer . slice ( start , end ) , recordPad , header , last ) ; result = Buffer . concat ( [ result , block ] ) ; start = end ; ++ counter ; } return result ; }
Encrypt some bytes.  This uses the parameters to determine the key and block
size, which are described in the draft.

|params.version| contains the version of encoding to use: aes128gcm is the latest,
but aesgcm is also accepted (though the latter two might
disappear in a future release).  If omitted, assume aes128gcm.

If |params.key| is specified, that value is used as the key.

For Diffie-Hellman (WebPush), |params.dh| includes the public key of the
receiver.  |params.privateKey| is used to establish a shared secret.  Key
pairs can be created using |crypto.createECDH()|.
Encrypt some bytes . This uses the parameters to determine the key and block size which are described in the draft .