001: // CryptoUtils - some cryptography utilities
002: //
003: // Copyright (C) 1996 by Jef Poskanzer <jef@acme.com>. All rights reserved.
004: //
005: // Redistribution and use in source and binary forms, with or without
006: // modification, are permitted provided that the following conditions
007: // are met:
008: // 1. Redistributions of source code must retain the above copyright
009: // notice, this list of conditions and the following disclaimer.
010: // 2. Redistributions in binary form must reproduce the above copyright
011: // notice, this list of conditions and the following disclaimer in the
012: // documentation and/or other materials provided with the distribution.
013: //
014: // THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
015: // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
016: // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
017: // ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
018: // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
019: // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
020: // OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
021: // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
022: // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
023: // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
024: // SUCH DAMAGE.
025: //
026: // Visit the ACME Labs Java page for up-to-date versions of this and other
027: // fine Java utilities: http://www.acme.com/java/
028:
029: package Acme.Crypto;
030:
031: import java.io.*;
032:
033: /// Some cryptography utilities.
034: // <P>
035: // These are static methods used by a lot of the cryptography classes.
036: // Most of them operate on byte arrays, which we call blocks.
037: // They could be encapsulated in a "Block" class, but that would
038: // mean a big efficiency hit - method calls are a lot more
039: // expensive than array accesses.
040: // <P>
041: // <A HREF="/resources/classes/Acme/Crypto/CryptoUtils.java">Fetch the software.</A><BR>
042: // <A HREF="/resources/classes/Acme.tar.gz">Fetch the entire Acme package.</A>
043:
044: public class CryptoUtils {
045:
046: /// Utility routine to fill a block with zeros.
047: public static void zeroBlock(byte[] block, int off, int len) {
048: for (int i = off; i < off + len; ++i)
049: block[i] = 0;
050: }
051:
052: /// Utility routine to fill a block with zeros.
053: public static void zeroBlock(byte[] block) {
054: zeroBlock(block, 0, block.length);
055: }
056:
057: /// Utility routine to fill a block with random bytes.
058: public static void randomBlock(byte[] block, int off, int len) {
059: for (int i = off; i < off + len; ++i)
060: block[i] = (byte) (Math.random() * 256.0);
061: }
062:
063: /// Utility routine to fill a block with random bytes.
064: public static void randomBlock(byte[] block) {
065: randomBlock(block, 0, block.length);
066: }
067:
068: /// Utility routine to XOR two blocks.
069: public static void xorBlock(byte[] a, int aOff, byte[] b, int bOff,
070: byte[] dst, int dstOff, int len) {
071: for (int i = 0; i < len; ++i)
072: dst[dstOff + i] = (byte) (a[aOff + i] ^ b[bOff + i]);
073: }
074:
075: /// Utility routine to XOR two blocks.
076: public static void xorBlock(byte[] a, byte[] b, byte[] dst) {
077: xorBlock(a, 0, b, 0, dst, 0, a.length);
078: }
079:
080: /// Utility routine to copy one block to another.
081: public static void copyBlock(byte[] src, int srcOff, byte[] dst,
082: int dstOff, int len) {
083: for (int i = 0; i < len; ++i)
084: dst[dstOff + i] = src[srcOff + i];
085: }
086:
087: /// Utility routine to copy one block to another.
088: public static void copyBlock(byte[] src, byte[] dst) {
089: copyBlock(src, 0, dst, 0, src.length);
090: }
091:
092: /// Utility routine to check two blocks for equality.
093: public static boolean equalsBlock(byte[] a, int aOff, byte[] b,
094: int bOff, int len) {
095: for (int i = 0; i < len; ++i)
096: if (a[aOff + i] != b[bOff + i])
097: return false;
098: return true;
099: }
100:
101: /// Utility routine to check two blocks for equality.
102: public static boolean equalsBlock(byte[] a, byte[] b) {
103: return equalsBlock(a, 0, b, 0, a.length);
104: }
105:
106: /// Utility routine fill a block with a given byte.
107: public static void fillBlock(byte[] block, int blockOff, byte b,
108: int len) {
109: for (int i = blockOff; i < blockOff + len; ++i)
110: block[i] = b;
111: }
112:
113: /// Utility routine fill a block with a given byte.
114: public static void fillBlock(byte[] block, byte b) {
115: fillBlock(block, 0, b, block.length);
116: }
117:
118: /// Squash bytes down to ints.
119: public static void squashBytesToInts(byte[] inBytes, int inOff,
120: int[] outInts, int outOff, int intLen) {
121: for (int i = 0; i < intLen; ++i)
122: outInts[outOff + i] = ((inBytes[inOff + i * 4] & 0xff) << 24)
123: | ((inBytes[inOff + i * 4 + 1] & 0xff) << 16)
124: | ((inBytes[inOff + i * 4 + 2] & 0xff) << 8)
125: | ((inBytes[inOff + i * 4 + 3] & 0xff));
126: }
127:
128: /// Spread ints into bytes.
129: public static void spreadIntsToBytes(int[] inInts, int inOff,
130: byte[] outBytes, int outOff, int intLen) {
131: for (int i = 0; i < intLen; ++i) {
132: outBytes[outOff + i * 4] = (byte) ((inInts[inOff + i] >>> 24) & 0xff);
133: outBytes[outOff + i * 4 + 1] = (byte) ((inInts[inOff + i] >>> 16) & 0xff);
134: outBytes[outOff + i * 4 + 2] = (byte) ((inInts[inOff + i] >>> 8) & 0xff);
135: outBytes[outOff + i * 4 + 3] = (byte) ((inInts[inOff + i]) & 0xff);
136: }
137: }
138:
139: /// Squash bytes down to ints, little-endian.
140: public static void squashBytesToIntsLittle(byte[] inBytes,
141: int inOff, int[] outInts, int outOff, int intLen) {
142: for (int i = 0; i < intLen; ++i)
143: outInts[outOff + i] = ((inBytes[inOff + i * 4] & 0xff))
144: | ((inBytes[inOff + i * 4 + 1] & 0xff) << 8)
145: | ((inBytes[inOff + i * 4 + 2] & 0xff) << 16)
146: | ((inBytes[inOff + i * 4 + 3] & 0xff) << 24);
147: }
148:
149: /// Spread ints into bytes, little-endian.
150: public static void spreadIntsToBytesLittle(int[] inInts, int inOff,
151: byte[] outBytes, int outOff, int intLen) {
152: for (int i = 0; i < intLen; ++i) {
153: outBytes[outOff + i * 4] = (byte) ((inInts[inOff + i]) & 0xff);
154: outBytes[outOff + i * 4 + 1] = (byte) ((inInts[inOff + i] >>> 8) & 0xff);
155: outBytes[outOff + i * 4 + 2] = (byte) ((inInts[inOff + i] >>> 16) & 0xff);
156: outBytes[outOff + i * 4 + 3] = (byte) ((inInts[inOff + i] >>> 24) & 0xff);
157: }
158: }
159:
160: /// Squash bytes down to shorts.
161: public static void squashBytesToShorts(byte[] inBytes, int inOff,
162: int[] outShorts, int outOff, int shortLen) {
163: for (int i = 0; i < shortLen; ++i)
164: outShorts[outOff + i] = ((inBytes[inOff + i * 2] & 0xff) << 8)
165: | ((inBytes[inOff + i * 2 + 1] & 0xff));
166: }
167:
168: /// Spread shorts into bytes.
169: public static void spreadShortsToBytes(int[] inShorts, int inOff,
170: byte[] outBytes, int outOff, int shortLen) {
171: for (int i = 0; i < shortLen; ++i) {
172: outBytes[outOff + i * 2] = (byte) ((inShorts[inOff + i] >>> 8) & 0xff);
173: outBytes[outOff + i * 2 + 1] = (byte) ((inShorts[inOff + i]) & 0xff);
174: }
175: }
176:
177: /// Squash bytes down to shorts, little endian.
178: public static void squashBytesToShortsLittle(byte[] inBytes,
179: int inOff, int[] outShorts, int outOff, int shortLen) {
180: for (int i = 0; i < shortLen; ++i)
181: outShorts[outOff + i] = ((inBytes[inOff + i * 2] & 0xff))
182: | ((inBytes[inOff + i * 2 + 1] & 0xff) << 8);
183: }
184:
185: /// Spread shorts into bytes, little endian.
186: public static void spreadShortsToBytesLittle(int[] inShorts,
187: int inOff, byte[] outBytes, int outOff, int shortLen) {
188: for (int i = 0; i < shortLen; ++i) {
189: outBytes[outOff + i * 2] = (byte) ((inShorts[inOff + i]) & 0xff);
190: outBytes[outOff + i * 2 + 1] = (byte) ((inShorts[inOff + i] >>> 8) & 0xff);
191: }
192: }
193:
194: /// Convert a block to a String representation.
195: public static String toStringBlock(byte[] block, int off, int len) {
196: String hexits = "0123456789abcdef";
197: StringBuffer buf = new StringBuffer();
198: for (int i = off; i < off + len; ++i) {
199: buf.append(hexits.charAt((block[i] >>> 4) & 0xf));
200: buf.append(hexits.charAt(block[i] & 0xf));
201: }
202: return "[" + buf + "]";
203: }
204:
205: /// Convert a block to a String representation.
206: public static String toStringBlock(byte[] block) {
207: return toStringBlock(block, 0, block.length);
208: }
209:
210: }
|