File:  [LON-CAPA] / loncom / auth / londes.js
Revision 1.10: download - view: text, annotated - select for diffs
Wed Feb 17 19:15:40 2016 UTC (8 years, 10 months ago) by raeburn
Branches: MAIN
CVS tags: version_2_12_X, version_2_11_X, version_2_11_5_msu, version_2_11_5, version_2_11_4_uiuc, version_2_11_4_msu, version_2_11_4, version_2_11_3_uiuc, version_2_11_3_msu, version_2_11_3, version_2_11_2_uiuc, version_2_11_2_msu, version_2_11_2_educog, version_2_11_2, HEAD
- Bug 5679

<script type="text/javascript" language="JavaScript">
// <![CDATA[
// The LearningOnline Network with CAPA
// Encryption Routines according to Data Encryption Standard DES
// Federal Information Processing Standards Publication 46-2 (1993 Dec 30)
//
// $Id: londes.js,v 1.10 2016/02/17 19:15:40 raeburn Exp $
//
// Copyright Michigan State University Board of Trustees
//
// This file is part of the LearningOnline Network with CAPA (LON-CAPA).
//
// LON-CAPA is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// LON-CAPA is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with LON-CAPA; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
// /home/httpd/html/adm/gpl.txt
//
// http://www.lon-capa.org/
//
// JavaScript Implementation by Gerd Kortemeyer
// 1997,06/27/00,06/28 Gerd Kortemeyer

// Global variables

// Array of integers with i-th bit set
var bit=new Array(31);
// Initial permutation IP for right part
var riparr=new Array(31);
// Inverse permutation IP-1
var liiparr=new Array(31);
var uiiparr=new Array(31);
// Key vectors
var uk=new Array(16);
var lk=new Array(16);
// Upper- and lower 32-bit of external key
var uextkey=0;
var lextkey=0;
// Upper- and lower 32-bit of block
var ublock=0;
var lblock=0;
// Upper and lower 24 bit of expanded right vector
var lexpand=0;
var uexpand=0;
// S-box array
var sbarr=new Array(511);
// E expansion
var etarr=new Array(47);
// P permutation
var pparr=new Array(31);
// r- and l-vector
var rv=0;
var lv=0;
// Blocks of data for text
var b0=0;
var b1=0;
var b2=0;
var b3=0;
// Text variable
var text="";

// Initialize table arrays and perform self test

function init() {
     window.status="Initializing ...";
    var rip="58504234261810 260524436282012 462544638302214 664564840322416 8";
    var iip=" 8162432 7152331 6142230 5132129 4122028 3111927 2101826 1 91725";
     var sb
     sb ="14 413 1 21511 8 310 612 5 9 0 7";
     sb+=" 015 7 414 213 110 61211 9 5 3 8";
     sb+=" 4 114 813 6 2111512 9 7 310 5 0";
     sb+="1512 8 2 4 9 1 7 511 31410 0 613";
     sb+="15 1 814 611 3 4 9 7 21312 0 510";
     sb+=" 313 4 715 2 81412 0 110 6 911 5";
     sb+=" 014 71110 413 1 5 812 6 9 3 215";
     sb+="13 810 1 315 4 211 6 712 0 514 9";
     sb+="10 0 914 6 315 5 11312 711 4 2 8";
     sb+="13 7 0 9 3 4 610 2 8 514121115 1";
     sb+="13 6 4 9 815 3 011 1 212 51014 7";
     sb+=" 11013 0 6 9 8 7 41514 311 5 212";
     sb+=" 71314 3 0 6 910 1 2 8 51112 415";
     sb+="13 811 5 615 0 3 4 7 212 11014 9";
     sb+="10 6 9 01211 71315 1 314 5 2 8 4";
     sb+=" 315 0 610 113 8 9 4 51112 7 214";
     sb+=" 212 4 1 71011 6 8 5 31513 014 9";
     sb+="1411 212 4 713 1 5 01510 3 9 8 6";
     sb+=" 4 2 1111013 7 815 912 5 6 3 014";
     sb+="11 812 7 114 213 615 0 910 4 5 3";
     sb+="12 11015 9 2 6 8 013 3 414 7 511";
     sb+="1015 4 2 712 9 5 6 11314 011 3 8";
     sb+=" 91415 5 2 812 3 7 0 410 11311 6";
     sb+=" 4 3 212 9 515101114 1 7 6 0 813";
     sb+=" 411 21415 0 813 312 9 7 510 6 1";
     sb+="13 011 7 4 9 11014 3 512 215 8 6";
     sb+=" 1 4111312 3 7141015 6 8 0 5 9 2";
     sb+=" 61113 8 1 410 7 9 5 01514 2 312";
     sb+="13 2 8 4 61511 110 9 314 5 012 7";
     sb+=" 11513 810 3 7 412 5 611 014 9 2";
     sb+=" 711 4 1 91214 2 0 6101315 3 5 8";
     sb+=" 2 114 7 410 8131512 9 0 3 5 611";
     var et
     et ="32 1 2 3 4 5 4 5 6 7 8 9 8 910111213121314151617";
     et+="1617181920212021222324252425262728292829303132 1";
     var pp="16 7202129122817 1152326 5183110 2 824143227 3 9191330 62211 425";
     bit[0]=1;
     for (var i=1; i<=31;i++) { bit[i]=bit[i-1]<<1; }
     for (i=0; i<=31;i++) {
        riparr[i]=parseInt(rip.substring(i*2,i*2+2));
        pparr[i]=parseInt(pp.substring(i*2,i*2+2));
     }
     for (i=0;i<=15;i++) {
        liiparr[i]=parseInt(iip.substring(i*2,i*2+2));
        uiiparr[i]=parseInt(iip.substring(32+i*2,32+i*2+2));
     }
     for (i=0;i<=511;i++) {
        sbarr[i]=parseInt(sb.substring(i*2,i*2+2));
     }
     for (i=0;i<=47;i++) {
        etarr[i]=parseInt(et.substring(i*2,i*2+2));
     }

     window.status="Ready.";
}

