--- /dev/null
+\r
+package estreamj.ciphers.trivium;\r
+\r
+import estreamj.framework.*;\r
+\r
+public class Trivium implements ICipher \r
+{\r
+ final static int KEY_SIZE_BITS = 80;\r
+ final static int IV_SIZE_BITS = 80;\r
+ \r
+ ///////////////////////////////////////////////////////////////////////////\r
+ \r
+ byte[] key = new byte[10];\r
+ int[] s = new int[10];\r
+ \r
+ ///////////////////////////////////////////////////////////////////////////\r
+ \r
+ public int getKeySize() \r
+ {\r
+ return KEY_SIZE_BITS >> 3;\r
+ }\r
+\r
+ public int getNonceSize() \r
+ {\r
+ return IV_SIZE_BITS >> 3;\r
+ }\r
+\r
+ public int getWordSize() \r
+ {\r
+ return 4;\r
+ }\r
+\r
+ public boolean isPatented() \r
+ {\r
+ return false;\r
+ }\r
+\r
+ public void process(\r
+ byte[] inbuf, \r
+ int inOfs, \r
+ byte[] outbuf, \r
+ int outOfs, \r
+ int len) throws ESJException \r
+ {\r
+ int s11 = s[0];\r
+ int s12 = s[1];\r
+ int s13 = s[2];\r
+ int s21 = s[3];\r
+ int s22 = s[4];\r
+ int s23 = s[5];\r
+ int s31 = s[6];\r
+ int s32 = s[7];\r
+ int s33 = s[8];\r
+ int s34 = s[9];\r
+ \r
+ int outEnd = outOfs + (len & ~3); \r
+ \r
+ for (; outOfs < outEnd; outOfs+=4, inOfs+=4)\r
+ {\r
+ int t1, t2, t3, reg;\r
+ \r
+ t1 = ((s13 << 96-66) | (s12 >>> 66-64)) ^ ((s13 << 96-93 ) | (s12 >>> 93-64)); \r
+ t2 = ((s23 << 96-69) | (s22 >>> 69-64)) ^ ((s23 << 96-84 ) | (s22 >>> 84-64)); \r
+ t3 = ((s33 << 96-66) | (s32 >>> 66-64)) ^ ((s34 << 128-111) | (s33 >>> 111-96));\r
+ \r
+ reg = t1 ^ t2 ^ t3;\r
+ outbuf[outOfs ] = (byte)(inbuf[inOfs ] ^ reg); \r
+ outbuf[outOfs + 1] = (byte)(inbuf[inOfs + 1] ^ reg >> 8); \r
+ outbuf[outOfs + 2] = (byte)(inbuf[inOfs + 2] ^ reg >> 16); \r
+ outbuf[outOfs + 3] = (byte)(inbuf[inOfs + 3] ^ reg >> 24); \r
+\r
+ t1 ^= (((s13 << 96-91 ) | (s12 >>> 91-64)) & ((s13 << 96-92 ) | (s12 >>> 92-64))) ^ ((s23 << 96-78) | (s22 >>> 78-64)); \r
+ t2 ^= (((s23 << 96-82 ) | (s22 >>> 82-64)) & ((s23 << 96-83 ) | (s22 >>> 83-64))) ^ ((s33 << 96-87) | (s32 >>> 87-64)); \r
+ t3 ^= (((s34 << 128-109) | (s33 >>> 109-96)) & ((s34 << 128-110) | (s33 >>> 110-96))) ^ ((s13 << 96-69) | (s12 >>> 69-64)); \r
+ \r
+ s13 = s12; s12 = s11; s11 = t3; \r
+ s23 = s22; s22 = s21; s21 = t1; \r
+ s34 = s33; s33 = s32; s32 = s31; s31 = t2; \r
+ }\r
+ \r
+ // NOTE: could save some code memory by merging the two blocks, but that\r
+ // would decrease the speed because of additional conditional jumps...\r
+ outEnd = outOfs + (len & 3);\r
+ if (0 < outEnd)\r
+ {\r
+ int t1, t2, t3, reg;\r
+ \r
+ t1 = ((s13 << 96-66) | (s12 >>> 66-64)) ^ ((s13 << 96-93 ) | (s12 >>> 93-64)); \r
+ t2 = ((s23 << 96-69) | (s22 >>> 69-64)) ^ ((s23 << 96-84 ) | (s22 >>> 84-64)); \r
+ t3 = ((s33 << 96-66) | (s32 >>> 66-64)) ^ ((s34 << 128-111) | (s33 >>> 111-96));\r
+ \r
+ reg = t1 ^ t2 ^ t3;\r
+ for (;outOfs < outEnd; outOfs++, inOfs++)\r
+ {\r
+ outbuf[outOfs] = (byte)(inbuf[inOfs] ^ reg);\r
+ reg >>= 8;\r
+ }\r
+\r
+ t1 ^= (((s13 << 96-91 ) | (s12 >>> 91-64)) & ((s13 << 96-92 ) | (s12 >>> 92-64))) ^ ((s23 << 96-78) | (s22 >>> 78-64)); \r
+ t2 ^= (((s23 << 96-82 ) | (s22 >>> 82-64)) & ((s23 << 96-83 ) | (s22 >>> 83-64))) ^ ((s33 << 96-87) | (s32 >>> 87-64)); \r
+ t3 ^= (((s34 << 128-109) | (s33 >>> 109-96)) & ((s34 << 128-110) | (s33 >>> 110-96))) ^ ((s13 << 96-69) | (s12 >>> 69-64)); \r
+ \r
+ s13 = s12; s12 = s11; s11 = t3; \r
+ s23 = s22; s22 = s21; s21 = t1; \r
+ s34 = s33; s33 = s32; s32 = s31; s31 = t2; \r
+ }\r
+ \r
+ s[0] = s11;\r
+ s[1] = s12;\r
+ s[2] = s13;\r
+ s[3] = s21;\r
+ s[4] = s22;\r
+ s[5] = s23;\r
+ s[6] = s31;\r
+ s[7] = s32;\r
+ s[8] = s33;\r
+ s[9] = s34;\r
+ }\r
+\r
+ public void reset() throws ESJException \r
+ {\r
+ // key is cached already, nothing to do here\r
+ }\r
+\r
+ public void setupKey(\r
+ int mode, \r
+ byte[] key, \r
+ int ofs) throws ESJException \r
+ {\r
+ System.arraycopy(key, ofs, this.key, 0, this.key.length);\r
+ }\r
+\r
+ public void setupNonce(\r
+ byte[] nonce, \r
+ int ofs) throws ESJException \r
+ {\r
+ byte[] key = this.key;\r
+ int[] s = this.s;\r
+ \r
+ int s11 = Utils.readInt32LE(key, 0);\r
+ int s12 = Utils.readInt32LE(key, 4);\r
+ int s13 = ( key[8] & 0x0ff) | \r
+ ((key[9] << 8) & 0x0ff00); \r
+ int s21 = Utils.readInt32LE(nonce, ofs);\r
+ int s22 = Utils.readInt32LE(nonce, ofs + 4);\r
+ int s23 = ( nonce[ofs + 8] & 0x0ff) | \r
+ ((nonce[ofs + 9] << 8) & 0x0ff00); \r
+ int s31 = 0;\r
+ int s32 = 0;\r
+ int s33 = 0;\r
+ int s34 = 0x07000;\r
+ \r
+\r
+ ///////////////!!!!!!!!!!!!!!!!!!!!!!!!\r
+// System.out.printf(\r
+// "s11=%08x\n" +\r
+// "s12=%08x\n" +\r
+// "s13=%08x\n" +\r
+// "s21=%08x\n" +\r
+// "s22=%08x\n" +\r
+// "s23=%08x\n" +\r
+// "s31=%08x\n" +\r
+// "s32=%08x\n" +\r
+// "s33=%08x\n" +\r
+// "s34=%08x\n",\r
+// s11, s12, s13,\r
+// s21, s22, s23,\r
+// s31, s32, s33, s34); \r
+ \r
+ \r
+ for (int i = 0; i < 4*9; i++)\r
+ {\r
+ int t1, t2, t3;\r
+ \r
+ t1 = ((s13 << 96-66) | (s12 >>> 66-64)) ^ ((s13 << 96-93 ) | (s12 >>> 93-64)); \r
+ t2 = ((s23 << 96-69) | (s22 >>> 69-64)) ^ ((s23 << 96-84 ) | (s22 >>> 84-64)); \r
+ t3 = ((s33 << 96-66) | (s32 >>> 66-64)) ^ ((s34 << 128-111) | (s33 >>> 111-96)); \r
+\r
+ t1 ^= (((s13 << 96-91 ) | (s12 >>> 91-64)) & ((s13 << 96-92 ) | (s12 >>> 92-64))) ^ ((s23 << 96-78) | (s22 >>> 78-64)); \r
+ t2 ^= (((s23 << 96-82 ) | (s22 >>> 82-64)) & ((s23 << 96-83 ) | (s22 >>> 83-64))) ^ ((s33 << 96-87) | (s32 >>> 87-64)); \r
+ t3 ^= (((s34 << 128-109) | (s33 >>> 109-96)) & ((s34 << 128-110) | (s33 >>> 110-96))) ^ ((s13 << 96-69) | (s12 >>> 69-64)); \r
+ \r
+ s13 = s12; s12 = s11; s11 = t3; \r
+ s23 = s22; s22 = s21; s21 = t1; \r
+ s34 = s33; s33 = s32; s32 = s31; s31 = t2; \r
+ }\r
+ \r
+ s[0] = s11;\r
+ s[1] = s12;\r
+ s[2] = s13;\r
+ s[3] = s21;\r
+ s[4] = s22;\r
+ s[5] = s23;\r
+ s[6] = s31;\r
+ s[7] = s32;\r
+ s[8] = s33;\r
+ s[9] = s34;\r
+ }\r
+ \r
+ ///////////////////////////////////////////////////////////////////////////\r
+ \r
+ static class Maker implements ICipherMaker\r
+ {\r
+ public ICipher create() throws ESJException \r
+ {\r
+ return new Trivium();\r
+ }\r
+\r
+ public String getName() \r
+ {\r
+ return "Trivium";\r
+ }\r
+ }\r
+ \r
+ public static void register()\r
+ {\r
+ Engine.registerCipher(new Maker());\r
+ }\r
+}
\ No newline at end of file
--- /dev/null
+\r
+package estreamj.framework;\r
+\r
+public class ESJException extends Exception \r
+{\r
+ private static final long serialVersionUID = 6375271013846829471L;\r
+\r
+ public ESJException() {\r
+ super();\r
+ }\r
+\r
+ public ESJException(String message) {\r
+ super(message);\r
+ }\r
+\r
+ public ESJException(Throwable cause) {\r
+ super(cause);\r
+ }\r
+\r
+ public ESJException(String message, Throwable cause) {\r
+ super(message, cause);\r
+ }\r
+}\r
--- /dev/null
+\r
+package estreamj.framework;\r
+\r
+import java.util.*;\r
+import java.lang.reflect.*;\r
+\r
+/**\r
+ * The engine accumulates all the stream ciphers available. All implementations\r
+ * register with the engine by themselves.\r
+ */\r
+public class Engine \r
+{\r
+ /**\r
+ * @return the names of all ciphers registered; can be empty if no ciphers\r
+ * have been registered so far\r
+ */\r
+ public static String[] getCipherNames()\r
+ {\r
+ String[] result;\r
+ \r
+ synchronized(_cphMks)\r
+ {\r
+ Vector<String> lst = new Vector<String>();\r
+ lst.addAll(_cphMks.keySet());\r
+ Collections.sort(lst);\r
+ result = lst.toArray(new String[lst.size()]);\r
+ }\r
+ \r
+ return result;\r
+ }\r
+ \r
+ /**\r
+ * Creates a new cipher instance.\r
+ * @param name name of the cipher to make\r
+ * @return new cipher instance\r
+ * @throws ESJException if any error occured\r
+ */\r
+ public static ICipher createCipher(String name) throws ESJException\r
+ {\r
+ ICipherMaker maker;\r
+ \r
+ synchronized(_cphMks)\r
+ {\r
+ maker = _cphMks.get(name);\r
+ if (null == maker)\r
+ {\r
+ throw new ESJException("no maker registered for cipher \"" + \r
+ name + "\"");\r
+ }\r
+ }\r
+ return maker.create();\r
+ }\r
+ \r
+ ///////////////////////////////////////////////////////////////////////////\r
+\r
+ static HashMap<String, ICipherMaker> _cphMks = \r
+ new HashMap<String, ICipherMaker>();\r
+\r
+ /**\r
+ * Called by cipher implementations to register their factories, usually\r
+ * during startup time.\r
+ * @param cphMk the factory to register\r
+ */\r
+ public static void registerCipher(ICipherMaker cphMk)\r
+ {\r
+ String name = cphMk.getName();\r
+ \r
+ synchronized(_cphMks)\r
+ {\r
+ if (_cphMks.containsKey(name))\r
+ {\r
+ System.err.println("cipher \"" + name +\r
+ "\" has been registered already");\r
+ System.exit(1);\r
+ }\r
+ _cphMks.put(cphMk.getName(), cphMk);\r
+ }\r
+ }\r
+\r
+ ///////////////////////////////////////////////////////////////////////////\r
+ \r
+ // all the cipher classes must be listed here, the rest of the registration\r
+ // is done via reflection; this is done by having every class implementing\r
+ // a 'public static void register()' method (see below)\r
+ static Class[] _cipherClasses =\r
+ {\r
+ //estreamj.ciphers.phelix.Phelix.class,\r
+ //estreamj.ciphers.hc256.HC256.class,\r
+ //estreamj.ciphers.salsa20.Salsa20.class,\r
+ //estreamj.ciphers.aes.AESCTR.class,\r
+ //estreamj.ciphers.mickey.MICKEY.class,\r
+ //estreamj.ciphers.mickey.MICKEY128.class,\r
+ //estreamj.ciphers.hermes8.Hermes8.class,\r
+ //estreamj.ciphers.rc4.RC4.class,\r
+ //estreamj.ciphers.dragon.Dragon.class,\r
+ //estreamj.ciphers.lex.LEX.class,\r
+ estreamj.ciphers.trivium.Trivium.class//,\r
+ //estreamj.ciphers.sosemanuk.Sosemanuk.class,\r
+ //estreamj.ciphers.grain.GrainP2.class,\r
+ //estreamj.ciphers.grain.Grain128.class,\r
+ //estreamj.ciphers.nil.Nil.class\r
+ };\r
+\r
+ ///////////////////////////////////////////////////////////////////////////\r
+ \r
+ static\r
+ {\r
+ try\r
+ {\r
+ for (int i = 0; i < _cipherClasses.length; i++)\r
+ {\r
+ // check if the register method is there and static\r
+ Class cls = _cipherClasses[i];\r
+ Method mthd = cls.getMethod("register", (Class[])null);\r
+ if (Modifier.STATIC != (mthd.getModifiers() & Modifier.STATIC))\r
+ {\r
+ throw new Exception(\r
+ "register() method is not static (" + cls + ")");\r
+ }\r
+ // ready to register\r
+ mthd.invoke(null, (Object[])null);\r
+ }\r
+ }\r
+ catch (Exception e)\r
+ {\r
+ System.err.println(\r
+ "cipher registration error (" + e.getMessage() + ")");\r
+ System.exit(1);\r
+ }\r
+ }\r
+}\r
--- /dev/null
+\r
+package estreamj.framework;\r
+\r
+/**\r
+ * Generic interface every cipher needs to implement, so it can participate in\r
+ * the test framework. If a cipher comes in different flavors (variable key\r
+ * sizes, MAC computation or not, etc.) it should then implement a version for\r
+ * each of them - this keeps the actual testing logic simple. Simple is good.\r
+ */\r
+public interface ICipher \r
+{\r
+ /**\r
+ * mode: instance is used for encryption\r
+ */\r
+ public final static int MODE_ENCRYPT = 0;\r
+\r
+ /**\r
+ * mode: instance is used for decryption\r
+ */\r
+ public final static int MODE_DECRYPT = 1;\r
+ \r
+ ///////////////////////////////////////////////////////////////////////////\r
+ \r
+ /**\r
+ * @return true: algorithm is patented, check with vendor for license\r
+ * details / false: free to use in private and commerical applications \r
+ */\r
+ public boolean isPatented();\r
+ \r
+ /**\r
+ * @return key size in bytes\r
+ */\r
+ public int getKeySize();\r
+ \r
+ /**\r
+ * @return nonce size in bytes.\r
+ */\r
+ public int getNonceSize();\r
+ \r
+ /**\r
+ * @return alignment of data needed during calls into process() \r
+ */\r
+ public int getWordSize();\r
+\r
+ ///////////////////////////////////////////////////////////////////////////\r
+\r
+ /**\r
+ * Resets the instance, so it can be reused.\r
+ * @exception ESJException if any error occurs\r
+ */\r
+ public void reset() throws ESJException;\r
+ \r
+ /**\r
+ * Sets up a new key with the existing instance. \r
+ * @param mode see MODE_xxx\r
+ * @param key buffer with key material\r
+ * @param ofs where the key starts \r
+ * @exception ESJException if any error occurs\r
+ */\r
+ public void setupKey(int mode, byte[] key, int ofs) \r
+ throws ESJException;\r
+ \r
+ /**\r
+ * Sets up a new nonce with the existing cipher instance. \r
+ * @param mode see MODE_xxx\r
+ * @param nonce buffer with nonce material\r
+ * @param ofs where the nonce starts\r
+ * @exception ESJException if any error occurs\r
+ */\r
+ public void setupNonce(byte[] nonce, int ofs) \r
+ throws ESJException;\r
+ \r
+ ///////////////////////////////////////////////////////////////////////////\r
+ \r
+ /**\r
+ * Processes data.\r
+ * @param inbuf input buffer\r
+ * @param inOfs where to start reading from the input buffer\r
+ * @param outbuf output buffer\r
+ * @param outOfs where to start writing in the output buffer\r
+ * @param len number of bytes to process, must be aligned to the cipher's\r
+ * word size except on the last call where an arbitrary size can be used\r
+ * @throws ESJException in any error occured\r
+ */\r
+ public void process(\r
+ byte[] inbuf, \r
+ int inOfs, \r
+ byte[] outbuf, \r
+ int outOfs, \r
+ int len) throws ESJException;\r
+}\r
--- /dev/null
+\r
+package estreamj.framework;\r
+\r
+/**\r
+ * Simple cipher factory.\r
+ */\r
+public interface ICipherMaker \r
+{\r
+ /**\r
+ * @return the name of cipher, which is used for queries - so it must be\r
+ * unique\r
+ */\r
+ public String getName();\r
+ \r
+ /**\r
+ * Create a new cipher instance.\r
+ * @return new instance, which can also be of the type ICipherMAC, use the\r
+ * "instanceof" keyword to find out what you are dealing with \r
+ * @throws ESJException if any error occured\r
+ */\r
+ public ICipher create() throws ESJException;\r
+}\r
--- /dev/null
+\r
+package estreamj.framework;\r
+\r
+import java.io.*;\r
+import java.util.Arrays;\r
+\r
+public class Utils \r
+{\r
+ public static void fillPattern123(byte[] buf, int ofs, int len)\r
+ {\r
+ int counter, end;\r
+ \r
+ counter = 0;\r
+ end = ofs + len;\r
+ while (ofs < end)\r
+ {\r
+ buf[ofs++] = (byte)counter++;\r
+ }\r
+ }\r
+\r
+ public static boolean checkPattern123(byte[] buf, int ofs, int len)\r
+ {\r
+ int counter, end;\r
+ \r
+ counter = 0;\r
+ end = ofs + len;\r
+ while (ofs < end)\r
+ {\r
+ if (buf[ofs] != (byte)counter)\r
+ {\r
+ return false;\r
+ }\r
+ counter++;\r
+ ofs++;\r
+ }\r
+ return true;\r
+ }\r
+ \r
+ public static byte[] makeOutputBuffer(int len, int extraLen)\r
+ {\r
+ byte[] result = new byte[len + extraLen];\r
+ Arrays.fill(result, (byte)0xcc);\r
+ return result;\r
+ }\r
+ \r
+ public static boolean arraysEquals(\r
+ byte[] a, int ofsA, byte[] b, int ofsB, int len)\r
+ {\r
+ int end = ofsA + len;\r
+ while (ofsA < end)\r
+ {\r
+ if (b[ofsB++] != a[ofsA++])\r
+ {\r
+ return false;\r
+ }\r
+ }\r
+ return true;\r
+ }\r
+ \r
+ public final static int readInt32LE(byte[] data, int ofs)\r
+ {\r
+ return ( data[ofs + 3] << 24) |\r
+ ((data[ofs + 2] & 0xff) << 16) |\r
+ ((data[ofs + 1] & 0xff) << 8) |\r
+ (data[ofs ] & 0xff);\r
+ }\r
+ \r
+ public final static void writeInt32LE(int value, byte[] data, int ofs)\r
+ {\r
+ data[ofs ] = (byte)(value );\r
+ data[ofs + 1] = (byte)(value >>> 8);\r
+ data[ofs + 2] = (byte)(value >>> 16);\r
+ data[ofs + 3] = (byte)(value >>> 24);\r
+ }\r
+\r
+ public final static int readInt32BE(byte[] data, int ofs)\r
+ {\r
+ return ( data[ofs ] << 24) |\r
+ ((data[ofs + 1] & 0xff) << 16) |\r
+ ((data[ofs + 2] & 0xff) << 8) |\r
+ (data[ofs + 3] & 0xff);\r
+ }\r
+ \r
+ public final static void writeInt32BE(int value, byte[] data, int ofs)\r
+ {\r
+ data[ofs + 3] = (byte)(value );\r
+ data[ofs + 2] = (byte)(value >>> 8);\r
+ data[ofs + 1] = (byte)(value >>> 16);\r
+ data[ofs ] = (byte)(value >>> 24);\r
+ }\r
+ \r
+ public static byte[] hexStrToBytes(String hex)\r
+ {\r
+ int len = hex.length();\r
+ if (1 == (len & 1))\r
+ {\r
+ return null;\r
+ }\r
+ byte[] result = new byte[len >> 1];\r
+ int r = 0;\r
+ int pos = 0;\r
+ while (pos < len)\r
+ {\r
+ int nReg = 0;\r
+ for (int nI = 0; nI < 2; nI++)\r
+ {\r
+ nReg <<= 4;\r
+ char c = Character.toLowerCase(hex.charAt(pos++));\r
+ if ('0' <= c && '9' >= c)\r
+ {\r
+ nReg |= c - '0';\r
+ }\r
+ else if ('a' <= c && 'f' >= c)\r
+ {\r
+ nReg |= (c - 'a') + 10;\r
+ }\r
+ else\r
+ {\r
+ return null;\r
+ }\r
+ }\r
+ result[r++] = (byte)nReg;\r
+ }\r
+ return result;\r
+ }\r
+ \r
+ final static char[] HEXTAB =\r
+ {\r
+ '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'\r
+ };\r
+\r
+ public static int hexDump(\r
+ InputStream is,\r
+ PrintStream ps,\r
+ int maxRead,\r
+ int bytesPerLine)\r
+ {\r
+ int read, chr, i, result;\r
+ char[] pad;\r
+ StringBuffer left, right;\r
+ \r
+ \r
+ if (1 > bytesPerLine)\r
+ {\r
+ bytesPerLine = 1;\r
+ }\r
+ \r
+ left = new StringBuffer();\r
+ right = new StringBuffer();\r
+ \r
+ result = 0;\r
+ \r
+ for (read = 0, i = 0;;)\r
+ {\r
+ if (-1 != maxRead)\r
+ {\r
+ if (maxRead <= read)\r
+ {\r
+ break;\r
+ }\r
+ }\r
+ \r
+ try\r
+ {\r
+ if (-1 == (chr = is.read()))\r
+ {\r
+ break; \r
+ }\r
+ }\r
+ catch (IOException ioe)\r
+ {\r
+ break;\r
+ }\r
+ \r
+ result++;\r
+\r
+ if (0 < i++)\r
+ {\r
+ left.append(' ');\r
+ }\r
+\r
+ left.append(HEXTAB[chr >>> 4]);\r
+ left.append(HEXTAB[chr & 0x0f]);\r
+\r
+ right.append((chr < ' ') ? '.' : (char)chr);\r
+ \r
+ if (0 == (i % bytesPerLine))\r
+ {\r
+ ps.print(left.toString());\r
+ ps.print(" ");\r
+ ps.println(right.toString());\r
+ \r
+ left.setLength(0);\r
+ right.setLength(0);\r
+ \r
+ i = 0;\r
+ }\r
+ }\r
+\r
+ if (0 < i)\r
+ {\r
+ pad = new char[((bytesPerLine - i) * 3) + 4];\r
+ Arrays.fill(pad, ' '); \r
+ \r
+ ps.print(left.toString());\r
+ ps.print(pad);\r
+ ps.println(right.toString());\r
+ }\r
+ \r
+ return result;\r
+ }\r
+ \r
+ public static byte[] swapByteOrder32(byte[] data, int ofs, int len)\r
+ {\r
+ int end = ofs + len;\r
+ byte tmp;\r
+ \r
+ for (; ofs < end; ofs += 4)\r
+ {\r
+ tmp = data[ofs];\r
+ data[ofs] = data[ofs + 3];\r
+ data[ofs + 3] = tmp;\r
+\r
+ tmp = data[ofs + 1];\r
+ data[ofs + 1] = data[ofs + 2];\r
+ data[ofs + 2] = tmp;\r
+ }\r
+ return data;\r
+ }\r
+}\r