Graal Forums

Graal Forums (https://forums.graalonline.com/forums/index.php)
-   Future Improvements (https://forums.graalonline.com/forums/forumdisplay.php?f=10)
-   -   Bitwise zero-fill right shift (https://forums.graalonline.com/forums/showthread.php?t=87551)

WhiteDragon 08-22-2009 07:52 AM

Bitwise zero-fill right shift
 
It'd be nice if I could do this in addition to the other bitwise shifts.

Usually, this is represented by >>>.

I need it for an encryption algorithm I'm currently writing.

Example:

-9 (base 10): 11111111111111111111111111110111 (base 2)
-9 >> 2 (base 10): 11111111111111111111111111111101 (base 2) = -3 (base 10)
-9 >>> 2 (base 10): 00111111111111111111111111111101 (base 2) = 1073741821 (base 10)


It'd be cool if this was done on the current client, or at least v6.

This, and unsigned bitwise shifts, which I already made a thread about awhile back.

WhiteDragon 08-22-2009 09:08 AM

And here is the script that it's for... I had to remove all whitespace, comments and two precomputed variables for it to fit though.

If the >>> ever gets added I'll release a working version in the Code Gallery.

Example:
AESEncryptCtr("bob", "kadoweu239a0djwei23oqe9w", 128)

I imagine this could be added to shared.encrypt as well.

PHP Code:

function Cipher(temp.input, temp.w) {
  
temp.Nb = 4;
  
temp.Nr = temp.w.size()/temp.Nb - 1;
  
temp.state = {};
  
temp.state[0] = {};
  
temp.state[1] = {};
  
temp.state[2] = {};
  
temp.state[3] = {};
  for (
temp.i = 0; temp.i < 4*temp.Nb; temp.i++) {
  }
  
temp.state = AddRoundKey(temp.state, temp.w, 0, temp.Nb);
  for (
temp.round = 1; temp.round < temp.Nr; temp.round++) {
    
temp.state = SubBytes(temp.state, temp.Nb);
    
temp.state = ShiftRows(temp.state, temp.Nb);
    
temp.state = MixColumns(temp.state, temp.Nb);
    
temp.state = AddRoundKey(temp.state, temp.w, temp.round, temp.Nb);
  }
  
temp.state = SubBytes(temp.state, temp.Nb);
  
temp.state = ShiftRows(temp.state, temp.Nb);
  
temp.state = AddRoundKey(temp.state, temp.w, temp.Nr, temp.Nb);
  
temp.output = new [4*temp.Nb];
  for (
temp.i = 0; temp.i < 4*temp.Nb; temp.i++) {
  }
  return 
temp.output;
}
function 
SubBytes(temp.s, temp.Nb) {
  for (
temp.r = 0; temp.r < 4; temp.r++) {
    for (
temp.c = 0; temp.c < temp.Nb; temp.c++) {
      
temp.s[temp.r][temp.c] = this.Sbox[temp.s[temp.r][temp.c]];
    }
  }
  return 
s;
}
function 
ShiftRows(temp.s, temp.Nb) {
  
temp.t = new [4];
  for (
temp.r = 1; temp.r < 4; temp.r++) {
    for (
temp.c = 0; temp.c < 4; temp.c++) {
    }
    for (
temp.c=0; temp.c < 4; temp.c++) {
      
temp.s[temp.r][temp.c] = temp.t[temp.c];
    }
  }
  return 
s;
}
function 
MixColumns(temp.s, temp.Nb) {
  for (
temp.c = 0; temp.c < 4; temp.c++) {
    
temp.a = new [4];
    
temp.b = new [4];
    for (
temp.i = 0; temp.i < 4; temp.i++) {
      
temp.a[temp.i] = temp.s[temp.i][temp.c];
      
temp.b[temp.i] = temp.s[temp.i][temp.c]&0x80 ? temp.s[temp.i][temp.c]<<1 xor 0x011b : temp.s[temp.i][temp.c]<<1;
    }
    
temp.s[0][temp.c] = temp.b[0] xor temp.a[1] xor temp.b[1] xor temp.a[2] xor temp.a[3];
    
temp.s[1][temp.c] = temp.a[0] xor temp.b[1] xor temp.a[2] xor temp.b[2] xor temp.a[3];
    
temp.s[2][temp.c] = temp.a[0] xor temp.a[1] xor temp.b[2] xor temp.a[3] xor temp.b[3];
    
temp.s[3][temp.c] = temp.a[0] xor temp.b[0] xor temp.a[1] xor temp.a[2] xor temp.b[3];
  }
  return 
temp.s;
}
function 
AddRoundKey(temp.state, temp.w, temp.rnd, temp.Nb) {
  for (
temp.r = 0; temp.r < 4; temp.r++) {
    for (
temp.c = 0; temp.c < temp.Nb; temp.c++) {
      
temp.state[temp.r][temp.c] = temp.state[temp.r][temp.c] xor temp.w[temp.rnd*4 + temp.c][temp.r];
    }
  }
  return 
temp.state;
}
function 
KeyExpansion(temp.key) {
  
temp.Nb = 4;
  
temp.Nk = temp.key.size()/4;
  
temp.Nr = temp.Nk + 6;
  
temp.w = new [temp.Nb * (temp.Nr+1)];
  
temp.temp = new [4];
  for (
temp.i = 0; temp.i < temp.Nk; temp.i++) {
    
temp.r = {temp.key[4*temp.i], temp.key[4*temp.i + 1], temp.key[4*temp.i + 2], temp.key[4*temp.i + 3]};
    
temp.w[temp.i] = temp.r;
  }
  for (
temp.i = temp.Nk; temp.i < (temp.Nb*(temp.Nr+1)); temp.i++) {
    
temp.w[temp.i] = new [4];
    for (
temp.t = 0; temp.t < 4; temp.t++) {
      
temp.temp[temp.t] = temp.w[temp.i-1][temp.t];
    }
      
temp.temp = SubWord(RotWord(temp.temp));
      for (
temp.t = 0; temp.t < 4; temp.t++) {
        
temp.temp[temp.t] = temp.temp[temp.t] xor this.Rcon[temp.i/temp.Nk][temp.t];
      }
      
temp.temp = SubWord(temp.temp);
    }
    for (
temp.t = 0; temp.t < 4; temp.t++) {
      
temp.w[temp.i][temp.t] = temp.w[temp.i-temp.Nk][temp.t] xor temp.temp[temp.t];
    }
  }
  return 
temp.w;
}
function 
SubWord(temp.w) {
  for (
temp.i = 0; temp.i < 4; temp.i++) {
    
temp.w[temp.i] = this.Sbox[temp.w[temp.i]];
  }
  return 
w;
}
function 
RotWord(temp.w) {
  
temp.tmp = temp.w[0];
  for (
temp.i = 0; temp.i < 3; temp.i++) {
    
temp.w[temp.i] = temp.w[temp.i+1];
  }
  
temp.w[3] = temp.tmp;
  return 
temp.w;
}
function 
AESEncryptCtr(temp.plaintext, temp.password, temp.nBits) {
  
temp.blockSize = 16;
  if (!(
temp.nBits == 128 || temp.nBits == 192 || temp.nBits == 256)) return "";
    
  
temp.nBytes = temp.nBits/8;
  
temp.pwBytes = new [temp.nBytes];
  for (
temp.i = 0; temp.i < temp.nBytes; temp.i++) {
    
temp.pwBytes[temp.i] = getascii(temp.password.charat(i));
  }
  
temp.key = Cipher(temp.pwBytes, KeyExpansion(temp.pwBytes));
  
temp.key.addarray(temp.key.subarray(0, temp.nBytes-16));
  
temp.counterBlock = new [temp.blockSize];
  
temp.nonce = timevar2;
  
temp.nonceSec = int(temp.nonce/1000);
  for (
temp.i = 0; temp.i < 4; temp.i++) {
    
temp.counterBlock[temp.i] = (temp.nonceSec >>> temp.i*8) & 0xff;
  }
  for (
temp.i = 0; temp.i < 4; temp.i++) {
    
temp.counterBlock[temp.i+4] = temp.nonceMs & 0xff;
  }
  
temp.ctrTxt = "";
  for (
temp.i = 0; temp.i < 8; temp.i++) {
    
temp.ctrTxt @= char(temp.counterBlock[temp.i]);
  }
  
temp.keySchedule = KeyExpansion(temp.key);
  
temp.blockCount = ceil(temp.plaintext.length()/temp.blockSize)+1;
  
temp.ciphertxt = new [temp.blockCount];
  for (
temp.b = 0; temp.b < temp.blockCount; temp.b++) {
    for (
temp.c = 0; temp.c < 4; temp.c++) {
      
temp.counterBlock[15-temp.c] = (temp.b >>> temp.c*8) & 0xff;
    }
    for (
temp.c = 0; temp.c < 4; temp.c++) {
      
temp.counterBlock[15-temp.c-4] = (temp.b/0x100000000 >>> temp.c*8);
    }
    
temp.cipherCntr = Cipher(temp.counterBlock, temp.keySchedule);
    
temp.cipherChar = new [temp.blockLength];
    for (
temp.i = 0; temp.i < temp.blockLength; temp.i++) {
      
temp.cipherChar[temp.i] = temp.cipherCntr[temp.i] xor getascii(temp.plaintext.charat(temp.b*temp.blockSize+temp.i));
      
temp.cipherChar[temp.i] = char(temp.cipherChar[temp.i]);
    }
    for (
temp.i = 0; temp.i < cipherChar.size(); temp.i++) {
      
temp.ciphertxt[temp.b] @= cipherChar[temp.i];
    }
  }
  
temp.ciphertext = temp.ctrTxt;
  for (
temp.i = 0; temp.i < cipherChar.size(); temp.i++) {
    
temp.ciphertext @= cipherChar[temp.i];
  }
  
temp.ciphertext = base64encode(ciphertext);
  return 
temp.ciphertext;
}
function 
ceil(temp.i) {
  return (
temp.i == int(temp.i) ? temp.i : int(temp.i)+1);
}
function 
AESDecryptCtr(temp.ciphertext, temp.password, temp.nBits) {
  
temp.blockSize = 16;
  if (!(
temp.nBits==128 || temp.nBits==192 || temp.nBits==256)) return "";
  
temp.ciphertext = base64decode(temp.ciphertext);
  
temp.nBytes = temp.nBits/8;
  
temp.pwBytes = new [temp.nBytes];
  for (
temp.i = 0; temp.i < temp.nBytes; temp.i++) {
    
temp.pwBytes[temp.i] = getascii(temp.password.charat(i));
  }
  
temp.key = Cipher(temp.pwBytes, KeyExpansion(temp.pwBytes));
  
temp.key.addarray(temp.key.subarray(0, temp.nBytes-16));
  
temp.counterBlock = new [8];
  
temp.ctrTxt = temp.ciphertext.subarray(0, 8);
  for (
temp.i = 0; temp.i < 8; temp.i++)
    
temp.counterBlock[temp.i] = getascii(temp.ctrTxt.charat(i));
  
temp.keySchedule = KeyExpansion(temp.key);
  
temp.nBlocks = ceil((temp.ciphertext.length()-8) / temp.blockSize);
  
temp.ct = new [temp.nBlocks];
  for (
temp.b = 0; temp.b < temp.nBlocks; temp.b++)
    
temp.ct[temp.b] = temp.ciphertext.subarray(8+temp.b*temp.blockSize, 8+temp.b*temp.blockSize+temp.blockSize);
  
temp.ciphertext = temp.ct;
  
temp.plaintxt = new [temp.ciphertext.length];
  for (
temp.b = 0; temp.b < temp.nBlocks; temp.b++) {
    for (
temp.c = 0; temp.c < 4; temp.c++) {
      
temp.counterBlock[15-temp.c] = ((temp.b) >>> temp.c*8) & 0xff;
    }
    for (
temp.c = 0; temp.c < 4; temp.c++) {
      
temp.counterBlock[15-temp.c-4] = (((temp.b+1)/0x100000000-1) >>> temp.c*8) & 0xff;
    }
    
temp.cipherCntr = Cipher(temp.counterBlock, temp.keySchedule);
    
temp.plaintxtByte = new [temp.ciphertext[temp.b].length()];
    for (
temp.i = 0; temp.i < temp.ciphertext[temp.b].length(); temp.i++) {
      
temp.plaintxtByte[temp.i] = temp.cipherCntr[temp.i] xor getascii(temp.ciphertext[temp.b].charat(i));
      
temp.plaintxtByte[temp.i] = char(temp.plaintxtByte[i]);
    }
    
temp.plaintxt = "";
    for (
temp.i = 0; temp.i < temp.plaintxtByte.size(); temp.i++) {
      
temp.plaintxt[temp.b] @= temp.plaintxtByte[temp.i];
    }
  }
  
temp.plaintext = "";
  for (
temp.i = 0; temp.i < temp.plaintxt.size(); temp.i++) {
    
temp.plaintext @= temp.plaintxt[temp.i];
  }
  return 
temp.plaintext;
} 



All times are GMT +2. The time now is 01:48 PM.

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2026, vBulletin Solutions Inc.
Copyright (C) 1998-2019 Toonslab All Rights Reserved.