// Return a string with hex-representation of integer

function hexstring(i) {
     var hstr="";
     var hchr="0123456789abcdef";
     for (var k=28; k>=0; k=k-4) {
         j=0;
         for (var m=0; m<=3; m++) { if ((i&bit[k+m])!=0) { j=j|bit[m]; } }
         hstr+=hchr.substring(j,j+1);
     }   
     return(hstr);
}

// Shift a 28-bit register one time

function shift(sreg) {
     var bit27=(sreg&bit[0])<<27;
     return (sreg>>1)|bit27;
}
        
// Initialize key-arrays according to uextkey and lextkey

function initkeys() {
     init();
// Constants  
     var celements="574941332517 9 158504234261810 259514335271911 360524436";
     var delements="63554739312315 762544638302214 661534537292113 5282012 4";
     var lkelements="14171124 1 5 32815 62110231912 426 816 7272013 2";
     var ukelements="415231374755304051453348444939563453464250362932";
     var shifttimes="1122222212222221";
// PC-2 order
     var ukarr=new Array(23);
     var lkarr=new Array(23);
     for (i=0;i<=23;i++) {
        ukarr[i]=parseInt(ukelements.substring(i*2,i*2+2));
        lkarr[i]=parseInt(lkelements.substring(i*2,i*2+2));
     }
// Initialize c and d
     var bt;
     var c=0;
     var d=0;
     for (var i=0; i<=27;i++) {
          bt=parseInt(celements.substring(i*2,i*2+2));
          if (bt<=32) {
              if ((uextkey & bit[31-(bt-1)]) != 0) { c=c|bit[i]; }
          } else {
              if ((lextkey & bit[31-(bt-33)]) != 0) { c=c|bit[i]; }
          }
          bt=parseInt(delements.substring(i*2,i*2+2));
          if (bt<=32) {
              if ((uextkey & bit[31-(bt-1)]) != 0) { d=d|bit[i]; }
          } else {
              if ((lextkey & bit[31-(bt-33)]) != 0) { d=d|bit[i]; }
          }
      }
// Initialize the k vectors
      for (i=1;i<=16;i++) {
// Shift c and d
          if (shifttimes.substring(i-1,i)=='1') {
              c=shift(c);
              d=shift(d);
          } else {
              c=shift(shift(c));
              d=shift(shift(d));
          }
          uk[i]=0;
          lk[i]=0;
          for (j=0; j<=23;j++) {            
            if ((d&bit[ukarr[j]-29])!=0) { lk[i]=lk[i]|bit[23-j]; }
            if ((c&bit[lkarr[j]-1])!=0) { uk[i]=uk[i]|bit[23-j]; }
          }
      }
}

// Initial permutation of ublock and lblock into rv and lv

function ip() {
     var bt;
     rv=0;
     lv=0;
     for (var i=0; i<=31;i++) {
          bt=riparr[i];
          if (bt<=32) {
              if ((lblock & bit[bt-1]) != 0) { rv=rv|bit[i]; }
          } else {
              if ((ublock & bit[bt-33]) != 0) { rv=rv|bit[i]; }
          }
          if (bt<=33) {
              if ((lblock & bit[bt-2]) != 0) { lv=lv|bit[i]; }
          } else {
              if ((ublock & bit[bt-34]) != 0) { lv=lv|bit[i]; }
          }     
     }
}

// Inverse Initial Permutation IP-1, input rv,lv, output lblock,ublock

