/*
 * Based on the public domain C reference code for New Hope.
 * This Java version is also placed into the public domain.
 * 
 * Original authors: Erdem Alkim, Léo Ducas, Thomas Pöppelmann, Peter Schwabe
 * Java port: Rhys Weatherley
 */

package com.southernstorm.noise.crypto;

import java.util.Arrays;

/**
 * New Hope key exchange algorithm, "torref" variant.
 * 
 * This version of New Hope implements the alternative constant-time
 * method for generating the public "a" value for anonymity networks
 * like Tor.  It is not binary-compatible with the standard New Hope
 * implementation in the NewHope class.
 * 
 * Reference: https://cryptojedi.org/papers/newhope-20160803.pdf
 * 
 * @see NewHope
 */
public class NewHopeTor extends NewHope {

	public NewHopeTor() {}

	@Override
	protected void uniform(char[] coeffs, byte[] seed)
	{
	  long[] state = new long [25];
	  int nblocks=16;
	  byte[] buf = new byte [SHAKE128_RATE*nblocks];
	  char[] x = new char [buf.length / 2];

	  try {
		  shake128_absorb(state, seed, 0, SEEDBYTES);
		  do
		  {
		    shake128_squeezeblocks(buf, 0, nblocks, state);
		    for (int i = buf.length - 2; i >= 0; i -= 2)
		    {
		      x[i / 2] = (char)((buf[i] & 0xff) | ((buf[i+1] & 0xff) << 8));
		    }
		  }
		  while (discardtopoly(coeffs, x));
	  } finally {
		  Arrays.fill(state, 0);
		  Arrays.fill(buf, (byte)0);
		  Arrays.fill(x, (char)0);
	  }
	}

	private static boolean discardtopoly(char[] coeffs, char[] x)
	{
	  int i, r=0;

	  for(i=0;i<16;i++)
		  batcher84(x, i);

	  // Check whether we're safe:
	  for(i=1008;i<1024;i++)
	    r |= 61444 - x[i];
	  if((r >>= 31) != 0) return true;

	  // If we are, copy coefficients to polynomial:
	  for(i=0;i<PARAM_N;i++)
	    coeffs[i] = x[i];

	  return false;
	}

