public Base() { super(new Salsa20Engine(), 8); } }
public void reset() { index = 0; resetLimitCounter(); resetCounter(); generateKeyStream(keyStream); }
public byte returnByte(byte in) { if (limitExceeded()) { throw new MaxBytesExceededException("2^70 byte limit per IV; Change IV"); } byte out = (byte)(keyStream[index]^in); index = (index + 1) & 63; if (index == 0) { advanceCounter(); generateKeyStream(keyStream); } return out; }
advanceCounter(count); advanceCounter(); retreatCounter(count); retreatCounter(); generateKeyStream(keyStream);
/** * Creates a Salsa20 engine * * @param key the key to use * @return an initialized Salsa20 engine */ @SuppressWarnings("WeakerAccess") public static Salsa20Engine createSalsa20(byte[] key) { MessageDigest md = Encryption.getMessageDigestInstance(); KeyParameter keyParameter = new KeyParameter(md.digest(key)); ParametersWithIV ivParameter = new ParametersWithIV(keyParameter, SALSA20_IV); Salsa20Engine engine = new Salsa20Engine(); engine.init(true, ivParameter); return engine; }
throw new IllegalStateException(getAlgorithmName() + " not initialised"); if (limitExceeded(len)) advanceCounter(); generateKeyStream(keyStream);
throw new IllegalArgumentException(getAlgorithmName() + " Init parameters must include an IV"); if (iv == null || iv.length != getNonceSize()) throw new IllegalArgumentException(getAlgorithmName() + " requires exactly " + getNonceSize() + " bytes of IV"); throw new IllegalStateException(getAlgorithmName() + " KeyParameter can not be null for first initialisation"); setKey(null, iv); setKey(((KeyParameter)keyParam).getKey(), iv); throw new IllegalArgumentException(getAlgorithmName() + " Init parameters must contain a KeyParameter (or null for re-init)"); reset();
throw new IllegalStateException(getAlgorithmName()+" not initialised"); if (limitExceeded(len)) generateKeyStream(keyStream);
private void generateKeyStream(byte[] output) { salsaCore(20, engineState, x); Pack.intToLittleEndian(x, output, 0); }
public byte returnByte(byte in) { if (limitExceeded()) { throw new MaxBytesExceededException("2^70 byte limit per IV; Change IV"); } if (index == 0) { generateKeyStream(keyStream); if (++engineState[8] == 0) { ++engineState[9]; } } byte out = (byte)(keyStream[index]^in); index = (index + 1) & 63; return out; }
@Override public byte[] encrypt(byte[] decryptedText) { byte[] output = new byte[decryptedText.length]; salsa20.processBytes(decryptedText, 0, decryptedText.length, output, 0); return output; } }
public void reset() { setKey(workingKey, workingIV); }
x[ 4] ^= rotl((x[ 0]+x[12]), 7); x[ 8] ^= rotl((x[ 4]+x[ 0]), 9); x[12] ^= rotl((x[ 8]+x[ 4]),13); x[ 0] ^= rotl((x[12]+x[ 8]),18); x[ 9] ^= rotl((x[ 5]+x[ 1]), 7); x[13] ^= rotl((x[ 9]+x[ 5]), 9); x[ 1] ^= rotl((x[13]+x[ 9]),13); x[ 5] ^= rotl((x[ 1]+x[13]),18); x[14] ^= rotl((x[10]+x[ 6]), 7); x[ 2] ^= rotl((x[14]+x[10]), 9); x[ 6] ^= rotl((x[ 2]+x[14]),13); x[10] ^= rotl((x[ 6]+x[ 2]),18); x[ 3] ^= rotl((x[15]+x[11]), 7); x[ 7] ^= rotl((x[ 3]+x[15]), 9); x[11] ^= rotl((x[ 7]+x[ 3]),13); x[15] ^= rotl((x[11]+x[ 7]),18); x[ 1] ^= rotl((x[ 0]+x[ 3]), 7); x[ 2] ^= rotl((x[ 1]+x[ 0]), 9); x[ 3] ^= rotl((x[ 2]+x[ 1]),13); x[ 0] ^= rotl((x[ 3]+x[ 2]),18); x[ 6] ^= rotl((x[ 5]+x[ 4]), 7); x[ 7] ^= rotl((x[ 6]+x[ 5]), 9); x[ 4] ^= rotl((x[ 7]+x[ 6]),13); x[ 5] ^= rotl((x[ 4]+x[ 7]),18); x[11] ^= rotl((x[10]+x[ 9]), 7); x[ 8] ^= rotl((x[11]+x[10]), 9); x[ 9] ^= rotl((x[ 8]+x[11]),13); x[10] ^= rotl((x[ 9]+x[ 8]),18); x[12] ^= rotl((x[15]+x[14]), 7);
protected void setKey(byte[] keyBytes, byte[] ivBytes) { if (keyBytes != null) { if ((keyBytes.length != 16) && (keyBytes.length != 32)) { throw new IllegalArgumentException(getAlgorithmName() + " requires 128 bit or 256 bit key"); } int tsOff = (keyBytes.length - 16) / 4; engineState[0 ] = TAU_SIGMA[tsOff ]; engineState[5 ] = TAU_SIGMA[tsOff + 1]; engineState[10] = TAU_SIGMA[tsOff + 2]; engineState[15] = TAU_SIGMA[tsOff + 3]; // Key Pack.littleEndianToInt(keyBytes, 0, engineState, 1, 4); Pack.littleEndianToInt(keyBytes, keyBytes.length - 16, engineState, 11, 4); } // IV Pack.littleEndianToInt(ivBytes, 0, engineState, 6, 2); }
resetCounter(); int offset = 0; byte[] constants;
private void initialize(byte[] protectedStreamKey) { byte[] salsaKey = Sha256.hash(protectedStreamKey); try { salsa20Engine = new Salsa20Engine(); salsa20Engine.init(true, new ParametersWithIV(new KeyParameter(salsaKey), Hex.decode(SALSA20IV))); } catch (Exception e) { throw new UnsupportedOperationException("Could not find provider '" + SALSA20_ALGORITHM + "'", e); } }
protected void generateKeyStream(byte[] output) { salsaCore(rounds, engineState, x); Pack.intToLittleEndian(x, output, 0); }
@Override public byte[] decrypt(byte[] encryptedText) { byte[] output = new byte[encryptedText.length]; salsa20.processBytes(encryptedText, 0, encryptedText.length, output, 0); return output; }
workingIV = iv; setKey(workingKey, workingIV);
x04 ^= rotl(x00 + x12, 7); x08 ^= rotl(x04 + x00, 9); x12 ^= rotl(x08 + x04, 13); x00 ^= rotl(x12 + x08, 18); x09 ^= rotl(x05 + x01, 7); x13 ^= rotl(x09 + x05, 9); x01 ^= rotl(x13 + x09, 13); x05 ^= rotl(x01 + x13, 18); x14 ^= rotl(x10 + x06, 7); x02 ^= rotl(x14 + x10, 9); x06 ^= rotl(x02 + x14, 13); x10 ^= rotl(x06 + x02, 18); x03 ^= rotl(x15 + x11, 7); x07 ^= rotl(x03 + x15, 9); x11 ^= rotl(x07 + x03, 13); x15 ^= rotl(x11 + x07, 18); x01 ^= rotl(x00 + x03, 7); x02 ^= rotl(x01 + x00, 9); x03 ^= rotl(x02 + x01, 13); x00 ^= rotl(x03 + x02, 18); x06 ^= rotl(x05 + x04, 7); x07 ^= rotl(x06 + x05, 9); x04 ^= rotl(x07 + x06, 13); x05 ^= rotl(x04 + x07, 18); x11 ^= rotl(x10 + x09, 7); x08 ^= rotl(x11 + x10, 9); x09 ^= rotl(x08 + x11, 13); x10 ^= rotl(x09 + x08, 18);