Annotation of loncom/auth/londes.js, revision 1.1
1.1 ! www 1: <script language="JavaScript">
! 2: // The LearningOnline Network with CAPA
! 3: // Encryption Routines according to Data Encryption Standard DES
! 4: // Federal Information Processing Standards Publication 46-2 (1993 Dec 30)
! 5: // JavaScript Implementation by Gerd Kortemeyer
! 6: // 1997,06/27/00,06/28 Gerd Kortemeyer
! 7:
! 8: // Global variables
! 9:
! 10: // Array of integers with i-th bit set
! 11: var bit=new Array(31);
! 12: // Initial permutation IP for right part
! 13: var riparr=new Array(31);
! 14: // Inverse permutation IP-1
! 15: var liiparr=new Array(31);
! 16: var uiiparr=new Array(31);
! 17: // Key vectors
! 18: var uk=new Array(16);
! 19: var lk=new Array(16);
! 20: // Upper- and lower 32-bit of external key
! 21: var uextkey=0;
! 22: var lextkey=0;
! 23: // Upper- and lower 32-bit of block
! 24: var ublock=0;
! 25: var lblock=0;
! 26: // Upper and lower 24 bit of expanded right vector
! 27: var lexpand=0;
! 28: var uexpand=0;
! 29: // S-box array
! 30: var sbarr=new Array(511);
! 31: // E expansion
! 32: var etarr=new Array(47);
! 33: // P permutation
! 34: var pparr=new Array(31);
! 35: // r- and l-vector
! 36: var rv=0;
! 37: var lv=0;
! 38: // Blocks of data for text
! 39: var b0=0;
! 40: var b1=0;
! 41: var b2=0;
! 42: var b3=0;
! 43: // Text variable
! 44: var text="";
! 45:
! 46: // Initialize table arrays and perform self test
! 47:
! 48: function init() {
! 49: window.status="Initializing ...";
! 50: var rip="58504234261810 260524436282012 462544638302214 664564840322416 8";
! 51: var iip=" 8162432 7152331 6142230 5132129 4122028 3111927 2101826 1 91725";
! 52: var sb
! 53: sb ="14 413 1 21511 8 310 612 5 9 0 7";
! 54: sb+=" 015 7 414 213 110 61211 9 5 3 8";
! 55: sb+=" 4 114 813 6 2111512 9 7 310 5 0";
! 56: sb+="1512 8 2 4 9 1 7 511 31410 0 613";
! 57: sb+="15 1 814 611 3 4 9 7 21312 0 510";
! 58: sb+=" 313 4 715 2 81412 0 110 6 911 5";
! 59: sb+=" 014 71110 413 1 5 812 6 9 3 215";
! 60: sb+="13 810 1 315 4 211 6 712 0 514 9";
! 61: sb+="10 0 914 6 315 5 11312 711 4 2 8";
! 62: sb+="13 7 0 9 3 4 610 2 8 514121115 1";
! 63: sb+="13 6 4 9 815 3 011 1 212 51014 7";
! 64: sb+=" 11013 0 6 9 8 7 41514 311 5 212";
! 65: sb+=" 71314 3 0 6 910 1 2 8 51112 415";
! 66: sb+="13 811 5 615 0 3 4 7 212 11014 9";
! 67: sb+="10 6 9 01211 71315 1 314 5 2 8 4";
! 68: sb+=" 315 0 610 113 8 9 4 51112 7 214";
! 69: sb+=" 212 4 1 71011 6 8 5 31513 014 9";
! 70: sb+="1411 212 4 713 1 5 01510 3 9 8 6";
! 71: sb+=" 4 2 1111013 7 815 912 5 6 3 014";
! 72: sb+="11 812 7 114 213 615 0 910 4 5 3";
! 73: sb+="12 11015 9 2 6 8 013 3 414 7 511";
! 74: sb+="1015 4 2 712 9 5 6 11314 011 3 8";
! 75: sb+=" 91415 5 2 812 3 7 0 410 11311 6";
! 76: sb+=" 4 3 212 9 515101114 1 7 6 0 813";
! 77: sb+=" 411 21415 0 813 312 9 7 510 6 1";
! 78: sb+="13 011 7 4 9 11014 3 512 215 8 6";
! 79: sb+=" 1 4111312 3 7141015 6 8 0 5 9 2";
! 80: sb+=" 61113 8 1 410 7 9 5 01514 2 312";
! 81: sb+="13 2 8 4 61511 110 9 314 5 012 7";
! 82: sb+=" 11513 810 3 7 412 5 611 014 9 2";
! 83: sb+=" 711 4 1 91214 2 0 6101315 3 5 8";
! 84: sb+=" 2 114 7 410 8131512 9 0 3 5 611";
! 85: var et
! 86: et ="32 1 2 3 4 5 4 5 6 7 8 9 8 910111213121314151617";
! 87: et+="1617181920212021222324252425262728292829303132 1";
! 88: var pp="16 7202129122817 1152326 5183110 2 824143227 3 9191330 62211 425";
! 89: bit[0]=1;
! 90: for (var i=1; i<=31;i++) { bit[i]=bit[i-1]<<1; }
! 91: for (i=0; i<=31;i++) {
! 92: riparr[i]=parseInt(rip.substring(i*2,i*2+2));
! 93: pparr[i]=parseInt(pp.substring(i*2,i*2+2));
! 94: }
! 95: for (i=0;i<=15;i++) {
! 96: liiparr[i]=parseInt(iip.substring(i*2,i*2+2));
! 97: uiiparr[i]=parseInt(iip.substring(32+i*2,32+i*2+2));
! 98: }
! 99: for (i=0;i<=511;i++) {
! 100: sbarr[i]=parseInt(sb.substring(i*2,i*2+2));
! 101: }
! 102: for (i=0;i<=47;i++) {
! 103: etarr[i]=parseInt(et.substring(i*2,i*2+2));
! 104: }
! 105:
! 106: window.status="Ready.";
! 107: }
! 108:
! 109: // Return a string with hex-representation of integer
! 110:
! 111: function hexstring(i) {
! 112: var hstr="";
! 113: var hchr="0123456789abcdef";
! 114: for (var k=28; k>=0; k=k-4) {
! 115: j=0;
! 116: for (var m=0; m<=3; m++) { if ((i&bit[k+m])!=0) { j=j|bit[m]; } }
! 117: hstr+=hchr.substring(j,j+1);
! 118: }
! 119: return(hstr);
! 120: }
! 121:
! 122: // Shift a 28-bit register one time
! 123:
! 124: function shift(sreg) {
! 125: var bit27=(sreg&bit[0])<<27;
! 126: return (sreg>>1)|bit27;
! 127: }
! 128:
! 129: // Initialize key-arrays according to uextkey and lextkey
! 130:
! 131: function initkeys() {
! 132: // Constants
! 133: var celements="574941332517 9 158504234261810 259514335271911 360524436";
! 134: var delements="63554739312315 762544638302214 661534537292113 5282012 4";
! 135: var lkelements="14171124 1 5 32815 62110231912 426 816 7272013 2";
! 136: var ukelements="415231374755304051453348444939563453464250362932";
! 137: var shifttimes="1122222212222221";
! 138: // PC-2 order
! 139: var ukarr=new Array(23);
! 140: var lkarr=new Array(23);
! 141: for (i=0;i<=23;i++) {
! 142: ukarr[i]=parseInt(ukelements.substring(i*2,i*2+2));
! 143: lkarr[i]=parseInt(lkelements.substring(i*2,i*2+2));
! 144: }
! 145: // Initialize c and d
! 146: var bt;
! 147: var c=0;
! 148: var d=0;
! 149: for (var i=0; i<=27;i++) {
! 150: bt=parseInt(celements.substring(i*2,i*2+2));
! 151: if (bt<=32) {
! 152: if ((uextkey & bit[31-(bt-1)]) != 0) { c=c|bit[i]; }
! 153: } else {
! 154: if ((lextkey & bit[31-(bt-33)]) != 0) { c=c|bit[i]; }
! 155: }
! 156: bt=parseInt(delements.substring(i*2,i*2+2));
! 157: if (bt<=32) {
! 158: if ((uextkey & bit[31-(bt-1)]) != 0) { d=d|bit[i]; }
! 159: } else {
! 160: if ((lextkey & bit[31-(bt-33)]) != 0) { d=d|bit[i]; }
! 161: }
! 162: }
! 163: // Initialize the k vectors
! 164: for (i=1;i<=16;i++) {
! 165: // Shift c and d
! 166: if (shifttimes.substring(i-1,i)=='1') {
! 167: c=shift(c);
! 168: d=shift(d);
! 169: } else {
! 170: c=shift(shift(c));
! 171: d=shift(shift(d));
! 172: }
! 173: uk[i]=0;
! 174: lk[i]=0;
! 175: for (j=0; j<=23;j++) {
! 176: if ((d&bit[ukarr[j]-29])!=0) { lk[i]=lk[i]|bit[23-j]; }
! 177: if ((c&bit[lkarr[j]-1])!=0) { uk[i]=uk[i]|bit[23-j]; }
! 178: }
! 179: }
! 180: }
! 181:
! 182: // Initial permutation of ublock and lblock into rv and lv
! 183:
! 184: function ip() {
! 185: var bt;
! 186: rv=0;
! 187: lv=0;
! 188: for (var i=0; i<=31;i++) {
! 189: bt=riparr[i];
! 190: if (bt<=32) {
! 191: if ((lblock & bit[bt-1]) != 0) { rv=rv|bit[i]; }
! 192: } else {
! 193: if ((ublock & bit[bt-33]) != 0) { rv=rv|bit[i]; }
! 194: }
! 195: if (bt<=33) {
! 196: if ((lblock & bit[bt-2]) != 0) { lv=lv|bit[i]; }
! 197: } else {
! 198: if ((ublock & bit[bt-34]) != 0) { lv=lv|bit[i]; }
! 199: }
! 200: }
! 201: }
! 202:
! 203: // Inverse Initial Permutation IP-1, input rv,lv, output lblock,ublock
! 204:
! 205: function invip() {
! 206: var bt;
! 207: ublock=0;
! 208: lblock=0;
! 209: for (var i=0; i<=15;i++) {
! 210: bt=liiparr[i];
! 211: if ((rv & bit[bt-1]) != 0) { lblock=lblock|bit[i*2]; }
! 212: if ((lv & bit[bt-1]) != 0) { lblock=lblock|bit[i*2+1]; }
! 213: bt=uiiparr[i];
! 214: if ((rv & bit[bt-1]) != 0) { ublock=ublock|bit[i*2]; }
! 215: if ((lv & bit[bt-1]) != 0) { ublock=ublock|bit[i*2+1]; }
! 216: }
! 217: }
! 218:
! 219: // Expansion of right vector according to E, input rv
! 220:
! 221: function expand() {
! 222: var bt;
! 223: uexpand=0;
! 224: lexpand=0;
! 225: for (var i=0; i<=23; i++) {
! 226: bt=etarr[i];
! 227: if (rv & bit[bt-1]) { lexpand=lexpand|bit[i]; }
! 228: }
! 229: for (i=24; i<=47; i++) {
! 230: bt=etarr[i];
! 231: if (rv & bit[bt-1]) { uexpand=uexpand|bit[i-24]; }
! 232: }
! 233: }
! 234:
! 235: // Permutes rv according to P, input/output rv
! 236:
! 237: function permute() {
! 238: var prv=rv;
! 239: rv=0;
! 240: for (var i=0; i<=31; i++) {
! 241: if ((prv&bit[31-(pparr[i]-1)])!=0) { rv=rv|bit[31-i]; }
! 242: }
! 243: }
! 244:
! 245: // Performs stage si of the encryption, input/output rv
! 246:
! 247: function stage(si) {
! 248: expand();
! 249: var uadd=uexpand^uk[si];
! 250: var ladd=lexpand^lk[si];
! 251: rv=0;
! 252: var ks=0;
! 253: for (var ki=42;ki>=24;ki=ki-6) {
! 254: rv=rv<<4;
! 255: var i=0;
! 256: if ((uadd&bit[ki-24])!=0) { i=i|bit[0]; }
! 257: if ((uadd&bit[ki-19])!=0) { i=i|bit[1]; }
! 258: var j=0;
! 259: for (var kj=0; kj<=3; kj++) {
! 260: if ((uadd&bit[ki-23+kj])!=0) { j=j|bit[kj]; }
! 261: }
! 262: rv=rv|sbarr[ks*64+i*16+j];
! 263: ks++;
! 264: }
! 265: for (var ki=18;ki>=0;ki=ki-6) {
! 266: rv=rv<<4;
! 267: var i=0;
! 268: if ((ladd&bit[ki] )!=0) { i=i|bit[0]; }
! 269: if ((ladd&bit[ki+5])!=0) { i=i|bit[1]; }
! 270: var j=0;
! 271: for (var kj=0; kj<=3; kj++) {
! 272: if ((ladd&bit[ki+1+kj])!=0) { j=j|bit[kj]; }
! 273: }
! 274: rv=rv|sbarr[ks*64+i*16+j];
! 275: ks++;
! 276: }
! 277: permute();
! 278: }
! 279:
! 280: // Encryption
! 281:
! 282: function encrypt() {
! 283: ip();
! 284: for (var i=1; i<=16; i++) {
! 285: var prv=rv;
! 286: stage(i);
! 287: rv=rv^lv;
! 288: lv=prv;
! 289: }
! 290: invip();
! 291: }
! 292:
! 293: // Decryption
! 294:
! 295: function decrypt() {
! 296: ip();
! 297: for (var i=16; i>=1; i--) {
! 298: var prv=rv;
! 299: stage(i);
! 300: rv=rv^lv;
! 301: lv=prv;
! 302: }
! 303: invip();
! 304: }
! 305:
! 306: // Put text into b0,b1,b2,b3
! 307:
! 308: function block(text) {;
! 309: var equiv= "*+ -./0123456789......@";
! 310: equiv+="ABCDEFGHIJKLMNOPQRSTUVWXYZ _ ";
! 311: equiv+="abcdefghijklmnopqrstuvwxyz";
! 312: var tl=text.length;
! 313: if (tl>=16) { tl=15; }
! 314: text+=" ";
! 315: text=escape(text);
! 316: var i;
! 317: var c;
! 318: var conv='';
! 319: var j=0;
! 320: for (i=0;i<15;i++) {
! 321: if (text.charAt(j)=='%') {
! 322: conv+=text.charAt(j+1)+text.charAt(j+2);
! 323: j=j+3;
! 324: } else {
! 325: c=hexstring(42+equiv.indexOf(text.charAt(j)));
! 326: conv+=c.substr(6,2);
! 327: j++;
! 328: }
! 329: }
! 330: b3=tl*bit[24]+parseInt("0x"+conv.substr(0,6));
! 331: b2=parseInt("0x"+conv.substr(6,8));
! 332: b1=parseInt("0x"+conv.substr(14,8));
! 333: b0=parseInt("0x"+conv.substr(22,8));
! 334:
! 335: }
! 336:
! 337: function crypted(text) {
! 338: block(text);
! 339: lblock=b0;
! 340: ublock=b1;
! 341: encrypt();
! 342: b0=lblock;
! 343: b1=ublock;
! 344: lblock=b2;
! 345: ublock=b3;
! 346: encrypt();
! 347: b2=lblock;
! 348: b3=ublock;
! 349: return(hexstring(b3)+hexstring(b2)+hexstring(b1)+hexstring(b0));
! 350: }
! 351:
! 352: </script>
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>