/** * Creates a new {@code HKDF} instance. * * @param algorithm the MAC algorithm to use. * @param info optional context and application specific information, may be {@code null} or * empty. * @param dkLen the desired length for derived keys, in bytes. * @throws NullPointerException if {@code algorithm} is {@code null}. * @throws IllegalArgumentException if {@code dkLen} is negative, or if the MAC algorithm is * unknown, or if {@code dkLen} is greater than 255 * MAC algorithm's output length. */ HKDF(Algorithm<MAC> algorithm, byte[] info, int dkLen) { Parameters.checkCondition(dkLen > 0); MAC mac = Factory.newMAC(algorithm, new byte[0]); Parameters.checkCondition(dkLen <= 255 * mac.length()); this.algorithm = algorithm; this.dkLen = dkLen; this.info = info == null ? new byte[0] : XArrays.copyOf(info); }
/** * Creates and returns a {@link MAC} instance corresponding to the given algorithm, initialized * with the provided secret key. * * @param algorithm the MAC algorithm. * @param key the secret key. * @return the created {@link MAC} instance. * @throws NullPointerException if {@code algorithm} is {@code null}. * @throws IllegalArgumentException if the given algorithm is unknown. */ static MAC newMAC(Algorithm<MAC> algorithm, byte[] key) { Parameters.checkNotNull(algorithm); MAC mac; if (algorithm == Algorithm.HMAC_MD2) { mac = HMAC.md2(key); } else if (algorithm == Algorithm.HMAC_MD4) { mac = HMAC.md4(key); } else if (algorithm == Algorithm.HMAC_MD5) { mac = HMAC.md5(key); } else if (algorithm == Algorithm.HMAC_SHA1) { mac = HMAC.sha1(key); } else if (algorithm == Algorithm.HMAC_SHA256) { mac = HMAC.sha256(key); } else if (algorithm == Algorithm.HMAC_SHA512) { mac = HMAC.sha512(key); } else if (algorithm == Algorithm.HMAC_KECCAK224) { mac = HMAC.keccak224(key); } else if (algorithm == Algorithm.HMAC_KECCAK256) { mac = HMAC.keccak256(key); } else if (algorithm == Algorithm.HMAC_KECCAK384) { mac = HMAC.keccak384(key); } else if (algorithm == Algorithm.HMAC_KECCAK512) { mac = HMAC.keccak512(key); } else { throw new IllegalArgumentException("Unknown algorithm"); } return mac; }
/** * Creates and returns a {@link Digest} instance corresponding to the given algorithm. * * @param algorithm the digest algorithm. * @return the created {@link Digest} instance. * @throws NullPointerException if {@code algorithm} is {@code null}. * @throws IllegalArgumentException if the given algorithm is unknown. */ static Digest newDigest(Algorithm<Digest> algorithm) { Parameters.checkNotNull(algorithm); Digest digest; if (algorithm == Algorithm.MD2) { digest = Digests.md2(); } else if (algorithm == Algorithm.MD4) { digest = Digests.md4(); } else if (algorithm == Algorithm.MD5) { digest = Digests.md5(); } else if (algorithm == Algorithm.SHA1) { digest = Digests.sha1(); } else if (algorithm == Algorithm.SHA256) { digest = Digests.sha256(); } else if (algorithm == Algorithm.SHA512) { digest = Digests.sha512(); } else if (algorithm == Algorithm.KECCAK224) { digest = Digests.keccak224(); } else if (algorithm == Algorithm.KECCAK256) { digest = Digests.keccak256(); } else if (algorithm == Algorithm.KECCAK384) { digest = Digests.keccak384(); } else if (algorithm == Algorithm.KECCAK512) { digest = Digests.keccak512(); } else { throw new IllegalArgumentException("Unknown algorithm"); } return digest; }
/** * Creates a new {@code StringReader}. * * @param strings the input {@link String}s. * @throws NullPointerException if {@code strings} is {@code null} or if it contains a {@code * null} reference. */ public StringReader(Iterable<String> strings) { this.in = new StringBuilder(); for (String str : strings) { Parameters.checkNotNull(str); this.in.append(str); } this.in.trimToSize(); }
@Override public long skip(long n) { Parameters.checkCondition(n >= 0); if (finished()) { return 0; } long skipped = n; if (n > in.length() - index) { skipped = in.length() - index; } index += skipped; return skipped; }
/** * Marks the current position in the stream. Subsequent calls to reset() will reposition the * stream to this point. * * @param readLimit limit on the number of characters that may be read while still preserving the * mark. Because the stream's input comes from {@code String}s, there is no actual limit, so * this argument must not be negative, but is otherwise ignored. * @throws IllegalArgumentException if {@code readLimit} is negative. */ @Override public void mark(int readLimit) { Parameters.checkCondition(readLimit >= 0); mark = index; }