package jmathlib.toolbox.crypto;
/* This file is part or JMathLib
* */
import jmathlib.core.tokens.*;
import jmathlib.core.tokens.numbertokens.DoubleNumberToken;
import jmathlib.core.functions.ExternalFunction;
import jmathlib.core.interpreter.GlobalValues;
/**An external function for computing a mesh of a matrix */
public class aes extends ExternalFunction
{
/**returns two matrices
* @param operands[0] = x values (e.g. [-2:0.2:2])
* @param operands[1] = y values (e.g. [-2:0.2:2])
* @param operands[2] = y values (e.g. [-2:0.2:2])
* @return [X,Y] as matrices */
public OperandToken evaluate(Token[] operands, GlobalValues globals)
{
// one operand
if (getNArgIn(operands)!=3)
throwMathLibException("AES: number of input arguments != 3");
if (!(operands[0] instanceof CharToken))
throwMathLibException("AES: first argument: encrypt or decrypt");
if ( !(operands[1] instanceof DoubleNumberToken) ||
!(operands[2] instanceof DoubleNumberToken) )
throwMathLibException("AES: works only on numbers");
// get data from arguments
String type = ((CharToken)operands[0]).getValue();
double[][] x = ((DoubleNumberToken)operands[1]).getReValues();
double[][] y = ((DoubleNumberToken)operands[2]).getReValues();
// AES works only on blocks of 16 bytes = 128bits
if ((x.length != 1) ||
(x[0].length != 16) ||
(y.length != 1) ||
(y[0].length != 16) )
throwMathLibException("AES: works only on row vectors with 16 bytes");
// convert key from double to byte array
byte[] cipherKey = new byte[16];
for (int i=0; i<16; i++)
{
// check if key numbers are positiv and only 8 bits max
if ((y[0][i]<0) || (y[0][i]>255))
throwMathLibException("AES expects input between 0 (0x0) and 255 (0xff)");
cipherKey[i] = new Double(y[0][i]).byteValue();
}
// prepare key
makeKey(cipherKey, 128 );
// allocate memory of plain text and cipher text
byte[] plainText = { 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0 };
byte[] cipherText = { 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0 };
// allocate memry for return numbers
double[][] ret = new double[1][16];
// encryption or decryption
if (type.toLowerCase().substring(0,1).equals("e"))
{
// encrypt
// convert plain text to byte array
for (int i=0; i<16; i++)
{
// check if numbers are positiv and only 8 bits max
if ((x[0][i]<0) || (x[0][i]>255))
throwMathLibException("AES expects plain text between 0 (0x0) and 255 (0xff)");
plainText[i] = new Double(x[0][i]).byteValue();
}
// compute encryption
encrypt(plainText, cipherText);
// convert byte to double
for (int i=0; i<16; i++)
{
ret[0][i] = (double)(cipherText[i]);
// move range -128 to 127 into the range 0 to 255
if (ret[0][i]<0)
ret[0][i] = 256 + ret[0][i];
}
}
else
{
// decrypt
// convert cipher text to byte array
for (int i=0; i<16; i++)
{
// check if numbers are positiv and only 8 bits max
if ((x[0][i]<0) || (x[0][i]>255))
throwMathLibException("AES expects cypher text between 0 (0x0) and 255 (0xff)");
cipherText[i] = new Double(x[0][i]).byteValue();
}
// compute decryption
decrypt(cipherText, plainText);
// convert byte to double
for (int i=0; i<16; i++)
{
ret[0][i] = (double)(plainText[i]);
// move range -128 to 127 into the range 0 to 255
if (ret[0][i]<0)
ret[0][i] = 256 + ret[0][i];
}
} // end encrypt/decrypt
//try {
// System.out.println("cipher Key " + new String(cipherKey, "UTF8") );
// System.out.println("plaintext block "+ new String(plainText, "UTF8") );
// System.out.println("ciphertext block "+ new String(cipherText, "UTF8") );
//}
//catch (Exception e){;}
return new DoubleNumberToken(ret);
} // end eval
/**
* AES.java
*
* The Advanced Encryption Standard (Rijndael, aka AES) block cipher,
* designed by J. Daemen and V. Rijmen.
*
* @author Paulo S. L. M. Barreto
*
* This software is hereby placed in the public domain.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
//public final class AES { //extends BlockCipher {
// public AES() {
// }
/**
* AES block size in bits
* (N.B. the Rijndael algorithm itself allows for other sizes).
*/
public static final int BLOCK_BITS = 128;
/**
* AES block size in bytes
* (N.B. the Rijndael algorithm itself allows for other sizes).
*/
public static final int BLOCK_SIZE = (BLOCK_BITS >>> 3);
public static final int DIR_DECRYPT = 1;
public static final int DIR_ENCRYPT = 2;
public static final int DIR_BOTH = 3;
/**
* Block size in bytes
*/
public final int blockSize() {
return BLOCK_SIZE;
}
/**
* Block size in bytes
*/
public final int keySize() {
return Nk << 5;
}
/**
* Substitution table (S-box).
*/
private static final String SS =
"\u637C\u777B\uF26B\u6FC5\u3001\u672B\uFED7\uAB76" +
"\uCA82\uC97D\uFA59\u47F0\uADD4\uA2AF\u9CA4\u72C0" +
"\uB7FD\u9326\u363F\uF7CC\u34A5\uE5F1\u71D8\u3115" +
"\u04C7\u23C3\u1896\u059A\u0712\u80E2\uEB27\uB275" +
"\u0983\u2C1A\u1B6E\u5AA0\u523B\uD6B3\u29E3\u2F84" +
"\u53D1\u00ED\u20FC\uB15B\u6ACB\uBE39\u4A4C\u58CF" +
"\uD0EF\uAAFB\u434D\u3385\u45F9\u027F\u503C\u9FA8" +
"\u51A3\u408F\u929D\u38F5\uBCB6\uDA21\u10FF\uF3D2" +
"\uCD0C\u13EC\u5F97\u4417\uC4A7\u7E3D\u645D\u1973" +
"\u6081\u4FDC\u222A\u9088\u46EE\uB814\uDE5E\u0BDB" +
"\uE032\u3A0A\u4906\u245C\uC2D3\uAC62\u9195\uE479" +
"\uE7C8\u376D\u8DD5\u4EA9\u6C56\uF4EA\u657A\uAE08" +
"\uBA78\u252E\u1CA6\uB4C6\uE8DD\u741F\u4BBD\u8B8A" +
"\u703E\uB566\u4803\uF60E\u6135\u57B9\u86C1\u1D9E" +
"\uE1F8\u9811\u69D9\u8E94\u9B1E\u87E9\uCE55\u28DF" +
"\u8CA1\u890D\uBFE6\u4268\u4199\u2D0F\uB054\uBB16";
private static final byte[]
Se = new byte[256];
private static final int[]
Te0 = new int[256],
Te1 = new int[256],
Te2 = new int[256],
Te3 = new int[256];
private static final byte[]
Sd = new byte[256];
private static final int[]
Td0 = new int[256],
Td1 = new int[256],
Td2 = new int[256],
Td3 = new int[256];
/**
* Round constants
*/
private static final int[]
rcon = new int[10]; /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
/**
* Number of rounds (depends on key size).
*/
private int Nr = 0;
private int Nk = 0;
private int Nw = 0;
/**
* Encryption key schedule
*/
private int rek[] = null;
/**
* Decryption key schedule
*/
private int rdk[] = null;
static {
/*
Te0[x] = Se[x].[02, 01, 01, 03];
Te1[x] = Se[x].[03, 02, 01, 01];
Te2[x] = Se[x].[01, 03, 02, 01];
Te3[x] = Se[x].[01, 01, 03, 02];
Td0[x] = Sd[x].[0e, 09, 0d, 0b];
Td1[x] = Sd[x].[0b, 0e, 09, 0d];
Td2[x] = Sd[x].[0d, 0b, 0e, 09];
Td3[x] = Sd[x].[09, 0d, 0b, 0e];
*/
int ROOT = 0x11B;
int s1, s2, s3, i1, i2, i4, i8, i9, ib, id, ie, t;
for (i1 = 0; i1 < 256; i1++) {
char c = SS.charAt(i1 >>> 1);
s1 = (byte)((i1 & 1) == 0 ? c >>> 8 : c) & 0xff;
s2 = s1 << 1;
if (s2 >= 0x100) {
s2 ^= ROOT;
}
s3 = s2 ^ s1;
i2 = i1 << 1;
if (i2 >= 0x100) {
i2 ^= ROOT;
}
i4 = i2 << 1;
if (i4 >= 0x100) {
i4 ^= ROOT;
}
i8 = i4 << 1;
if (i8 >= 0x100) {
i8 ^= ROOT;
}
i9 = i8 ^ i1;
ib = i9 ^ i2;
id = i9 ^ i4;
ie = i8 ^ i4 ^ i2;
Se[i1] = (byte)s1;
Te0[i1] = t = (s2 << 24) | (s1 << 16) | (s1 << 8) | s3;
Te1[i1] = (t >>> 8) | (t << 24);
Te2[i1] = (t >>> 16) | (t << 16);
Te3[i1] = (t >>> 24) | (t << 8);
Sd[s1] = (byte)i1;
Td0[s1] = t = (ie << 24) | (i9 << 16) | (id << 8) | ib;
Td1[s1] = (t >>> 8) | (t << 24);
Td2[s1] = (t >>> 16) | (t << 16);
Td3[s1] = (t >>> 24) | (t << 8);
}
/*
* round constants
*/
int r = 1;
rcon[0] = r << 24;
for (int i = 1; i < 10; i++) {
r <<= 1;
if (r >= 0x100) {
r ^= ROOT;
}
rcon[i] = r << 24;
}
}
/**
* Expand a cipher key into a full encryption key schedule.
*
* @param cipherKey the cipher key (128, 192, or 256 bits).
*/
private final void expandKey(byte[] cipherKey) {
int temp, r = 0;
for (int i = 0, k = 0; i < Nk; i++, k += 4) {
rek[i] =
((cipherKey[k ] ) << 24) |
((cipherKey[k + 1] & 0xff) << 16) |
((cipherKey[k + 2] & 0xff) << 8) |
((cipherKey[k + 3] & 0xff));
}
for (int i = Nk, n = 0; i < Nw; i++, n--) {
temp = rek[i - 1];
if (n == 0) {
n = Nk;
temp =
((Se[(temp >>> 16) & 0xff] ) << 24) |
((Se[(temp >>> 8) & 0xff] & 0xff) << 16) |
((Se[(temp ) & 0xff] & 0xff) << 8) |
((Se[(temp >>> 24) ] & 0xff));
temp ^= rcon[r++];
} else if (Nk == 8 && n == 4) {
temp =
((Se[(temp >>> 24) ] ) << 24) |
((Se[(temp >>> 16) & 0xff] & 0xff) << 16) |
((Se[(temp >>> 8) & 0xff] & 0xff) << 8) |
((Se[(temp ) & 0xff] & 0xff));
}
rek[i] = rek[i - Nk] ^ temp;
}
temp = 0;
}
/**
* Compute the decryption schedule from the encryption schedule .
*/
private final void invertKey() {
int d = 0, e = 4*Nr, w;
/*
* apply the inverse MixColumn transform to all round keys
* but the first and the last:
*/
rdk[d ] = rek[e ];
rdk[d + 1] = rek[e + 1];
rdk[d + 2] = rek[e + 2];
rdk[d + 3] = rek[e + 3];
d += 4;
e -= 4;
for (int r = 1; r < Nr; r++) {
w = rek[e ];
rdk[d ] =
Td0[Se[(w >>> 24) ] & 0xff] ^
Td1[Se[(w >>> 16) & 0xff] & 0xff] ^
Td2[Se[(w >>> 8) & 0xff] & 0xff] ^
Td3[Se[(w ) & 0xff] & 0xff];
w = rek[e + 1];
rdk[d + 1] =
Td0[Se[(w >>> 24) ] & 0xff] ^
Td1[Se[(w >>> 16) & 0xff] & 0xff] ^
Td2[Se[(w >>> 8) & 0xff] & 0xff] ^
Td3[Se[(w ) & 0xff] & 0xff];
w = rek[e + 2];
rdk[d + 2] =
Td0[Se[(w >>> 24) ] & 0xff] ^
Td1[Se[(w >>> 16) & 0xff] & 0xff] ^
Td2[Se[(w >>> 8) & 0xff] & 0xff] ^
Td3[Se[(w ) & 0xff] & 0xff];
w = rek[e + 3];
rdk[d + 3] =
Td0[Se[(w >>> 24) ] & 0xff] ^
Td1[Se[(w >>> 16) & 0xff] & 0xff] ^
Td2[Se[(w >>> 8) & 0xff] & 0xff] ^
Td3[Se[(w ) & 0xff] & 0xff];
d += 4;
e -= 4;
}
rdk[d ] = rek[e ];
rdk[d + 1] = rek[e + 1];
rdk[d + 2] = rek[e + 2];
rdk[d + 3] = rek[e + 3];
}
/**
* Setup the AES key schedule for encryption, decryption, or both.
*
* @param cipherKey the cipher key (128, 192, or 256 bits).
* @param keyBits size of the cipher key in bits.
* @param direction cipher direction (DIR_ENCRYPT, DIR_DECRYPT, or DIR_BOTH).
*/
public final void makeKey(byte[] cipherKey, int keySize, int direction)
throws RuntimeException {
// check key size:
switch (keySize) {
case 16:
case 24:
case 32:
keySize <<= 3; // keySize is now in bits
break;
case 128:
case 192:
case 256:
break;
default:
throw new RuntimeException("Invalid AES key size (" + keySize + ")");
}
Nk = keySize >>> 5;
Nr = Nk + 6;
Nw = 4*(Nr + 1);
rek = new int[Nw];
rdk = new int[Nw];
if ((direction & DIR_BOTH) != 0) {
expandKey(cipherKey);
/*
for (int r = 0; r <= Nr; r++) {
System.out.print("RK" + r + "=");
for (int i = 0; i < 4; i++) {
int w = rek[4*r + i];
System.out.print(" " + Integer.toHexString(w));
}
System.out.println();
}
*/
if ((direction & DIR_DECRYPT) != 0) {
invertKey();
}
}
}
/**
* Setup the AES key schedule (any cipher direction).
*
* @param cipherKey the cipher key (128, 192, or 256 bits).
* @param keyBits size of the cipher key in bits.
*/
public final void makeKey(byte[] cipherKey, int keyBits)
throws RuntimeException {
makeKey(cipherKey, keyBits, DIR_BOTH);
}
/**
* Encrypt exactly one block (BLOCK_SIZE bytes) of plaintext.
*
* @param pt plaintext block.
* @param ct ciphertext block.
*/
public final void encrypt(byte[] pt, byte[] ct) {
/*
* map byte array block to cipher state
* and add initial round key:
*/
int k = 0, v;
int t0 = ((pt[ 0] ) << 24 |
(pt[ 1] & 0xff) << 16 |
(pt[ 2] & 0xff) << 8 |
(pt[ 3] & 0xff) ) ^ rek[0];
int t1 = ((pt[ 4] ) << 24 |
(pt[ 5] & 0xff) << 16 |
(pt[ 6] & 0xff) << 8 |
(pt[ 7] & 0xff) ) ^ rek[1];
int t2 = ((pt[ 8] ) << 24 |
(pt[ 9] & 0xff) << 16 |
(pt[10] & 0xff) << 8 |
(pt[11] & 0xff) ) ^ rek[2];
int t3 = ((pt[12] ) << 24 |
(pt[13] & 0xff) << 16 |
(pt[14] & 0xff) << 8 |
(pt[15] & 0xff) ) ^ rek[3];
/*
* Nr - 1 full rounds:
*/
for (int r = 1; r < Nr; r++) {
k += 4;
int a0 =
Te0[(t0 >>> 24) ] ^
Te1[(t1 >>> 16) & 0xff] ^
Te2[(t2 >>> 8) & 0xff] ^
Te3[(t3 ) & 0xff] ^
rek[k ];
int a1 =
Te0[(t1 >>> 24) ] ^
Te1[(t2 >>> 16) & 0xff] ^
Te2[(t3 >>> 8) & 0xff] ^
Te3[(t0 ) & 0xff] ^
rek[k + 1];
int a2 =
Te0[(t2 >>> 24) ] ^
Te1[(t3 >>> 16) & 0xff] ^
Te2[(t0 >>> 8) & 0xff] ^
Te3[(t1 ) & 0xff] ^
rek[k + 2];
int a3 =
Te0[(t3 >>> 24) ] ^
Te1[(t0 >>> 16) & 0xff] ^
Te2[(t1 >>> 8) & 0xff] ^
Te3[(t2 ) & 0xff] ^
rek[k + 3];
t0 = a0; t1 = a1; t2 = a2; t3 = a3;
}
/*
* last round lacks MixColumn:
*/
k += 4;
v = rek[k ];
ct[ 0] = (byte)(Se[(t0 >>> 24) ] ^ (v >>> 24));
ct[ 1] = (byte)(Se[(t1 >>> 16) & 0xff] ^ (v >>> 16));
ct[ 2] = (byte)(Se[(t2 >>> 8) & 0xff] ^ (v >>> 8));
ct[ 3] = (byte)(Se[(t3 ) & 0xff] ^ (v ));
v = rek[k + 1];
ct[ 4] = (byte)(Se[(t1 >>> 24) ] ^ (v >>> 24));
ct[ 5] = (byte)(Se[(t2 >>> 16) & 0xff] ^ (v >>> 16));
ct[ 6] = (byte)(Se[(t3 >>> 8) & 0xff] ^ (v >>> 8));
ct[ 7] = (byte)(Se[(t0 ) & 0xff] ^ (v ));
v = rek[k + 2];
ct[ 8] = (byte)(Se[(t2 >>> 24) ] ^ (v >>> 24));
ct[ 9] = (byte)(Se[(t3 >>> 16) & 0xff] ^ (v >>> 16));
ct[10] = (byte)(Se[(t0 >>> 8) & 0xff] ^ (v >>> 8));
ct[11] = (byte)(Se[(t1 ) & 0xff] ^ (v ));
v = rek[k + 3];
ct[12] = (byte)(Se[(t3 >>> 24) ] ^ (v >>> 24));
ct[13] = (byte)(Se[(t0 >>> 16) & 0xff] ^ (v >>> 16));
ct[14] = (byte)(Se[(t1 >>> 8) & 0xff] ^ (v >>> 8));
ct[15] = (byte)(Se[(t2 ) & 0xff] ^ (v ));
}
/**
* Decrypt exactly one block (BLOCK_SIZE bytes) of ciphertext.
*
* @param ct ciphertext block.
* @param pt plaintext block.
*/
public final void decrypt(byte[] ct, byte[] pt) {
/*
* map byte array block to cipher state
* and add initial round key:
*/
int k = 0, v;
int t0 = ((ct[ 0] ) << 24 |
(ct[ 1] & 0xff) << 16 |
(ct[ 2] & 0xff) << 8 |
(ct[ 3] & 0xff) ) ^ rdk[0];
int t1 = ((ct[ 4] ) << 24 |
(ct[ 5] & 0xff) << 16 |
(ct[ 6] & 0xff) << 8 |
(ct[ 7] & 0xff) ) ^ rdk[1];
int t2 = ((ct[ 8] ) << 24 |
(ct[ 9] & 0xff) << 16 |
(ct[10] & 0xff) << 8 |
(ct[11] & 0xff) ) ^ rdk[2];
int t3 = ((ct[12] ) << 24 |
(ct[13] & 0xff) << 16 |
(ct[14] & 0xff) << 8 |
(ct[15] & 0xff) ) ^ rdk[3];
/*
* Nr - 1 full rounds:
*/
for (int r = 1; r < Nr; r++) {
k += 4;
int a0 =
Td0[(t0 >>> 24) ] ^
Td1[(t3 >>> 16) & 0xff] ^
Td2[(t2 >>> 8) & 0xff] ^
Td3[(t1 ) & 0xff] ^
rdk[k ];
int a1 =
Td0[(t1 >>> 24) ] ^
Td1[(t0 >>> 16) & 0xff] ^
Td2[(t3 >>> 8) & 0xff] ^
Td3[(t2 ) & 0xff] ^
rdk[k + 1];
int a2 =
Td0[(t2 >>> 24) ] ^
Td1[(t1 >>> 16) & 0xff] ^
Td2[(t0 >>> 8) & 0xff] ^
Td3[(t3 ) & 0xff] ^
rdk[k + 2];
int a3 =
Td0[(t3 >>> 24) ] ^
Td1[(t2 >>> 16) & 0xff] ^
Td2[(t1 >>> 8) & 0xff] ^
Td3[(t0 ) & 0xff] ^
rdk[k + 3];
t0 = a0; t1 = a1; t2 = a2; t3 = a3;
}
/*
* last round lacks MixColumn:
*/
k += 4;
v = rdk[k ];
pt[ 0] = (byte)(Sd[(t0 >>> 24) ] ^ (v >>> 24));
pt[ 1] = (byte)(Sd[(t3 >>> 16) & 0xff] ^ (v >>> 16));
pt[ 2] = (byte)(Sd[(t2 >>> 8) & 0xff] ^ (v >>> 8));
pt[ 3] = (byte)(Sd[(t1 ) & 0xff] ^ (v ));
v = rdk[k + 1];
pt[ 4] = (byte)(Sd[(t1 >>> 24) ] ^ (v >>> 24));
pt[ 5] = (byte)(Sd[(t0 >>> 16) & 0xff] ^ (v >>> 16));
pt[ 6] = (byte)(Sd[(t3 >>> 8) & 0xff] ^ (v >>> 8));
pt[ 7] = (byte)(Sd[(t2 ) & 0xff] ^ (v ));
v = rdk[k + 2];
pt[ 8] = (byte)(Sd[(t2 >>> 24) ] ^ (v >>> 24));
pt[ 9] = (byte)(Sd[(t1 >>> 16) & 0xff] ^ (v >>> 16));
pt[10] = (byte)(Sd[(t0 >>> 8) & 0xff] ^ (v >>> 8));
pt[11] = (byte)(Sd[(t3 ) & 0xff] ^ (v ));
v = rdk[k + 3];
pt[12] = (byte)(Sd[(t3 >>> 24) ] ^ (v >>> 24));
pt[13] = (byte)(Sd[(t2 >>> 16) & 0xff] ^ (v >>> 16));
pt[14] = (byte)(Sd[(t1 >>> 8) & 0xff] ^ (v >>> 8));
pt[15] = (byte)(Sd[(t0 ) & 0xff] ^ (v ));
}
/**
* Destroy all sensitive information in this object.
*/
public final void finalize() {
if (rek != null) {
for (int i = 0; i < rek.length; i++) {
rek[i] = 0;
}
rek = null;
}
if (rdk != null) {
for (int i = 0; i < rdk.length; i++) {
rdk[i] = 0;
}
rdk = null;
}
}
}
/*
@GROUP
Crypto
@SYNTAX
answer = AES ("encrypt", plain, key)
answer = AES ("e", plain, key)
answer = AES ("decrypt", cipher, key)
answer = AES ("d", cipher, key)
@DOC
does encryption and descrption using the AES (advanced encryption standard) algorithm
@EXAMPLES
<programlisting>
> k=str2num("0987098709870987")
k=[48,57,56,55,48,57,56,55,48,57,56,55,48,57,56,55]
> a=str2num("asdfasdfasdfasdf")
a=[97,115,100,102,97,115,100,102,97,115,100,102,97,115,100,102]
> b=aes("e",a,k)
b=[-103,34,84,18,-46,-58,35,89,80,17,81,118,-4,-15,-93,-31]
> c=aes("d",b,k)
c=[97,115,100,102,97,115,100,102,97,115,100,102,97,115,100,102]
> num2str(c)
ans = asdfasdfasdfasdf
</programlisting>
@NOTES
@SEE
*/