private byte[] updateMac(KeccakDigest mac, byte[] seed, int offset, byte[] out, int outOffset, boolean egress) throws IOException { byte[] aesBlock = new byte[mac.getDigestSize()]; doSum(mac, aesBlock); makeMacCipher().processBlock(aesBlock, 0, aesBlock, 0); // Note that although the mac digest size is 32 bytes, we only use 16 bytes in the computation int length = 16; for (int i = 0; i < length; i++) { aesBlock[i] ^= seed[i + offset]; } mac.update(aesBlock, 0, length); byte[] result = new byte[mac.getDigestSize()]; doSum(mac, result); if (egress) { System.arraycopy(result, 0, out, outOffset, length); } else { for (int i = 0; i < length; i++) { if (out[i + outOffset] != result[i]) { throw new IOException("MAC mismatch"); } } } return result; }
/** * Create a final key from the parameters passed */ public static byte[] getFinalKeyDigest(byte[] key, byte[] masterSeed, byte[] transformSeed, long transformRounds) { AESEngine engine = new AESEngine(); engine.init(true, new KeyParameter(transformSeed)); // copy input key byte[] transformedKey = new byte[key.length]; System.arraycopy(key, 0, transformedKey, 0, transformedKey.length); // transform rounds times for (long rounds = 0; rounds < transformRounds; rounds++) { engine.processBlock(transformedKey, 0, transformedKey, 0); engine.processBlock(transformedKey, 16, transformedKey, 16); } MessageDigest md = getMessageDigestInstance(); byte[] transformedKeyDigest = md.digest(transformedKey); md.update(masterSeed); return md.digest(transformedKeyDigest); }
byte[] encryptedHalf1 = new byte[16]; byte[] encryptedHalf2 = new byte[16]; cipher.processBlock(xor, 0, encryptedHalf1, 0); cipher.processBlock(xor, 16, encryptedHalf2, 0); byte[] result = new byte[43]; result[0] = 1;
byte[] encryptedHalf1 = new byte[16]; byte[] encryptedHalf2 = new byte[16]; cipher.processBlock(seedB, 0, encryptedHalf1, 0); byte[] secondBlock = new byte[16]; System.arraycopy(encryptedHalf1, 8, secondBlock, 0, 8); secondBlock[i] ^= derived[i + 16]; cipher.processBlock(secondBlock, 0, encryptedHalf2, 0); ByteArrayOutputStream baos = new ByteArrayOutputStream(); baos.write(0x01); pointB[i + 1] ^= derived[i]; cipher.processBlock(pointB, 1, encryptedPointB, 1); cipher.processBlock(pointB, 17, encryptedPointB, 17); baos.reset(); baos.write(0x64);
cipher.init(false, new KeyParameter(key)); byte[] secret = new byte[32]; cipher.processBlock(encryptedSecret, 0, secret, 0); cipher.processBlock(encryptedSecret, 16, secret, 16); for (int i = 0; i < 32; i++) { secret[i] ^= passwordDerived[i]; cipher.init(false, new KeyParameter(key)); byte[] decryptedHalf2 = new byte[16]; cipher.processBlock(encryptedPrivateKeyBytes, 23, decryptedHalf2, 0); for (int i = 0; i < 16; i++) { decryptedHalf2[i] ^= derived[i + 16]; System.arraycopy(decryptedHalf2, 0, encryptedHalf1, 8, 8); byte[] decryptedHalf1 = new byte[16]; cipher.processBlock(encryptedHalf1, 0, decryptedHalf1, 0); for (int i = 0; i < 16; i++) { decryptedHalf1[i] ^= derived[i];
cipher.processBlock(encryptedPointB, 1, pointB, 1); cipher.processBlock(encryptedPointB, 17, pointB, 17);