// Path: src/main/java/com/github/aelstad/keccakj/keyak/v2/LakeKeyak.java
// public class LakeKeyak {
// 	private final static int KEYPACK_LENGTH = 40;
// 	private final static int SQUEEZE_BYTES = 1344/8;
// 	private final static int ABSORB_BYTES = 1536/8;
// 
// 	Piston piston;
// 
// 	public LakeKeyak() {
// 		piston = new Piston(SQUEEZE_BYTES, ABSORB_BYTES);
// 	}
// 
// 	public void init(byte[] key, byte[] nonce, int nonceOff, int nonceLen, byte[] tag, int tagoff, boolean forget, boolean unwrap) throws IOException, InvalidKeyException
// 	{
// 		if(key == null || key.length > KEYPACK_LENGTH-2)
// 			throw new InvalidKeyException();
// 
// 		piston.reset();
// 
// 		PistonInitStreamBuilder pisb = new PistonInitStreamBuilder(key, KEYPACK_LENGTH, nonce, nonceOff, nonceLen);
// 
// 		InputStream is = pisb.stream((byte) 1, (byte) 0);
// 		piston.setStreams(null, is);
// 
// 		int len = 0;
// 		do {
// 			if(len > 0) {
// 				piston.spark();
// 			} else {
// 				len = piston.fillBuffer();
// 			}
// 			piston.transformBuffer(null, false);
// 			len = piston.fillBuffer();
// 		} while(len > 0);
// 		if(forget) {
// 			forget();
// 		}
// 		piston.handleTag(tag, tagoff, tag != null ? 16 : 0, unwrap);
// 	}
// 
// 	void forget() throws IOException {
// 		byte[] tmp = new byte[32];
// 		piston.handleTag(tmp, 0, tmp.length, false);
// 		piston.setStreams(null, new ByteArrayInputStream(tmp));
// 		piston.fillBuffer();
// 		piston.transformBuffer(null, false);
// 	}
// 
// 	void wrapOrUnwrap(InputStream in, InputStream ad, OutputStream out, byte[] tag, int tagoff, boolean forget, boolean unwrap) throws IOException
// 	{
// 		piston.setStreams(in, ad);
// 		int len = 0;
// 		do {
// 			if(len > 0) {
// 				piston.spark();
// 			} else {
// 				len = piston.fillBuffer();
// 			}
// 			piston.transformBuffer(out, unwrap);
// 			len = piston.fillBuffer();
// 		} while(len > 0);
// 		if(forget) {
// 			forget();
// 		}
// 		piston.handleTag(tag, tagoff, 16, unwrap);
// 	}
// 
// 	public void unwrap(InputStream ciphertext, InputStream ad, OutputStream plaintext, byte[] tag, int tagoff, boolean forget) throws IOException
// 	{
// 		wrapOrUnwrap(ciphertext, ad, plaintext, tag, tagoff, forget, true);
// 	}
// 
// 	public void wrap(InputStream ciphertext, InputStream ad, OutputStream plaintext, byte[] tag, int tagoff, boolean forget) throws IOException
// 	{
// 		wrapOrUnwrap(ciphertext, ad, plaintext, tag, tagoff, forget, false);
// 	}
// }


import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;
import org.junit.Assert;
import org.junit.Test;
import com.github.aelstad.keccakj.keyak.v2.LakeKeyak;
package com.github.aelstad.keccakj.keyak.v2;




public class TestLakeKeyak {

	byte[] tagBuf = new byte[16];

	byte[] generateSimpleRawMaterial(int len, int seed1, int seed2)
	{
		seed1 &= 0xff;
		byte[] rv = new byte[len];
		for(int i=0; i < len; ++i) {
			int iRolled= ((i&0xff) << (seed2&7)) | ((i&0xff) >>> 8-(seed2&7));
			int val = seed1 + (161*len) - iRolled + i;
			val &= 0xff;
			rv[i] = (byte) val;
		}
		return rv;
	}