function invip() {
     var bt;
     ublock=0;
     lblock=0;
     for (var i=0; i<=15;i++) {
          bt=liiparr[i];
          if ((rv & bit[bt-1]) != 0) { lblock=lblock|bit[i*2]; }
          if ((lv & bit[bt-1]) != 0) { lblock=lblock|bit[i*2+1]; }
          bt=uiiparr[i];
          if ((rv & bit[bt-1]) != 0) { ublock=ublock|bit[i*2]; }
          if ((lv & bit[bt-1]) != 0) { ublock=ublock|bit[i*2+1]; }
     }
}

// Expansion of right vector according to E, input rv

function expand() {
    var bt;
    uexpand=0;
    lexpand=0;
    for (var i=0; i<=23; i++) {
       bt=etarr[i];
       if (rv & bit[bt-1]) { lexpand=lexpand|bit[i]; } 
    }
    for (i=24; i<=47; i++) {
       bt=etarr[i];
       if (rv & bit[bt-1]) { uexpand=uexpand|bit[i-24]; }
    }
}

// Permutes rv according to P, input/output rv

function permute() {
    var prv=rv;
    rv=0;
    for (var i=0; i<=31; i++) {
       if ((prv&bit[31-(pparr[i]-1)])!=0) { rv=rv|bit[31-i]; }
    }
}

// Performs stage si of the encryption, input/output rv

function stage(si) {
    expand();
    var uadd=uexpand^uk[si];
    var ladd=lexpand^lk[si];
    rv=0;
    var ks=0;
    for (var ki=42;ki>=24;ki=ki-6) {
       rv=rv<<4;
       var i=0;
       if ((uadd&bit[ki-24])!=0) { i=i|bit[0]; }
       if ((uadd&bit[ki-19])!=0) { i=i|bit[1]; }
       var j=0;
       for (var kj=0; kj<=3; kj++) {
          if ((uadd&bit[ki-23+kj])!=0) { j=j|bit[kj]; }
       }
       rv=rv|sbarr[ks*64+i*16+j];
       ks++;
    } 
    for (var ki=18;ki>=0;ki=ki-6) {
       rv=rv<<4;
       var i=0;
       if ((ladd&bit[ki]  )!=0) { i=i|bit[0]; }
       if ((ladd&bit[ki+5])!=0) { i=i|bit[1]; }
       var j=0;
       for (var kj=0; kj<=3; kj++) {
          if ((ladd&bit[ki+1+kj])!=0) { j=j|bit[kj]; }
       }
       rv=rv|sbarr[ks*64+i*16+j];
       ks++;
    }
    permute();
}

// Encryption

function encrypt() {
    ip();
    for (var i=1; i<=16; i++) {
        var prv=rv;
        stage(i);
        rv=rv^lv;
        lv=prv;
    }
    invip();
}

// Decryption

function decrypt() {
    ip();
    for (var i=16; i>=1; i--) {
        var prv=rv;
        stage(i);
        rv=rv^lv;
        lv=prv;
    }
    invip();
}

// Put text into b0,b1,b2,b3
    
function block(text) {;
var equiv= "*+ -./0123456789......@";
    equiv+="ABCDEFGHIJKLMNOPQRSTUVWXYZ    _ ";
    equiv+="abcdefghijklmnopqrstuvwxyz";
    var tl=text.length;
    if (tl>=16) { tl=15; }
    text+="                ";
    text=escape(text);
    var i;
    var c;
    var conv='';
    var j=0;
    for (i=0;i<15;i++) {
        if (text.charAt(j)=='%') {
           conv+=text.charAt(j+1)+text.charAt(j+2);
           j=j+3;
        } else {
           c=hexstring(42+equiv.indexOf(text.charAt(j)));
           conv+=c.substr(6,2);
           j++;
        }
    }
    b3=tl*bit[24]+parseInt("0x"+conv.substr(0,6));
    b2=parseInt("0x"+conv.substr(6,8));
    b1=parseInt("0x"+conv.substr(14,8));
    b0=parseInt("0x"+conv.substr(22,8));

}

function crypted(text) {
    block(text);
    lblock=b0;
    ublock=b1;
    encrypt();
    b0=lblock;
    b1=ublock;
    lblock=b2;
    ublock=b3;
    encrypt();
    b2=lblock;
    b3=ublock;
    return(hexstring(b3)+hexstring(b2)+hexstring(b1)+hexstring(b0));
}

function getCrypted(text) {
    var cryptedtext = '';
    if (text.length > 0) {
        var rem = text.length % 15;
        var count = Math.floor(text.length/15);
        if (rem > 0) {
            count ++;
        }
        for (var i=0; i<count; i++) {
            var start = i*15;
            cryptedtext += crypted(text.substr(start,15));
        }
    }
    return cryptedtext;
}


// ]]>
</script>

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>