//
// (c) 2007 Alexander E Genaud,
//     absolutely all rights reserved and more
//

/**
 * page 244 of Bruce Schneier's Applied Cryptography
 * http://en.wikipedia.org/wiki/Modular_exponentiation
 */
var modpow = function(b, e, m) {
   var result = 1;
   while (e > 0) {
      // multiply in this bits' contribution
      // while using modulus to keep result small
      if ((e & 1) == 1) result = (result * b) % m;
      e >>= 1;
      b = (b * b) % m;
   }
   return result;
}

var maxalert = 20;
var assertEquals = function(msg,x,y) {
  if (""+x != ""+y) {
    if ((maxalert-- % 1000) > 1) alert(msg +" expected: "+ x +" actual: "+ y);
  }
};

function d2h(d) {
  if ( (d-0) < 0 || (d-0) > 255) return "[out of bounds: "+d+"]";
  var h = d.toString(16);
  if (h.length == 1) return "0"+h;
  else return h;
}
function h2d(h) {
  return parseInt(h,16);
}

var c2m = function(str,e,n) {
  var prev = -1;
  var val = 0;
  var r = "";
  for (var i=0; i<str.length; i++) {
    if (str.substr(i,1).match("[0-9a-fA-F]")) {
      val = h2d(str.substr(i,1)) -0;
      if (prev > -1) {
        r += String.fromCharCode(modpow( prev + val , e , n));
        prev = -1;
      }
      else {
        prev = 16 * val;
      } // fi prev
    } // fi str match 0-9a-f
  } // rof
  return r;
}

var m2c = function(str,e,n) {
  var r = "";
  for (var i=0; i<str.length; i++) {
    r += r.length == 0 ? "" : " ";
    r += d2h(modpow(str.charCodeAt(i),e,n));
  }
  return r;
}

var encrypt = function() {
  var m = document.frm.m.value;
  var e = document.frm.e.value;
  var n = document.frm.n.value;
  document.frm.c.value = m2c(m,e,n);
}

var decrypt = function() {
  var c = document.frm.c.value;
  var e = document.frm.e.value;
  var n = document.frm.n.value;
  document.frm.m.value = c2m(c,e,n);
}


