package jnorx;


/**
 *  
 * java implementation of NORX.
 * 
 * @author r. graenitz 2015 
 * @license CC0, see LICENSE for more details.
 *
 */
public class JNorx {
	
	Params params = null;
	
	
	public JNorx (int w, int r, int d, int t){
		params = new Params(w, d, 0xFFFFFFFF, r, 0);
	}
	
	
	static class Params {
		
		Params(){
			W = 32;
			D = 1;
			M = 0xFFFFFFFF;
			U = U32;
			norxR = 0;
			A = 0;
		}
		
		Params(int w, int d, int m, int r, int a){
			W = w;
			D = d;
			M = m;
			if (w==32){
				U = U32;
			}	
			norxR = r;
			A = a;
		}
		
		
		static int U32[] = {
				0x243F6A88, 0x85A308D3,
				0x13198A2E, 0x03707344,
				0x254F537A, 0x38531D48,
				0x839C6E83, 0xF97A3AE5,
				0x8C91D88C, 0x11EAFB59
		};
		
		static int R32[] = {8, 11, 16, 31};
		
		
		int W;
		
		int D;
		
		int M;
		
		int U[];
		
		int norxR;
		
		int A;
		
		int[] R_;
		
	}
	
	
	/**
	 * H
	 * approx. a + b
	 * 
	 * @param a
	 * @param b
	 * @return
	 */
	int H(int a, int b){
		return ((a ^ b) ^ ((a & b) << 1));
	}
	
	/**
	 * ROTR
	 * 
	 * @param a
	 * @param r
	 * @return
	 */
	int ROTR(int a , int r) {
		return ((a >>> r) | (a << (params.W - r)));
	}
	
	/**
	 * G
	 * 
	 * @param S
	 * @param a
	 * @param b
	 * @param c
	 * @param d
	 */
	void G(int[] S, int a, int b, int c, int d) {
		S[a] = H(S[a], S[b]);
		S[d] = ROTR(S[a] ^ S[d], 8);
		S[c] = H(S[c], S[d]);
		S[b] = ROTR(S[b] ^ S[c], 11);
		S[a] = H(S[a], S[b]);
		S[d] = ROTR(S[a] ^ S[d], 16);
		S[c] = H(S[c], S[d]);
		S[b] = ROTR(S[b] ^ S[c], 31);
	}
	
	/**
	 * F
	 * 
	 * @param S
	 * @param r
	 */
	void F(int[] S) {
		
		// Column step
		G(S, 0, 4, 8, 12);
		G(S, 1, 5, 9, 13);
		G(S, 2, 6, 10, 14);
		G(S, 3, 7, 11, 15);
		
		// Diagonal step
		G(S, 0, 5, 10, 15);
		G(S, 1, 6, 11, 12);
		G(S, 2, 7, 8, 13);
		G(S, 3, 4, 9, 14);	
	}
	
	/**
	 * permute 
	 * 
	 * @param S
	 * @param r
	 */
	void permute(int[] S, int r){
		for (int i = 0; i < r; i++) {
			F(S);
		}
	}
	
	
	
}