	String getHexString(byte[] rv) {
		String tmp = Hex.encodeHexString(rv);
		String formatted="";
		for(int i=0; i < tmp.length(); i+=2) {
			if(formatted.length()>0) formatted += " ";
			formatted += tmp.substring(i, i+2);
		}
		return formatted;
	}

// Path: src/main/java/com/github/aelstad/keccakj/keyak/v2/LakeKeyak.java
// public class LakeKeyak {
// 	private final static int KEYPACK_LENGTH = 40;
// 	private final static int SQUEEZE_BYTES = 1344/8;
// 	private final static int ABSORB_BYTES = 1536/8;
// 
// 	Piston piston;
// 
// 	public LakeKeyak() {
// 		piston = new Piston(SQUEEZE_BYTES, ABSORB_BYTES);
// 	}
// 
// 	public void init(byte[] key, byte[] nonce, int nonceOff, int nonceLen, byte[] tag, int tagoff, boolean forget, boolean unwrap) throws IOException, InvalidKeyException
// 	{
// 		if(key == null || key.length > KEYPACK_LENGTH-2)
// 			throw new InvalidKeyException();
// 
// 		piston.reset();
// 
// 		PistonInitStreamBuilder pisb = new PistonInitStreamBuilder(key, KEYPACK_LENGTH, nonce, nonceOff, nonceLen);
// 
// 		InputStream is = pisb.stream((byte) 1, (byte) 0);
// 		piston.setStreams(null, is);
// 
// 		int len = 0;
// 		do {
// 			if(len > 0) {
// 				piston.spark();
// 			} else {
// 				len = piston.fillBuffer();
// 			}
// 			piston.transformBuffer(null, false);
// 			len = piston.fillBuffer();
// 		} while(len > 0);
// 		if(forget) {
// 			forget();
// 		}
// 		piston.handleTag(tag, tagoff, tag != null ? 16 : 0, unwrap);
// 	}
// 
// 	void forget() throws IOException {
// 		byte[] tmp = new byte[32];
// 		piston.handleTag(tmp, 0, tmp.length, false);
// 		piston.setStreams(null, new ByteArrayInputStream(tmp));
// 		piston.fillBuffer();
// 		piston.transformBuffer(null, false);
// 	}
// 
// 	void wrapOrUnwrap(InputStream in, InputStream ad, OutputStream out, byte[] tag, int tagoff, boolean forget, boolean unwrap) throws IOException
// 	{
// 		piston.setStreams(in, ad);
// 		int len = 0;
// 		do {
// 			if(len > 0) {
// 				piston.spark();
// 			} else {
// 				len = piston.fillBuffer();
// 			}
// 			piston.transformBuffer(out, unwrap);
// 			len = piston.fillBuffer();
// 		} while(len > 0);
// 		if(forget) {
// 			forget();
// 		}
// 		piston.handleTag(tag, tagoff, 16, unwrap);
// 	}
// 
// 	public void unwrap(InputStream ciphertext, InputStream ad, OutputStream plaintext, byte[] tag, int tagoff, boolean forget) throws IOException
// 	{
// 		wrapOrUnwrap(ciphertext, ad, plaintext, tag, tagoff, forget, true);
// 	}
// 
// 	public void wrap(InputStream ciphertext, InputStream ad, OutputStream plaintext, byte[] tag, int tagoff, boolean forget) throws IOException
// 	{
// 		wrapOrUnwrap(ciphertext, ad, plaintext, tag, tagoff, forget, false);
// 	}
// }


// Path: src/test/java/com/github/aelstad/keccakj/keyak/v2/TestLakeKeyak.java
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;
import org.junit.Assert;
import org.junit.Test;
import com.github.aelstad.keccakj.keyak.v2.LakeKeyak;

package com.github.aelstad.keccakj.keyak.v2;




public class TestLakeKeyak {

	byte[] tagBuf = new byte[16];

	byte[] generateSimpleRawMaterial(int len, int seed1, int seed2)
	{
		seed1 &= 0xff;
		byte[] rv = new byte[len];
		for(int i=0; i < len; ++i) {
			int iRolled= ((i&0xff) << (seed2&7)) | ((i&0xff) >>> 8-(seed2&7));
			int val = seed1 + (161*len) - iRolled + i;
			val &= 0xff;
			rv[i] = (byte) val;
		}
		return rv;
	}

	String getHexString(byte[] rv) {
		String tmp = Hex.encodeHexString(rv);
		String formatted="";
		for(int i=0; i < tmp.length(); i+=2) {
			if(formatted.length()>0) formatted += " ";
			formatted += tmp.substring(i, i+2);
		}
		return formatted;
	}

	void startEngine(LakeKeyak global, LakeKeyak wrap, LakeKeyak unwrap, byte[] key, byte[] nonce, boolean tag, boolean forget) throws IOException, InvalidKeyException {