public static int setupSI( byte[] key1, byte[] key2, byte[] keyENC, String[] listOfKeyword, Multimap<String, String> lookup, Multimap<String, String> encryptedIdToRealId) throws InvalidKeyException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException, IOException { int globalCounter = 0; for (String word : listOfKeyword) { // Computation of the keyword tag byte[] tag1 = CryptoPrimitives.generateCmac(key1, word); byte[] tag2 = CryptoPrimitives.generateCmac(key2, word); // Extraction of all documents identifiers associated to the word Collection<String> documents = lookup.get(word); int counter = 0; // initialize beta to be equal to zero int beta = 1; for (String id : documents) { // Compute the hash of the tag alongside with the counter byte[] hmac = CryptoPrimitives.concat( CryptoPrimitives.generateHmac512( keyHMACSI, Integer.toString( CryptoPrimitives.getIntFromByte( CryptoPrimitives.generateCmac(tag1, Integer.toString(counter)), 128))), CryptoPrimitives.generateHmac512( keyHMACSI, Integer.toString( CryptoPrimitives.getIntFromByte( CryptoPrimitives.generateCmac(tag2, Integer.toString(counter)), 128)))); // Determine the needed number of bytes for the bucket // Divide the result of the hash in three different values int numberOfBytes = (int) Math.ceil((Math.log(bucketSize) / (Math.log(2) * 8))); byte[] bucket = new byte[numberOfBytes]; byte[] labelAndValue = new byte[securityParameter + valueSize]; System.arraycopy(hmac, 0, bucket, 0, bucket.length); System.arraycopy(hmac, bucket.length, labelAndValue, 0, labelAndValue.length); if (free.get( CryptoPrimitives.getIntFromByte( bucket, (int) (Math.log(bucketSize) / (Math.log(2))))) .isEmpty()) { System.out.println("Sub-Buckets are not big enough ==> re-do the process with a new key"); System.exit(0); } // generate the integer which is associated to free[b] byte[] randomBytes = CryptoPrimitives.randomBytes( (int) Math.ceil( (Math.log( free.get( CryptoPrimitives.getIntFromByte( bucket, (int) (Math.log(bucketSize) / (Math.log(2))))) .size()) / (Math.log(2) * 8)))); int position = CryptoPrimitives.getIntFromByte( randomBytes, (int) Math.ceil( Math.log( free.get( CryptoPrimitives.getIntFromByte( bucket, (int) (Math.log(bucketSize) / (Math.log(2))))) .size()) / Math.log(2))); while (position >= free.get( CryptoPrimitives.getIntFromByte( bucket, (int) (Math.log(bucketSize) / (Math.log(2))))) .size()) { position = position / 2; } int valueOfSubBucket = free.get( CryptoPrimitives.getIntFromByte( bucket, (int) (Math.log(bucketSize) / (Math.log(2))))) .get(position); free.get( CryptoPrimitives.getIntFromByte( bucket, (int) (Math.log(bucketSize) / (Math.log(2))))) .remove(position); // The last document if (counter == documents.size() - 1) { beta = 0; } byte[] label = new byte[securityParameter]; byte[] value = new byte[valueSize]; System.arraycopy(labelAndValue, 0, label, 0, label.length); System.arraycopy(labelAndValue, label.length, value, 0, value.length); secureIndex .get( CryptoPrimitives.getIntFromByte( bucket, (int) (Math.log(bucketSize) / (Math.log(2))))) .get(valueOfSubBucket) .setLabel(label); // Computation of masked value Iterator<String> itr = encryptedIdToRealId.get(id).iterator(); byte[] identifierBytes = CryptoPrimitives.encryptAES_CTR_String( keyENC, CryptoPrimitives.randomBytes(16), itr.next(), 60); byte[] identifierBF = new byte[10]; String idBF = Integer.toString(globalCounter); while (idBF.length() < 10) { idBF = "0" + idBF; } for (int h = 0; h < 10; h++) { identifierBF[h] = (byte) idBF.charAt(h); } byte[] betaByte = {(byte) beta}; byte[] concatenation = CryptoPrimitives.concat(betaByte, identifierBytes); concatenation = CryptoPrimitives.concat(concatenation, identifierBF); int k = 0; for (byte b : value) { value[k] = (byte) (b ^ concatenation[k++]); } secureIndex .get( CryptoPrimitives.getIntFromByte( bucket, (int) (Math.log(bucketSize) / (Math.log(2))))) .get(valueOfSubBucket) .setValue(value); counter++; globalCounter++; } } return 1; }
public static List<InvertedIndexResultFormat> testSI( byte[] token1, byte[] token2, List<List<Record>> secureIndex, int bucketSize) throws InvalidKeyException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException, IOException { List<InvertedIndexResultFormat> result = new ArrayList<InvertedIndexResultFormat>(); // initialize beta to 1 int beta = 1; // initialize the counter to 0 int counter = 0; int numberOfBytes = (int) Math.ceil((Math.log(bucketSize) / (Math.log(2) * 8))); // security parameter in bytes defines the label while the value size defines the concatenation // of the beta, the identifier of the document and the pointer to the bloom filter int securityParameter = 16; int valueSize = 87; while (beta != 0) { // Generate the HMAC based for each identifier byte[] hmac = CryptoPrimitives.concat( CryptoPrimitives.generateHmac512( keyHMACSI, Integer.toString( CryptoPrimitives.getIntFromByte( CryptoPrimitives.generateCmac(token1, Integer.toString(counter)), 128))), CryptoPrimitives.generateHmac512( keyHMACSI, Integer.toString( CryptoPrimitives.getIntFromByte( CryptoPrimitives.generateCmac(token2, Integer.toString(counter)), 128)))); // parsing the result of the random byte[] bucket = new byte[numberOfBytes]; byte[] label = new byte[securityParameter]; byte[] value = new byte[valueSize]; System.arraycopy(hmac, 0, bucket, 0, bucket.length); System.arraycopy(hmac, bucket.length, label, 0, label.length); System.arraycopy(hmac, bucket.length + label.length, value, 0, value.length); int counterWorNotExist = 0; boolean flag2 = false; for (Record record : secureIndex.get( CryptoPrimitives.getIntFromByte( bucket, (int) (Math.log(bucketSize) / (Math.log(2)))))) { if (Arrays.equals(record.getLabel(), label)) { flag2 = true; // De-masking the value int k = 0; for (byte b : value) { value[k] = (byte) (b ^ record.getValue()[k++]); } // Spliting the array "value" to FLAG + TITLE + BF IDENTIFIER byte[] flagByte = new byte[1]; byte[] docId = new byte[76]; byte[] bFId = new byte[10]; System.arraycopy(value, 0, flagByte, 0, flagByte.length); System.arraycopy(value, flagByte.length, docId, 0, docId.length); System.arraycopy(value, flagByte.length + docId.length, bFId, 0, bFId.length); // instantiation of the record encoding String valueMatch = ""; for (int s = 0; s < value.length; s++) { valueMatch = valueMatch + (char) value[s]; } // checking if it is the last identifier if (String.valueOf(flagByte[0]).charAt(0) == '0') { beta = 0; } // return the string of the identifier and the bloom filter result.add(new InvertedIndexResultFormat(docId, bFId)); } else if ((counterWorNotExist == secureIndex .get( CryptoPrimitives.getIntFromByte( bucket, (int) (Math.log(bucketSize) / (Math.log(2))))) .size() - 1) && (flag2 == false)) { // the word searched for does not exists beta = 0; } counterWorNotExist++; } counter++; } return result; }