	private static void batcher84(char[] x, int offset)
	{
		int c, t;
		c = 61444 - x[offset +    0]; t = (x[offset +    0] ^ x[offset +   16]) & (c >> 31); x[offset +    0] ^= t; x[offset +   16] ^= t;
		c = 61444 - x[offset +   32]; t = (x[offset +   32] ^ x[offset +   48]) & (c >> 31); x[offset +   32] ^= t; x[offset +   48] ^= t;
		c = 61444 - x[offset +    0]; t = (x[offset +    0] ^ x[offset +   32]) & (c >> 31); x[offset +    0] ^= t; x[offset +   32] ^= t;
		c = 61444 - x[offset +   16]; t = (x[offset +   16] ^ x[offset +   48]) & (c >> 31); x[offset +   16] ^= t; x[offset +   48] ^= t;
		c = 61444 - x[offset +   16]; t = (x[offset +   16] ^ x[offset +   32]) & (c >> 31); x[offset +   16] ^= t; x[offset +   32] ^= t;
		c = 61444 - x[offset +   64]; t = (x[offset +   64] ^ x[offset +   80]) & (c >> 31); x[offset +   64] ^= t; x[offset +   80] ^= t;
		c = 61444 - x[offset +   96]; t = (x[offset +   96] ^ x[offset +  112]) & (c >> 31); x[offset +   96] ^= t; x[offset +  112] ^= t;
		c = 61444 - x[offset +   64]; t = (x[offset +   64] ^ x[offset +   96]) & (c >> 31); x[offset +   64] ^= t; x[offset +   96] ^= t;
		c = 61444 - x[offset +   80]; t = (x[offset +   80] ^ x[offset +  112]) & (c >> 31); x[offset +   80] ^= t; x[offset +  112] ^= t;
		c = 61444 - x[offset +   80]; t = (x[offset +   80] ^ x[offset +   96]) & (c >> 31); x[offset +   80] ^= t; x[offset +   96] ^= t;
		c = 61444 - x[offset +    0]; t = (x[offset +    0] ^ x[offset +   64]) & (c >> 31); x[offset +    0] ^= t; x[offset +   64] ^= t;
		c = 61444 - x[offset +   32]; t = (x[offset +   32] ^ x[offset +   96]) & (c >> 31); x[offset +   32] ^= t; x[offset +   96] ^= t;
		c = 61444 - x[offset +   32]; t = (x[offset +   32] ^ x[offset +   64]) & (c >> 31); x[offset +   32] ^= t; x[offset +   64] ^= t;
		c = 61444 - x[offset +   16]; t = (x[offset +   16] ^ x[offset +   80]) & (c >> 31); x[offset +   16] ^= t; x[offset +   80] ^= t;
		c = 61444 - x[offset +   48]; t = (x[offset +   48] ^ x[offset +  112]) & (c >> 31); x[offset +   48] ^= t; x[offset +  112] ^= t;
		c = 61444 - x[offset +   48]; t = (x[offset +   48] ^ x[offset +   80]) & (c >> 31); x[offset +   48] ^= t; x[offset +   80] ^= t;
		c = 61444 - x[offset +   16]; t = (x[offset +   16] ^ x[offset +   32]) & (c >> 31); x[offset +   16] ^= t; x[offset +   32] ^= t;
		c = 61444 - x[offset +   48]; t = (x[offset +   48] ^ x[offset +   64]) & (c >> 31); x[offset +   48] ^= t; x[offset +   64] ^= t;
		c = 61444 - x[offset +   80]; t = (x[offset +   80] ^ x[offset +   96]) & (c >> 31); x[offset +   80] ^= t; x[offset +   96] ^= t;
		c = 61444 - x[offset +  128]; t = (x[offset +  128] ^ x[offset +  144]) & (c >> 31); x[offset +  128] ^= t; x[offset +  144] ^= t;
		c = 61444 - x[offset +  160]; t = (x[offset +  160] ^ x[offset +  176]) & (c >> 31); x[offset +  160] ^= t; x[offset +  176] ^= t;
		c = 61444 - x[offset +  128]; t = (x[offset +  128] ^ x[offset +  160]) & (c >> 31); x[offset +  128] ^= t; x[offset +  160] ^= t;
		c = 61444 - x[offset +  144]; t = (x[offset +  144] ^ x[offset +  176]) & (c >> 31); x[offset +  144] ^= t; x[offset +  176] ^= t;
		c = 61444 - x[offset +  144]; t = (x[offset +  144] ^ x[offset +  160]) & (c >> 31); x[offset +  144] ^= t; x[offset +  160] ^= t;
		c = 61444 - x[offset +  192]; t = (x[offset +  192] ^ x[offset +  208]) & (c >> 31); x[offset +  192] ^= t; x[offset +  208] ^= t;
		c = 61444 - x[offset +  224]; t = (x[offset +  224] ^ x[offset +  240]) & (c >> 31); x[offset +  224] ^= t; x[offset +  240] ^= t;
		c = 61444 - x[offset +  192]; t = (x[offset +  192] ^ x[offset +  224]) & (c >> 31); x[offset +  192] ^= t; x[offset +  224] ^= t;
		c = 61444 - x[offset +  208]; t = (x[offset +  208] ^ x[offset +  240]) & (c >> 31); x[offset +  208] ^= t; x[offset +  240] ^= t;
		c = 61444 - x[offset +  208]; t = (x[offset +  208] ^ x[offset +  224]) & (c >> 31); x[offset +  208] ^= t; x[offset +  224] ^= t;
		c = 61444 - x[offset +  128]; t = (x[offset +  128] ^ x[offset +  192]) & (c >> 31); x[offset +  128] ^= t; x[offset +  192] ^= t;
		c = 61444 - x[offset +  160]; t = (x[offset +  160] ^ x[offset +  224]) & (c >> 31); x[offset +  160] ^= t; x[offset +  224] ^= t;
		c = 61444 - x[offset +  160]; t = (x[offset +  160] ^ x[offset +  192]) & (c >> 31); x[offset +  160] ^= t; x[offset +  192] ^= t;
		c = 61444 - x[offset +  144]; t = (x[offset +  144] ^ x[offset +  208]) & (c >> 31); x[offset +  144] ^= t; x[offset +  208] ^= t;
		c = 61444 - x[offset +  176]; t = (x[offset +  176] ^ x[offset +  240]) & (c >> 31); x[offset +  176] ^= t; x[offset +  240] ^= t;
		c = 61444 - x[offset +  176]; t = (x[offset +  176] ^ x[offset +  208]) & (c >> 31); x[offset +  176] ^= t; x[offset +  208] ^= t;
		c = 61444 - x[offset +  144]; t = (x[offset +  144] ^ x[offset +  160]) & (c >> 31); x[offset +  144] ^= t; x[offset +  160] ^= t;
		c = 61444 - x[offset +  176]; t = (x[offset +  176] ^ x[offset +  192]) & (c >> 31); x[offset +  176] ^= t; x[offset +  192] ^= t;
		c = 61444 - x[offset +  208]; t = (x[offset +  208] ^ x[offset +  224]) & (c >> 31); x[offset +  208] ^= t; x[offset +  224] ^= t;
		c = 61444 - x[offset +    0]; t = (x[offset +    0] ^ x[offset +  128]) & (c >> 31); x[offset +    0] ^= t; x[offset +  128] ^= t;
		c = 61444 - x[offset +   64]; t = (x[offset +   64] ^ x[offset +  192]) & (c >> 31); x[offset +   64] ^= t; x[offset +  192] ^= t;
		c = 61444 - x[offset +   64]; t = (x[offset +   64] ^ x[offset +  128]) & (c >> 31); x[offset +   64] ^= t; x[offset +  128] ^= t;
		c = 61444 - x[offset +   32]; t = (x[offset +   32] ^ x[offset +  160]) & (c >> 31); x[offset +   32] ^= t; x[offset +  160] ^= t;
		c = 61444 - x[offset +   96]; t = (x[offset +   96] ^ x[offset +  224]) & (c >> 31); x[offset +   96] ^= t; x[offset +  224] ^= t;
		c = 61444 - x[offset +   96]; t = (x[offset +   96] ^ x[offset +  160]) & (c >> 31); x[offset +   96] ^= t; x[offset +  160] ^= t;
		c = 61444 - x[offset +   32]; t = (x[offset +   32] ^ x[offset +   64]) & (c >> 31); x[offset +   32] ^= t; x[offset +   64] ^= t;
		c = 61444 - x[offset +   96]; t = (x[offset +   96] ^ x[offset +  128]) & (c >> 31); x[offset +   96] ^= t; x[offset +  128] ^= t;
		c = 61444 - x[offset +  160]; t = (x[offset +  160] ^ x[offset +  192]) & (c >> 31); x[offset +  160] ^= t; x[offset +  192] ^= t;
		c = 61444 - x[offset +   16]; t = (x[offset +   16] ^ x[offset +  144]) & (c >> 31); x[offset +   16] ^= t; x[offset +  144] ^= t;
		c = 61444 - x[offset +   80]; t = (x[offset +   80] ^ x[offset +  208]) & (c >> 31); x[offset +   80] ^= t; x[offset +  208] ^= t;
		c = 61444 - x[offset +   80]; t = (x[offset +   80] ^ x[offset +  144]) & (c >> 31); x[offset +   80] ^= t; x[offset +  144] ^= t;
		c = 61444 - x[offset +   48]; t = (x[offset +   48] ^ x[offset +  176]) & (c >> 31); x[offset +   48] ^= t; x[offset +  176] ^= t;
		c = 61444 - x[offset +  112]; t = (x[offset +  112] ^ x[offset +  240]) & (c >> 31); x[offset +  112] ^= t; x[offset +  240] ^= t;
		c = 61444 - x[offset +  112]; t = (x[offset +  112] ^ x[offset +  176]) & (c >> 31); x[offset +  112] ^= t; x[offset +  176] ^= t;
		c = 61444 - x[offset +   48]; t = (x[offset +   48] ^ x[offset +   80]) & (c >> 31); x[offset +   48] ^= t; x[offset +   80] ^= t;
		c = 61444 - x[offset +  112]; t = (x[offset +  112] ^ x[offset +  144]) & (c >> 31); x[offset +  112] ^= t; x[offset +  144] ^= t;
		c = 61444 - x[offset +  176]; t = (x[offset +  176] ^ x[offset +  208]) & (c >> 31); x[offset +  176] ^= t; x[offset +  208] ^= t;
		c = 61444 - x[offset +   16]; t = (x[offset +   16] ^ x[offset +   32]) & (c >> 31); x[offset +   16] ^= t; x[offset +   32] ^= t;
		c = 61444 - x[offset +   48]; t = (x[offset +   48] ^ x[offset +   64]) & (c >> 31); x[offset +   48] ^= t; x[offset +   64] ^= t;
		c = 61444 - x[offset +   80]; t = (x[offset +   80] ^ x[offset +   96]) & (c >> 31); x[offset +   80] ^= t; x[offset +   96] ^= t;
		c = 61444 - x[offset +  112]; t = (x[offset +  112] ^ x[offset +  128]) & (c >> 31); x[offset +  112] ^= t; x[offset +  128] ^= t;
		c = 61444 - x[offset +  144]; t = (x[offset +  144] ^ x[offset +  160]) & (c >> 31); x[offset +  144] ^= t; x[offset +  160] ^= t;
		c = 61444 - x[offset +  176]; t = (x[offset +  176] ^ x[offset +  192]) & (c >> 31); x[offset +  176] ^= t; x[offset +  192] ^= t;
		c = 61444 - x[offset +  208]; t = (x[offset +  208] ^ x[offset +  224]) & (c >> 31); x[offset +  208] ^= t; x[offset +  224] ^= t;
		c = 61444 - x[offset +  256]; t = (x[offset +  256] ^ x[offset +  272]) & (c >> 31); x[offset +  256] ^= t; x[offset +  272] ^= t;
		c = 61444 - x[offset +  288]; t = (x[offset +  288] ^ x[offset +  304]) & (c >> 31); x[offset +  288] ^= t; x[offset +  304] ^= t;
		c = 61444 - x[offset +  256]; t = (x[offset +  256] ^ x[offset +  288]) & (c >> 31); x[offset +  256] ^= t; x[offset +  288] ^= t;
		c = 61444 - x[offset +  272]; t = (x[offset +  272] ^ x[offset +  304]) & (c >> 31); x[offset +  272] ^= t; x[offset +  304] ^= t;
		c = 61444 - x[offset +  272]; t = (x[offset +  272] ^ x[offset +  288]) & (c >> 31); x[offset +  272] ^= t; x[offset +  288] ^= t;
		c = 61444 - x[offset +  320]; t = (x[offset +  320] ^ x[offset +  336]) & (c >> 31); x[offset +  320] ^= t; x[offset +  336] ^= t;
		c = 61444 - x[offset +  352]; t = (x[offset +  352] ^ x[offset +  368]) & (c >> 31); x[offset +  352] ^= t; x[offset +  368] ^= t;
		c = 61444 - x[offset +  320]; t = (x[offset +  320] ^ x[offset +  352]) & (c >> 31); x[offset +  320] ^= t; x[offset +  352] ^= t;
		c = 61444 - x[offset +  336]; t = (x[offset +  336] ^ x[offset +  368]) & (c >> 31); x[offset +  336] ^= t; x[offset +  368] ^= t;
		c = 61444 - x[offset +  336]; t = (x[offset +  336] ^ x[offset +  352]) & (c >> 31); x[offset +  336] ^= t; x[offset +  352] ^= t;
		c = 61444 - x[offset +  256]; t = (x[offset +  256] ^ x[offset +  320]) & (c >> 31); x[offset +  256] ^= t; x[offset +  320] ^= t;
		c = 61444 - x[offset +  288]; t = (x[offset +  288] ^ x[offset +  352]) & (c >> 31); x[offset +  288] ^= t; x[offset +  352] ^= t;
		c = 61444 - x[offset +  288]; t = (x[offset +  288] ^ x[offset +  320]) & (c >> 31); x[offset +  288] ^= t; x[offset +  320] ^= t;
		c = 61444 - x[offset +  272]; t = (x[offset +  272] ^ x[offset +  336]) & (c >> 31); x[offset +  272] ^= t; x[offset +  336] ^= t;
		c = 61444 - x[offset +  304]; t = (x[offset +  304] ^ x[offset +  368]) & (c >> 31); x[offset +  304] ^= t; x[offset +  368] ^= t;
		c = 61444 - x[offset +  304]; t = (x[offset +  304] ^ x[offset +  336]) & (c >> 31); x[offset +  304] ^= t; x[offset +  336] ^= t;
		c = 61444 - x[offset +  272]; t = (x[offset +  272] ^ x[offset +  288]) & (c >> 31); x[offset +  272] ^= t; x[offset +  288] ^= t;
		c = 61444 - x[offset +  304]; t = (x[offset +  304] ^ x[offset +  320]) & (c >> 31); x[offset +  304] ^= t; x[offset +  320] ^= t;
		c = 61444 - x[offset +  336]; t = (x[offset +  336] ^ x[offset +  352]) & (c >> 31); x[offset +  336] ^= t; x[offset +  352] ^= t;
		c = 61444 - x[offset +  384]; t = (x[offset +  384] ^ x[offset +  400]) & (c >> 31); x[offset +  384] ^= t; x[offset +  400] ^= t;
		c = 61444 - x[offset +  416]; t = (x[offset +  416] ^ x[offset +  432]) & (c >> 31); x[offset +  416] ^= t; x[offset +  432] ^= t;
		c = 61444 - x[offset +  384]; t = (x[offset +  384] ^ x[offset +  416]) & (c >> 31); x[offset +  384] ^= t; x[offset +  416] ^= t;
		c = 61444 - x[offset +  400]; t = (x[offset +  400] ^ x[offset +  432]) & (c >> 31); x[offset +  400] ^= t; x[offset +  432] ^= t;
		c = 61444 - x[offset +  400]; t = (x[offset +  400] ^ x[offset +  416]) & (c >> 31); x[offset +  400] ^= t; x[offset +  416] ^= t;
		c = 61444 - x[offset +  448]; t = (x[offset +  448] ^ x[offset +  464]) & (c >> 31); x[offset +  448] ^= t; x[offset +  464] ^= t;
		c = 61444 - x[offset +  480]; t = (x[offset +  480] ^ x[offset +  496]) & (c >> 31); x[offset +  480] ^= t; x[offset +  496] ^= t;
		c = 61444 - x[offset +  448]; t = (x[offset +  448] ^ x[offset +  480]) & (c >> 31); x[offset +  448] ^= t; x[offset +  480] ^= t;
		c = 61444 - x[offset +  464]; t = (x[offset +  464] ^ x[offset +  496]) & (c >> 31); x[offset +  464] ^= t; x[offset +  496] ^= t;
		c = 61444 - x[offset +  464]; t = (x[offset +  464] ^ x[offset +  480]) & (c >> 31); x[offset +  464] ^= t; x[offset +  480] ^= t;
		c = 61444 - x[offset +  384]; t = (x[offset +  384] ^ x[offset +  448]) & (c >> 31); x[offset +  384] ^= t; x[offset +  448] ^= t;
		c = 61444 - x[offset +  416]; t = (x[offset +  416] ^ x[offset +  480]) & (c >> 31); x[offset +  416] ^= t; x[offset +  480] ^= t;
		c = 61444 - x[offset +  416]; t = (x[offset +  416] ^ x[offset +  448]) & (c >> 31); x[offset +  416] ^= t; x[offset +  448] ^= t;
		c = 61444 - x[offset +  400]; t = (x[offset +  400] ^ x[offset +  464]) & (c >> 31); x[offset +  400] ^= t; x[offset +  464] ^= t;
		c = 61444 - x[offset +  432]; t = (x[offset +  432] ^ x[offset +  496]) & (c >> 31); x[offset +  432] ^= t; x[offset +  496] ^= t;
		c = 61444 - x[offset +  432]; t = (x[offset +  432] ^ x[offset +  464]) & (c >> 31); x[offset +  432] ^= t; x[offset +  464] ^= t;
		c = 61444 - x[offset +  400]; t = (x[offset +  400] ^ x[offset +  416]) & (c >> 31); x[offset +  400] ^= t; x[offset +  416] ^= t;
		c = 61444 - x[offset +  432]; t = (x[offset +  432] ^ x[offset +  448]) & (c >> 31); x[offset +  432] ^= t; x[offset +  448] ^= t;
		c = 61444 - x[offset +  464]; t = (x[offset +  464] ^ x[offset +  480]) & (c >> 31); x[offset +  464] ^= t; x[offset +  480] ^= t;
		c = 61444 - x[offset +  256]; t = (x[offset +  256] ^ x[offset +  384]) & (c >> 31); x[offset +  256] ^= t; x[offset +  384] ^= t;
		c = 61444 - x[offset +  320]; t = (x[offset +  320] ^ x[offset +  448]) & (c >> 31); x[offset +  320] ^= t; x[offset +  448] ^= t;
		c = 61444 - x[offset +  320]; t = (x[offset +  320] ^ x[offset +  384]) & (c >> 31); x[offset +  320] ^= t; x[offset +  384] ^= t;
		c = 61444 - x[offset +  288]; t = (x[offset +  288] ^ x[offset +  416]) & (c >> 31); x[offset +  288] ^= t; x[offset +  416] ^= t;
		c = 61444 - x[offset +  352]; t = (x[offset +  352] ^ x[offset +  480]) & (c >> 31); x[offset +  352] ^= t; x[offset +  480] ^= t;
		c = 61444 - x[offset +  352]; t = (x[offset +  352] ^ x[offset +  416]) & (c >> 31); x[offset +  352] ^= t; x[offset +  416] ^= t;
		c = 61444 - x[offset +  288]; t = (x[offset +  288] ^ x[offset +  320]) & (c >> 31); x[offset +  288] ^= t; x[offset +  320] ^= t;
		c = 61444 - x[offset +  352]; t = (x[offset +  352] ^ x[offset +  384]) & (c >> 31); x[offset +  352] ^= t; x[offset +  384] ^= t;
		c = 61444 - x[offset +  416]; t = (x[offset +  416] ^ x[offset +  448]) & (c >> 31); x[offset +  416] ^= t; x[offset +  448] ^= t;
		c = 61444 - x[offset +  272]; t = (x[offset +  272] ^ x[offset +  400]) & (c >> 31); x[offset +  272] ^= t; x[offset +  400] ^= t;
		c = 61444 - x[offset +  336]; t = (x[offset +  336] ^ x[offset +  464]) & (c >> 31); x[offset +  336] ^= t; x[offset +  464] ^= t;
		c = 61444 - x[offset +  336]; t = (x[offset +  336] ^ x[offset +  400]) & (c >> 31); x[offset +  336] ^= t; x[offset +  400] ^= t;
		c = 61444 - x[offset +  304]; t = (x[offset +  304] ^ x[offset +  432]) & (c >> 31); x[offset +  304] ^= t; x[offset +  432] ^= t;
		c = 61444 - x[offset +  368]; t = (x[offset +  368] ^ x[offset +  496]) & (c >> 31); x[offset +  368] ^= t; x[offset +  496] ^= t;
		c = 61444 - x[offset +  368]; t = (x[offset +  368] ^ x[offset +  432]) & (c >> 31); x[offset +  368] ^= t; x[offset +  432] ^= t;
		c = 61444 - x[offset +  304]; t = (x[offset +  304] ^ x[offset +  336]) & (c >> 31); x[offset +  304] ^= t; x[offset +  336] ^= t;
		c = 61444 - x[offset +  368]; t = (x[offset +  368] ^ x[offset +  400]) & (c >> 31); x[offset +  368] ^= t; x[offset +  400] ^= t;
		c = 61444 - x[offset +  432]; t = (x[offset +  432] ^ x[offset +  464]) & (c >> 31); x[offset +  432] ^= t; x[offset +  464] ^= t;
		c = 61444 - x[offset +  272]; t = (x[offset +  272] ^ x[offset +  288]) & (c >> 31); x[offset +  272] ^= t; x[offset +  288] ^= t;
		c = 61444 - x[offset +  304]; t = (x[offset +  304] ^ x[offset +  320]) & (c >> 31); x[offset +  304] ^= t; x[offset +  320] ^= t;
		c = 61444 - x[offset +  336]; t = (x[offset +  336] ^ x[offset +  352]) & (c >> 31); x[offset +  336] ^= t; x[offset +  352] ^= t;
		c = 61444 - x[offset +  368]; t = (x[offset +  368] ^ x[offset +  384]) & (c >> 31); x[offset +  368] ^= t; x[offset +  384] ^= t;
		c = 61444 - x[offset +  400]; t = (x[offset +  400] ^ x[offset +  416]) & (c >> 31); x[offset +  400] ^= t; x[offset +  416] ^= t;
		c = 61444 - x[offset +  432]; t = (x[offset +  432] ^ x[offset +  448]) & (c >> 31); x[offset +  432] ^= t; x[offset +  448] ^= t;
		c = 61444 - x[offset +  464]; t = (x[offset +  464] ^ x[offset +  480]) & (c >> 31); x[offset +  464] ^= t; x[offset +  480] ^= t;
		c = 61444 - x[offset +    0]; t = (x[offset +    0] ^ x[offset +  256]) & (c >> 31); x[offset +    0] ^= t; x[offset +  256] ^= t;
		c = 61444 - x[offset +  128]; t = (x[offset +  128] ^ x[offset +  384]) & (c >> 31); x[offset +  128] ^= t; x[offset +  384] ^= t;
		c = 61444 - x[offset +  128]; t = (x[offset +  128] ^ x[offset +  256]) & (c >> 31); x[offset +  128] ^= t; x[offset +  256] ^= t;
		c = 61444 - x[offset +   64]; t = (x[offset +   64] ^ x[offset +  320]) & (c >> 31); x[offset +   64] ^= t; x[offset +  320] ^= t;
		c = 61444 - x[offset +  192]; t = (x[offset +  192] ^ x[offset +  448]) & (c >> 31); x[offset +  192] ^= t; x[offset +  448] ^= t;
		c = 61444 - x[offset +  192]; t = (x[offset +  192] ^ x[offset +  320]) & (c >> 31); x[offset +  192] ^= t; x[offset +  320] ^= t;
		c = 61444 - x[offset +   64]; t = (x[offset +   64] ^ x[offset +  128]) & (c >> 31); x[offset +   64] ^= t; x[offset +  128] ^= t;
		c = 61444 - x[offset +  192]; t = (x[offset +  192] ^ x[offset +  256]) & (c >> 31); x[offset +  192] ^= t; x[offset +  256] ^= t;
		c = 61444 - x[offset +  320]; t = (x[offset +  320] ^ x[offset +  384]) & (c >> 31); x[offset +  320] ^= t; x[offset +  384] ^= t;
		c = 61444 - x[offset +   32]; t = (x[offset +   32] ^ x[offset +  288]) & (c >> 31); x[offset +   32] ^= t; x[offset +  288] ^= t;
		c = 61444 - x[offset +  160]; t = (x[offset +  160] ^ x[offset +  416]) & (c >> 31); x[offset +  160] ^= t; x[offset +  416] ^= t;
		c = 61444 - x[offset +  160]; t = (x[offset +  160] ^ x[offset +  288]) & (c >> 31); x[offset +  160] ^= t; x[offset +  288] ^= t;
		c = 61444 - x[offset +   96]; t = (x[offset +   96] ^ x[offset +  352]) & (c >> 31); x[offset +   96] ^= t; x[offset +  352] ^= t;
		c = 61444 - x[offset +  224]; t = (x[offset +  224] ^ x[offset +  480]) & (c >> 31); x[offset +  224] ^= t; x[offset +  480] ^= t;
		c = 61444 - x[offset +  224]; t = (x[offset +  224] ^ x[offset +  352]) & (c >> 31); x[offset +  224] ^= t; x[offset +  352] ^= t;
		c = 61444 - x[offset +   96]; t = (x[offset +   96] ^ x[offset +  160]) & (c >> 31); x[offset +   96] ^= t; x[offset +  160] ^= t;
		c = 61444 - x[offset +  224]; t = (x[offset +  224] ^ x[offset +  288]) & (c >> 31); x[offset +  224] ^= t; x[offset +  288] ^= t;
		c = 61444 - x[offset +  352]; t = (x[offset +  352] ^ x[offset +  416]) & (c >> 31); x[offset +  352] ^= t; x[offset +  416] ^= t;
		c = 61444 - x[offset +   32]; t = (x[offset +   32] ^ x[offset +   64]) & (c >> 31); x[offset +   32] ^= t; x[offset +   64] ^= t;
		c = 61444 - x[offset +   96]; t = (x[offset +   96] ^ x[offset +  128]) & (c >> 31); x[offset +   96] ^= t; x[offset +  128] ^= t;
		c = 61444 - x[offset +  160]; t = (x[offset +  160] ^ x[offset +  192]) & (c >> 31); x[offset +  160] ^= t; x[offset +  192] ^= t;
		c = 61444 - x[offset +  224]; t = (x[offset +  224] ^ x[offset +  256]) & (c >> 31); x[offset +  224] ^= t; x[offset +  256] ^= t;
		c = 61444 - x[offset +  288]; t = (x[offset +  288] ^ x[offset +  320]) & (c >> 31); x[offset +  288] ^= t; x[offset +  320] ^= t;
		c = 61444 - x[offset +  352]; t = (x[offset +  352] ^ x[offset +  384]) & (c >> 31); x[offset +  352] ^= t; x[offset +  384] ^= t;
		c = 61444 - x[offset +  416]; t = (x[offset +  416] ^ x[offset +  448]) & (c >> 31); x[offset +  416] ^= t; x[offset +  448] ^= t;
		c = 61444 - x[offset +   16]; t = (x[offset +   16] ^ x[offset +  272]) & (c >> 31); x[offset +   16] ^= t; x[offset +  272] ^= t;
		c = 61444 - x[offset +  144]; t = (x[offset +  144] ^ x[offset +  400]) & (c >> 31); x[offset +  144] ^= t; x[offset +  400] ^= t;
		c = 61444 - x[offset +  144]; t = (x[offset +  144] ^ x[offset +  272]) & (c >> 31); x[offset +  144] ^= t; x[offset +  272] ^= t;
		c = 61444 - x[offset +   80]; t = (x[offset +   80] ^ x[offset +  336]) & (c >> 31); x[offset +   80] ^= t; x[offset +  336] ^= t;
		c = 61444 - x[offset +  208]; t = (x[offset +  208] ^ x[offset +  464]) & (c >> 31); x[offset +  208] ^= t; x[offset +  464] ^= t;
		c = 61444 - x[offset +  208]; t = (x[offset +  208] ^ x[offset +  336]) & (c >> 31); x[offset +  208] ^= t; x[offset +  336] ^= t;
		c = 61444 - x[offset +   80]; t = (x[offset +   80] ^ x[offset +  144]) & (c >> 31); x[offset +   80] ^= t; x[offset +  144] ^= t;
		c = 61444 - x[offset +  208]; t = (x[offset +  208] ^ x[offset +  272]) & (c >> 31); x[offset +  208] ^= t; x[offset +  272] ^= t;
		c = 61444 - x[offset +  336]; t = (x[offset +  336] ^ x[offset +  400]) & (c >> 31); x[offset +  336] ^= t; x[offset +  400] ^= t;
		c = 61444 - x[offset +   48]; t = (x[offset +   48] ^ x[offset +  304]) & (c >> 31); x[offset +   48] ^= t; x[offset +  304] ^= t;
		c = 61444 - x[offset +  176]; t = (x[offset +  176] ^ x[offset +  432]) & (c >> 31); x[offset +  176] ^= t; x[offset +  432] ^= t;
		c = 61444 - x[offset +  176]; t = (x[offset +  176] ^ x[offset +  304]) & (c >> 31); x[offset +  176] ^= t; x[offset +  304] ^= t;
		c = 61444 - x[offset +  112]; t = (x[offset +  112] ^ x[offset +  368]) & (c >> 31); x[offset +  112] ^= t; x[offset +  368] ^= t;
		c = 61444 - x[offset +  240]; t = (x[offset +  240] ^ x[offset +  496]) & (c >> 31); x[offset +  240] ^= t; x[offset +  496] ^= t;
		c = 61444 - x[offset +  240]; t = (x[offset +  240] ^ x[offset +  368]) & (c >> 31); x[offset +  240] ^= t; x[offset +  368] ^= t;
		c = 61444 - x[offset +  112]; t = (x[offset +  112] ^ x[offset +  176]) & (c >> 31); x[offset +  112] ^= t; x[offset +  176] ^= t;
		c = 61444 - x[offset +  240]; t = (x[offset +  240] ^ x[offset +  304]) & (c >> 31); x[offset +  240] ^= t; x[offset +  304] ^= t;
		c = 61444 - x[offset +  368]; t = (x[offset +  368] ^ x[offset +  432]) & (c >> 31); x[offset +  368] ^= t; x[offset +  432] ^= t;
		c = 61444 - x[offset +   48]; t = (x[offset +   48] ^ x[offset +   80]) & (c >> 31); x[offset +   48] ^= t; x[offset +   80] ^= t;
		c = 61444 - x[offset +  112]; t = (x[offset +  112] ^ x[offset +  144]) & (c >> 31); x[offset +  112] ^= t; x[offset +  144] ^= t;
		c = 61444 - x[offset +  176]; t = (x[offset +  176] ^ x[offset +  208]) & (c >> 31); x[offset +  176] ^= t; x[offset +  208] ^= t;
		c = 61444 - x[offset +  240]; t = (x[offset +  240] ^ x[offset +  272]) & (c >> 31); x[offset +  240] ^= t; x[offset +  272] ^= t;
		c = 61444 - x[offset +  304]; t = (x[offset +  304] ^ x[offset +  336]) & (c >> 31); x[offset +  304] ^= t; x[offset +  336] ^= t;
		c = 61444 - x[offset +  368]; t = (x[offset +  368] ^ x[offset +  400]) & (c >> 31); x[offset +  368] ^= t; x[offset +  400] ^= t;
		c = 61444 - x[offset +  432]; t = (x[offset +  432] ^ x[offset +  464]) & (c >> 31); x[offset +  432] ^= t; x[offset +  464] ^= t;
		c = 61444 - x[offset +   16]; t = (x[offset +   16] ^ x[offset +   32]) & (c >> 31); x[offset +   16] ^= t; x[offset +   32] ^= t;
		c = 61444 - x[offset +   48]; t = (x[offset +   48] ^ x[offset +   64]) & (c >> 31); x[offset +   48] ^= t; x[offset +   64] ^= t;
		c = 61444 - x[offset +   80]; t = (x[offset +   80] ^ x[offset +   96]) & (c >> 31); x[offset +   80] ^= t; x[offset +   96] ^= t;
		c = 61444 - x[offset +  112]; t = (x[offset +  112] ^ x[offset +  128]) & (c >> 31); x[offset +  112] ^= t; x[offset +  128] ^= t;
		c = 61444 - x[offset +  144]; t = (x[offset +  144] ^ x[offset +  160]) & (c >> 31); x[offset +  144] ^= t; x[offset +  160] ^= t;
		c = 61444 - x[offset +  176]; t = (x[offset +  176] ^ x[offset +  192]) & (c >> 31); x[offset +  176] ^= t; x[offset +  192] ^= t;
		c = 61444 - x[offset +  208]; t = (x[offset +  208] ^ x[offset +  224]) & (c >> 31); x[offset +  208] ^= t; x[offset +  224] ^= t;
		c = 61444 - x[offset +  240]; t = (x[offset +  240] ^ x[offset +  256]) & (c >> 31); x[offset +  240] ^= t; x[offset +  256] ^= t;
		c = 61444 - x[offset +  272]; t = (x[offset +  272] ^ x[offset +  288]) & (c >> 31); x[offset +  272] ^= t; x[offset +  288] ^= t;
		c = 61444 - x[offset +  304]; t = (x[offset +  304] ^ x[offset +  320]) & (c >> 31); x[offset +  304] ^= t; x[offset +  320] ^= t;
		c = 61444 - x[offset +  336]; t = (x[offset +  336] ^ x[offset +  352]) & (c >> 31); x[offset +  336] ^= t; x[offset +  352] ^= t;
		c = 61444 - x[offset +  368]; t = (x[offset +  368] ^ x[offset +  384]) & (c >> 31); x[offset +  368] ^= t; x[offset +  384] ^= t;
		c = 61444 - x[offset +  400]; t = (x[offset +  400] ^ x[offset +  416]) & (c >> 31); x[offset +  400] ^= t; x[offset +  416] ^= t;
		c = 61444 - x[offset +  432]; t = (x[offset +  432] ^ x[offset +  448]) & (c >> 31); x[offset +  432] ^= t; x[offset +  448] ^= t;
		c = 61444 - x[offset +  464]; t = (x[offset +  464] ^ x[offset +  480]) & (c >> 31); x[offset +  464] ^= t; x[offset +  480] ^= t;
		c = 61444 - x[offset +  512]; t = (x[offset +  512] ^ x[offset +  528]) & (c >> 31); x[offset +  512] ^= t; x[offset +  528] ^= t;
		c = 61444 - x[offset +  544]; t = (x[offset +  544] ^ x[offset +  560]) & (c >> 31); x[offset +  544] ^= t; x[offset +  560] ^= t;
		c = 61444 - x[offset +  512]; t = (x[offset +  512] ^ x[offset +  544]) & (c >> 31); x[offset +  512] ^= t; x[offset +  544] ^= t;
		c = 61444 - x[offset +  528]; t = (x[offset +  528] ^ x[offset +  560]) & (c >> 31); x[offset +  528] ^= t; x[offset +  560] ^= t;
		c = 61444 - x[offset +  528]; t = (x[offset +  528] ^ x[offset +  544]) & (c >> 31); x[offset +  528] ^= t; x[offset +  544] ^= t;
		c = 61444 - x[offset +  576]; t = (x[offset +  576] ^ x[offset +  592]) & (c >> 31); x[offset +  576] ^= t; x[offset +  592] ^= t;
		c = 61444 - x[offset +  608]; t = (x[offset +  608] ^ x[offset +  624]) & (c >> 31); x[offset +  608] ^= t; x[offset +  624] ^= t;
		c = 61444 - x[offset +  576]; t = (x[offset +  576] ^ x[offset +  608]) & (c >> 31); x[offset +  576] ^= t; x[offset +  608] ^= t;
		c = 61444 - x[offset +  592]; t = (x[offset +  592] ^ x[offset +  624]) & (c >> 31); x[offset +  592] ^= t; x[offset +  624] ^= t;
		c = 61444 - x[offset +  592]; t = (x[offset +  592] ^ x[offset +  608]) & (c >> 31); x[offset +  592] ^= t; x[offset +  608] ^= t;
		c = 61444 - x[offset +  512]; t = (x[offset +  512] ^ x[offset +  576]) & (c >> 31); x[offset +  512] ^= t; x[offset +  576] ^= t;
		c = 61444 - x[offset +  544]; t = (x[offset +  544] ^ x[offset +  608]) & (c >> 31); x[offset +  544] ^= t; x[offset +  608] ^= t;
		c = 61444 - x[offset +  544]; t = (x[offset +  544] ^ x[offset +  576]) & (c >> 31); x[offset +  544] ^= t; x[offset +  576] ^= t;
		c = 61444 - x[offset +  528]; t = (x[offset +  528] ^ x[offset +  592]) & (c >> 31); x[offset +  528] ^= t; x[offset +  592] ^= t;
		c = 61444 - x[offset +  560]; t = (x[offset +  560] ^ x[offset +  624]) & (c >> 31); x[offset +  560] ^= t; x[offset +  624] ^= t;
		c = 61444 - x[offset +  560]; t = (x[offset +  560] ^ x[offset +  592]) & (c >> 31); x[offset +  560] ^= t; x[offset +  592] ^= t;
		c = 61444 - x[offset +  528]; t = (x[offset +  528] ^ x[offset +  544]) & (c >> 31); x[offset +  528] ^= t; x[offset +  544] ^= t;
		c = 61444 - x[offset +  560]; t = (x[offset +  560] ^ x[offset +  576]) & (c >> 31); x[offset +  560] ^= t; x[offset +  576] ^= t;
		c = 61444 - x[offset +  592]; t = (x[offset +  592] ^ x[offset +  608]) & (c >> 31); x[offset +  592] ^= t; x[offset +  608] ^= t;
		c = 61444 - x[offset +  640]; t = (x[offset +  640] ^ x[offset +  656]) & (c >> 31); x[offset +  640] ^= t; x[offset +  656] ^= t;
		c = 61444 - x[offset +  672]; t = (x[offset +  672] ^ x[offset +  688]) & (c >> 31); x[offset +  672] ^= t; x[offset +  688] ^= t;
		c = 61444 - x[offset +  640]; t = (x[offset +  640] ^ x[offset +  672]) & (c >> 31); x[offset +  640] ^= t; x[offset +  672] ^= t;
		c = 61444 - x[offset +  656]; t = (x[offset +  656] ^ x[offset +  688]) & (c >> 31); x[offset +  656] ^= t; x[offset +  688] ^= t;
		c = 61444 - x[offset +  656]; t = (x[offset +  656] ^ x[offset +  672]) & (c >> 31); x[offset +  656] ^= t; x[offset +  672] ^= t;
		c = 61444 - x[offset +  704]; t = (x[offset +  704] ^ x[offset +  720]) & (c >> 31); x[offset +  704] ^= t; x[offset +  720] ^= t;
		c = 61444 - x[offset +  736]; t = (x[offset +  736] ^ x[offset +  752]) & (c >> 31); x[offset +  736] ^= t; x[offset +  752] ^= t;
		c = 61444 - x[offset +  704]; t = (x[offset +  704] ^ x[offset +  736]) & (c >> 31); x[offset +  704] ^= t; x[offset +  736] ^= t;
		c = 61444 - x[offset +  720]; t = (x[offset +  720] ^ x[offset +  752]) & (c >> 31); x[offset +  720] ^= t; x[offset +  752] ^= t;
		c = 61444 - x[offset +  720]; t = (x[offset +  720] ^ x[offset +  736]) & (c >> 31); x[offset +  720] ^= t; x[offset +  736] ^= t;
		c = 61444 - x[offset +  640]; t = (x[offset +  640] ^ x[offset +  704]) & (c >> 31); x[offset +  640] ^= t; x[offset +  704] ^= t;
		c = 61444 - x[offset +  672]; t = (x[offset +  672] ^ x[offset +  736]) & (c >> 31); x[offset +  672] ^= t; x[offset +  736] ^= t;
		c = 61444 - x[offset +  672]; t = (x[offset +  672] ^ x[offset +  704]) & (c >> 31); x[offset +  672] ^= t; x[offset +  704] ^= t;
		c = 61444 - x[offset +  656]; t = (x[offset +  656] ^ x[offset +  720]) & (c >> 31); x[offset +  656] ^= t; x[offset +  720] ^= t;
		c = 61444 - x[offset +  688]; t = (x[offset +  688] ^ x[offset +  752]) & (c >> 31); x[offset +  688] ^= t; x[offset +  752] ^= t;
		c = 61444 - x[offset +  688]; t = (x[offset +  688] ^ x[offset +  720]) & (c >> 31); x[offset +  688] ^= t; x[offset +  720] ^= t;
		c = 61444 - x[offset +  656]; t = (x[offset +  656] ^ x[offset +  672]) & (c >> 31); x[offset +  656] ^= t; x[offset +  672] ^= t;
		c = 61444 - x[offset +  688]; t = (x[offset +  688] ^ x[offset +  704]) & (c >> 31); x[offset +  688] ^= t; x[offset +  704] ^= t;
		c = 61444 - x[offset +  720]; t = (x[offset +  720] ^ x[offset +  736]) & (c >> 31); x[offset +  720] ^= t; x[offset +  736] ^= t;
		c = 61444 - x[offset +  512]; t = (x[offset +  512] ^ x[offset +  640]) & (c >> 31); x[offset +  512] ^= t; x[offset +  640] ^= t;
		c = 61444 - x[offset +  576]; t = (x[offset +  576] ^ x[offset +  704]) & (c >> 31); x[offset +  576] ^= t; x[offset +  704] ^= t;
		c = 61444 - x[offset +  576]; t = (x[offset +  576] ^ x[offset +  640]) & (c >> 31); x[offset +  576] ^= t; x[offset +  640] ^= t;
