├── .gitignore ├── include ├── ORAM.h ├── PartitionORAMInstance.h ├── Config.h ├── RecursiveTPPartitionORAMInstance.h ├── IBSOS.h ├── PathORAM.h ├── BinaryORAM.h ├── TPPartitionORAMInstance.h ├── Util.h ├── RecursivePathORAM.h ├── RecursiveBinaryORAM.h ├── ServerConnector.h ├── SRORAM.h ├── MongoConnector.h ├── PartitionORAM.h └── RecursivePartitionORAM.h ├── README.md ├── src ├── Util.cpp ├── PathORAM.cpp ├── IBSOS.cpp ├── RecursivePathORAM.cpp ├── MongoConnector.cpp ├── TPPartitionORAMInstance.cpp ├── RecursiveTPPartitionORAMInstance.cpp ├── BinaryORAM.cpp ├── RecursiveBinaryORAM.cpp └── SRORAM.cpp ├── IBSOS_main.cpp ├── PathORAM_main.cpp ├── BinaryORAM_main.cpp ├── SRORAM_main.cpp ├── RecursivePathORAM_main.cpp ├── RecursiveBinaryORAM_main.cpp ├── TPORAM_main.cpp ├── RecursiveTPORAM_main.cpp ├── CMakeLists.txt └── LICENSE /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | IBSOS_main 3 | TPORAM_main 4 | PathORAM_main 5 | BinaryORAM_main 6 | SRORAM_main 7 | HRORAM_main 8 | RecursivePathORAM_main 9 | RecursiveBinaryORAM_main 10 | RecursiveTPORAM_main 11 | CMakeFiles 12 | Makefile 13 | cmake_install.cmake 14 | CMakeCache.txt 15 | *.exe 16 | -------------------------------------------------------------------------------- /include/ORAM.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 by SEAL-ORAM Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | // 18 | // Created by Dong Xie on 7/6/2016. 19 | // 20 | 21 | #ifndef SEAL_ORAM_ORAM_H 22 | #define SEAL_ORAM_ORAM_H 23 | 24 | #include 25 | 26 | class ORAM { 27 | public: 28 | ORAM() {} 29 | virtual ~ORAM() {} 30 | 31 | virtual std::string get(const std::string & key) = 0; 32 | virtual void put(const std::string & key, const std::string & value) = 0; 33 | 34 | 35 | virtual std::string get(const uint32_t & key) = 0; 36 | virtual void put(const uint32_t & key, const std::string & value) = 0; 37 | }; 38 | 39 | #endif //SEAL_ORAM_ORAM_H 40 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # README 2 | This is a unified testbed for evaluating different Oblivious RAM schemes. Specifically, we have implemented the following ORAM schemes: 3 | 4 | - [Basic Square Root](http://dl.acm.org/citation.cfm?id=28416) 5 | - [IBS OS](http://www.cs.utah.edu/~dongx/paper/psp-icde.pdf) 6 | - [Towards Practical Oblivious RAM](http://arxiv.org/pdf/1106.3652.pdf) 7 | - [Binary Tree ORAM](https://eprint.iacr.org/2011/407.pdf) 8 | - [Path ORAM](https://people.csail.mit.edu/devadas/pubs/PathORam.pdf) 9 | 10 | **Note:** We also implemented recursive construction for TPORAM, Path ORAM and Binary Tree ORAM. 11 | 12 | *More schemes is now being integrating into this testbed....* 13 | 14 | ## Dependencies 15 | To compile this project, the following libraries and enviroments are required: 16 | 17 | - g++ 4.8+ 18 | - cryptopp 5.6.3+ 19 | - boost 1.56+ 20 | - mongo cxx legacy driver 1.10+ 21 | 22 | **Note:** Please make sure that all libraries are accessible directly by the complier, which typically means they are installed under `/usr` or `/usr/local`. 23 | 24 | ## Build 25 | Do `cmake .` first, then `make` and enjoy! 26 | 27 | ## Contacts 28 | Dong Xie: dongx [at] cs [dot] utah [dot] edu 29 | Zhao Chang: zchang [at] cs [dot] utah [dot] edu 30 | Feifei Li: lifeifei [at] cs [dot] utah [dot] edu 31 | -------------------------------------------------------------------------------- /include/PartitionORAMInstance.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 by SEAL-ORAM Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | // 18 | // Created by Dong Xie on 7/13/2016. 19 | // 20 | 21 | #ifndef SEAL_ORAM_PARTITIONORAMINSTANCE_H 22 | #define SEAL_ORAM_PARTITIONORAMINSTANCE_H 23 | 24 | #include 25 | 26 | struct Position { 27 | uint32_t part; 28 | int32_t level; 29 | int32_t offset; 30 | }; 31 | 32 | class PartitionORAMInstance { 33 | public: 34 | PartitionORAMInstance() {} 35 | virtual ~PartitionORAMInstance() {} 36 | 37 | virtual std::string get(const int32_t& key) = 0; 38 | virtual void put(const int32_t& key, const std::string& data) = 0; 39 | }; 40 | 41 | #endif //SEAL_ORAM_PARTITIONORAMINSTANCE_H 42 | -------------------------------------------------------------------------------- /include/Config.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 by SEAL-ORAM Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | // 18 | // Created by Dong Xie on 7/6/2016. 19 | // 20 | 21 | #ifndef SEAL_ORAM_CONFIG_H 22 | #define SEAL_ORAM_CONFIG_H 23 | 24 | #include 25 | #include 26 | 27 | const uint32_t B = 4096; 28 | const std::string server_host = "localhost"; 29 | 30 | /* The basic binary tree ORAM */ 31 | const uint32_t Gamma = 2; //The eviction rate 32 | const uint32_t Alpha = 2; //The ratio of the size of each bucket to log N 33 | 34 | /* Path ORAM */ 35 | const uint32_t PathORAM_Z = 4; 36 | 37 | /* TP-ORAM */ 38 | const double R = 0.9; 39 | const double capacity_parameter = 4.6; 40 | const double small_capacity_parameter = 6.0; 41 | /* # of partitions can be modified in PartitionORAM.h */ 42 | 43 | #endif //SEAL_ORAM_CONFIG_H 44 | -------------------------------------------------------------------------------- /include/RecursiveTPPartitionORAMInstance.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Dong Xie on 7/16/2016. 3 | // 4 | 5 | #ifndef SEAL_ORAM_RECURSIVETPPARTITIONORAMINSTANCE_H 6 | #define SEAL_ORAM_RECURSIVETPPARTITIONORAMINSTANCE_H 7 | 8 | #include 9 | #include 10 | #include 11 | #include "Config.h" 12 | #include "ServerConnector.h" 13 | #include "PartitionORAMInstance.h" 14 | #include "MongoConnector.h" 15 | #include "PartitionORAM.h" 16 | 17 | class RecursiveTPPartitionORAMInstance: public PartitionORAMInstance { 18 | public: 19 | RecursiveTPPartitionORAMInstance(const uint32_t& numofReals, size_t& real_ind, const uint32_t& PID, 20 | std::string* sbuffer, ORAM* p_map, MongoConnector * Conn); 21 | virtual ~RecursiveTPPartitionORAMInstance(); 22 | 23 | virtual std::string get(const int32_t& block_id); 24 | virtual void put(const int32_t& block_id, const std::string& data); 25 | private: 26 | std::string readBlock(uint32_t level, uint32_t offset); 27 | 28 | void fetchLevel(uint32_t level, std::string* sbuffer, uint32_t beginIndex, size_t & length); 29 | void loadLevel(uint32_t level, std::string * sbuffer, size_t length, bool insert); 30 | 31 | void updatePosMap(const uint32_t& id, const uint32_t& part, const uint32_t& level, const uint32_t& offset); 32 | void getPosMap(const uint32_t& id, uint32_t& part, uint32_t& level, uint32_t& offset); 33 | 34 | uint32_t n_levels; 35 | uint32_t top_level_len; 36 | uint32_t capacity; 37 | uint32_t PID; 38 | uint32_t pos_base = (B - Util::aes_block_size - 2 * sizeof(uint32_t)) / (3 * sizeof(uint32_t)); 39 | 40 | uint32_t* dummy; 41 | byte* key; 42 | std::string* sbuffer; 43 | bool* filled; 44 | size_t counter; 45 | ORAM* pos_map; 46 | 47 | MongoConnector *conn; 48 | bool* flag; 49 | 50 | std::string ns; 51 | }; 52 | 53 | #endif //SEAL_ORAM_RECURSIVETPPARTITIONORAMINSTANCE_H 54 | -------------------------------------------------------------------------------- /include/IBSOS.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 by SEAL-ORAM Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | // 18 | // Created by Dong Xie on 7/6/2016. 19 | // 20 | 21 | #ifndef SEAL_ORAM_IBSOS_H 22 | #define SEAL_ORAM_IBSOS_H 23 | 24 | #include 25 | #include 26 | #include "ServerConnector.h" 27 | #include "ORAM.h" 28 | 29 | class IBSOS: public ORAM { 30 | public: 31 | IBSOS(uint32_t n, uint32_t Alpha); 32 | virtual ~IBSOS(); 33 | 34 | virtual std::string get(const std::string & key); 35 | virtual void put(const std::string & key, const std::string & value); 36 | 37 | virtual std::string get(const uint32_t & key); 38 | virtual void put(const uint32_t & key, const std::string & value); 39 | private: 40 | void IBS(); 41 | 42 | void access(const char& op, const uint32_t& block_id, std::string& data); 43 | 44 | std::string fetchBlock(int32_t block_id); 45 | 46 | uint32_t alpha; 47 | 48 | uint32_t n_blocks; 49 | uint32_t n_real; 50 | uint32_t n_cache; 51 | uint32_t dummy_counter; 52 | uint32_t op_counter; 53 | 54 | std::unordered_map stash; 55 | byte* key; 56 | std::string* sbuffer; 57 | std::string salt; 58 | std::vector< std::pair > insert_buffer; 59 | 60 | ServerConnector* conn; 61 | ServerConnector* ibs_conn; 62 | }; 63 | 64 | #endif //SEAL_ORAM_IBSOS_H 65 | -------------------------------------------------------------------------------- /include/PathORAM.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 by SEAL-ORAM Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | // 18 | // Created by Dong Xie on 7/6/2016. 19 | // 20 | 21 | #ifndef SEAL_ORAM_PATHORAM_H 22 | #define SEAL_ORAM_PATHORAM_H 23 | 24 | #include 25 | #include 26 | #include "ServerConnector.h" 27 | #include "ORAM.h" 28 | #include "Util.h" 29 | 30 | class PathORAM: public ORAM { 31 | public: 32 | PathORAM(const uint32_t& n); 33 | virtual ~PathORAM(); 34 | 35 | virtual std::string get(const std::string & key); 36 | virtual void put(const std::string & key, const std::string & value); 37 | 38 | virtual std::string get(const uint32_t & key); 39 | virtual void put(const uint32_t & key, const std::string & value); 40 | private: 41 | void access(const char& op, const uint32_t& block_id, std::string& data); 42 | bool check(int x, int y, int l); 43 | 44 | void fetchAlongPath(const uint32_t& x, std::string* sbuffer, size_t& length); 45 | void loadAlongPath(const uint32_t& x, const std::string* sbuffer, const size_t& length); 46 | 47 | std::unordered_map stash; 48 | uint32_t *pos_map; 49 | std::vector< std::pair > insert_buffer; 50 | 51 | byte* key; 52 | std::string* sbuffer; 53 | uint32_t n_blocks; 54 | uint32_t height; 55 | 56 | ServerConnector* conn; 57 | }; 58 | 59 | #endif //SEAL_ORAM_PATHORAM_H 60 | -------------------------------------------------------------------------------- /include/BinaryORAM.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 by SEAL-ORAM Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | // 18 | // Created by Dong Xie on 7/10/2016. 19 | // 20 | 21 | #ifndef SEAL_ORAM_BINARYORAM_H 22 | #define SEAL_ORAM_BINARYORAM_H 23 | 24 | #include 25 | #include 26 | #include "ServerConnector.h" 27 | #include "ORAM.h" 28 | #include "Util.h" 29 | 30 | class BinaryORAM: public ORAM { 31 | public: 32 | BinaryORAM(const uint32_t& n); 33 | virtual ~BinaryORAM(); 34 | 35 | virtual std::string get(const std::string & key); 36 | virtual void put(const std::string & key, const std::string & value); 37 | 38 | virtual std::string get(const uint32_t & key); 39 | virtual void put(const uint32_t & key, const std::string & value); 40 | private: 41 | void access(const char& op, const uint32_t& block_id, std::string& data); 42 | 43 | void readBlock(const uint32_t level, const uint32_t bucket, const uint32_t piece); 44 | void writeBlock(const uint32_t level, const uint32_t bucket, const uint32_t piece); 45 | 46 | void fetchAlongPath(const uint32_t& block_id, const uint32_t& x); 47 | void evict(const uint32_t level, const uint32_t bucket); 48 | void evict(); 49 | 50 | uint32_t *pos_map; 51 | 52 | byte* key; 53 | std::string* sbuffer; 54 | uint32_t n_buckets; //The number of buckets in the largest level 55 | uint32_t height; //The height of the binary tree 56 | uint32_t bucket_size; //The size of each bucket 57 | 58 | ServerConnector* conn; 59 | }; 60 | 61 | #endif //SEAL_ORAM_BINARYORAM_H 62 | -------------------------------------------------------------------------------- /include/TPPartitionORAMInstance.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 by SEAL-ORAM Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | // 18 | // Created by Dong Xie on 7/13/2016. 19 | // 20 | 21 | #ifndef SEAL_ORAM_TPPARTITIONORAMINSTANCE_H 22 | #define SEAL_ORAM_TPPARTITIONORAMINSTANCE_H 23 | 24 | #include 25 | #include 26 | #include 27 | #include "Config.h" 28 | #include "ServerConnector.h" 29 | #include "PartitionORAMInstance.h" 30 | #include "MongoConnector.h" 31 | 32 | class TPPartitionORAMInstance: public PartitionORAMInstance { 33 | public: 34 | TPPartitionORAMInstance(const uint32_t& numofReals, size_t& real_ind, const uint32_t& PID, std::string* sbuffer, Position* p_map, MongoConnector * Conn); 35 | virtual ~TPPartitionORAMInstance(); 36 | 37 | virtual std::string get(const int32_t& block_id); 38 | virtual void put(const int32_t& block_id, const std::string& data); 39 | 40 | private: 41 | std::string readBlock(uint32_t level, uint32_t offset); 42 | 43 | void fetchLevel(uint32_t level, std::string* sbuffer, uint32_t beginIndex, size_t & length); 44 | void loadLevel(uint32_t level, std::string * sbuffer, size_t length, bool insert); 45 | 46 | 47 | uint32_t n_levels; 48 | uint32_t top_level_len; 49 | uint32_t capacity; 50 | uint32_t PID; 51 | 52 | uint32_t* dummy; 53 | byte* key; 54 | std::string* sbuffer; 55 | bool* filled; 56 | size_t counter; 57 | Position* pos_map; 58 | 59 | MongoConnector *conn; 60 | bool* flag; 61 | 62 | std::string ns; 63 | }; 64 | 65 | #endif //SEAL_ORAM_TPPARTITIONORAMINSTANCE_H 66 | -------------------------------------------------------------------------------- /include/Util.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 by SEAL-ORAM Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | // 18 | // Created by Dong Xie on 7/6/2016. 19 | // 20 | #ifndef SEAL_ORAM_UTIL_H 21 | #define SEAL_ORAM_UTIL_H 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | using namespace CryptoPP; 29 | 30 | class Util { 31 | public: 32 | static void aes_encrypt(const std::string& plain, const byte* key, std::string& cipher); 33 | static void aes_decrypt(const std::string& cipher, const byte* key, std::string& plain); 34 | static std::string sha256_hash(const std::string& key, const std::string& salt); 35 | static std::string generate_random_block(const size_t& length); 36 | 37 | template 38 | static void psuedo_random_permute(T* items, size_t n) { 39 | for (size_t i = n - 1; i > 0; --i) { 40 | size_t j = std::uniform_int_distribution(0, i)(gen); 41 | T tmp = items[i]; 42 | items[i] = items[j]; 43 | items[j] = tmp; 44 | } 45 | } 46 | 47 | static size_t rand_int(size_t n) { 48 | return std::uniform_int_distribution(0, n - 1)(gen); 49 | //return rand() % n; 50 | } 51 | 52 | static size_t key_length; 53 | static size_t aes_block_size; 54 | static AutoSeededRandomPool prng; 55 | static CFB_Mode::Encryption encrypt_handler; 56 | static CFB_Mode::Decryption decrypt_handler; 57 | 58 | static std::random_device rd; 59 | static std::mt19937 gen; 60 | }; 61 | 62 | #endif //SEAL_ORAM_UTIL_H 63 | -------------------------------------------------------------------------------- /include/RecursivePathORAM.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 by SEAL-ORAM Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | // 18 | // Created by Dong Xie on 7/16/2016. 19 | // 20 | 21 | #ifndef SEAL_ORAM_RECURSIVEPATHORAM_H_H 22 | #define SEAL_ORAM_RECURSIVEPATHORAM_H_H 23 | 24 | #include 25 | #include 26 | #include "ServerConnector.h" 27 | #include "ORAM.h" 28 | #include "PathORAM.h" 29 | #include "Config.h" 30 | 31 | class RecursivePathORAM: public ORAM { 32 | public: 33 | RecursivePathORAM(const uint32_t& n); 34 | virtual ~RecursivePathORAM(); 35 | 36 | virtual std::string get(const std::string & key); 37 | virtual void put(const std::string & key, const std::string & value); 38 | 39 | virtual std::string get(const uint32_t & key); 40 | virtual void put(const uint32_t & key, const std::string & value); 41 | private: 42 | void access(const char& op, const uint32_t& block_id, std::string& data); 43 | bool check(int x, int y, int l); 44 | 45 | void fetchAlongPath(const uint32_t& x, std::string* sbuffer, size_t& length); 46 | void loadAlongPath(const uint32_t& x, const std::string* sbuffer, const size_t& length); 47 | 48 | uint32_t checkAndUpdatePosMap(const uint32_t& id, const uint32_t& pos); 49 | uint32_t getPosMap(const uint32_t& id); 50 | 51 | std::unordered_map stash; 52 | std::unordered_map stash_posmap; 53 | 54 | ORAM* pos_map; 55 | std::vector< std::pair > insert_buffer; 56 | 57 | byte* key; 58 | std::string* sbuffer; 59 | uint32_t n_blocks; 60 | uint32_t height; 61 | uint32_t pos_base = (B - Util::aes_block_size - 3 * sizeof(uint32_t)) / 4; 62 | 63 | ServerConnector* conn; 64 | }; 65 | 66 | 67 | #endif //SEAL_ORAM_RECURSIVEPATHORAM_H_H 68 | -------------------------------------------------------------------------------- /include/RecursiveBinaryORAM.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 by SEAL-ORAM Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | // 18 | // Created by Dong Xie on 7/16/2016. 19 | // 20 | 21 | #ifndef SEAL_ORAM_RECURSIVEBINARYORAM_H 22 | #define SEAL_ORAM_RECURSIVEBINARYORAM_H 23 | 24 | #include 25 | #include 26 | #include "ServerConnector.h" 27 | #include "ORAM.h" 28 | #include "BinaryORAM.h" 29 | #include "Config.h" 30 | 31 | class RecursiveBinaryORAM: public ORAM { 32 | public: 33 | RecursiveBinaryORAM(const uint32_t& n); 34 | virtual ~RecursiveBinaryORAM(); 35 | 36 | virtual std::string get(const std::string & key); 37 | virtual void put(const std::string & key, const std::string & value); 38 | 39 | virtual std::string get(const uint32_t & key); 40 | virtual void put(const uint32_t & key, const std::string & value); 41 | private: 42 | void access(const char& op, const uint32_t& block_id, std::string& data); 43 | 44 | void readBlock(const uint32_t level, const uint32_t bucket, const uint32_t piece); 45 | void writeBlock(const uint32_t level, const uint32_t bucket, const uint32_t piece); 46 | void fetchAlongPath(const uint32_t& block_id, const uint32_t& x); 47 | void evict(const uint32_t level, const uint32_t bucket); 48 | void evict(); 49 | 50 | uint32_t checkAndUpdatePosMap(const uint32_t& id, const uint32_t& pos); 51 | uint32_t getPosMap(const uint32_t& id); 52 | 53 | ORAM* pos_map; 54 | 55 | byte* key; 56 | std::string* sbuffer; 57 | uint32_t n_buckets; //The number of buckets in the largest level 58 | uint32_t height; //The height of the binary tree 59 | uint32_t bucket_size; //The size of each bucket 60 | uint32_t pos_base = (B - Util::aes_block_size - 3 * sizeof(uint32_t)) / 4; 61 | 62 | ServerConnector* conn; 63 | }; 64 | 65 | #endif //SEAL_ORAM_RECURSIVEBINARYORAM_H 66 | -------------------------------------------------------------------------------- /src/Util.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 by SEAL-ORAM Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | // 18 | // Created by Dong Xie on 7/6/2016. 19 | // 20 | 21 | #include "Util.h" 22 | 23 | using namespace CryptoPP; 24 | 25 | size_t Util::key_length = (size_t)AES::DEFAULT_KEYLENGTH; 26 | size_t Util::aes_block_size = (size_t)AES::BLOCKSIZE; 27 | AutoSeededRandomPool Util::prng; 28 | CFB_Mode::Encryption Util::encrypt_handler; 29 | CFB_Mode::Decryption Util::decrypt_handler; 30 | std::random_device Util::rd; 31 | std::mt19937 Util::gen(Util::rd()); 32 | 33 | void Util::aes_encrypt(const std::string& plain, const byte* key, std::string& cipher) { 34 | byte iv[aes_block_size]; 35 | encrypt_handler.GetNextIV(prng, iv); 36 | 37 | encrypt_handler.SetKeyWithIV(key, key_length, iv, aes_block_size); 38 | byte cipher_text[plain.length()]; 39 | encrypt_handler.ProcessData(cipher_text, (byte*) plain.c_str(), plain.length()); 40 | cipher = std::string((const char*)iv, aes_block_size) + std::string((const char*)cipher_text, plain.length()); 41 | } 42 | 43 | void Util::aes_decrypt(const std::string& cipher, const byte* key, std::string& plain) { 44 | decrypt_handler.SetKeyWithIV(key, key_length, (byte*)cipher.c_str(), aes_block_size); 45 | size_t cipher_length = cipher.length() - aes_block_size; 46 | byte plain_text[cipher_length]; 47 | decrypt_handler.ProcessData(plain_text, (byte*)cipher.substr(aes_block_size).c_str(), cipher_length); 48 | plain = std::string((const char*)plain_text, cipher_length); 49 | } 50 | 51 | std::string Util::sha256_hash(const std::string& key, const std::string& salt) { 52 | byte buf[SHA256::DIGESTSIZE]; 53 | SHA256().CalculateDigest(buf, (byte*) ((key + salt).c_str()), key.length() + salt.length()); 54 | return std::string((const char*)buf, (size_t)SHA256::DIGESTSIZE); 55 | } 56 | 57 | std::string Util::generate_random_block(const size_t& length) { 58 | byte buf[length]; 59 | prng.GenerateBlock(buf, length); 60 | return std::string((const char*)buf, length); 61 | } -------------------------------------------------------------------------------- /IBSOS_main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "IBSOS.h" 4 | #include "Config.h" 5 | 6 | using namespace mongo; 7 | using namespace CryptoPP; 8 | 9 | int main() { 10 | mongo::client::initialize(); 11 | 12 | srand((uint32_t)time(NULL)); 13 | 14 | uint32_t N = 1024; 15 | ORAM* oram = new IBSOS(N, 1); 16 | 17 | for(uint32_t i = 0; i < N; i ++) { 18 | char str[12]; 19 | sprintf(str, "%zu\n", (size_t)i); 20 | std::string key(str); 21 | 22 | std::string value; 23 | const uint32_t tmp_len = B - AES::BLOCKSIZE - 2 * sizeof(uint32_t); 24 | byte tmp_buffer[tmp_len]; 25 | AutoSeededRandomPool prng; 26 | prng.GenerateBlock(tmp_buffer, tmp_len); 27 | value = std::string((const char *)tmp_buffer, tmp_len); 28 | int32_t blockID = i; 29 | std::string bID = std::string((const char *)(& blockID), sizeof(uint32_t)); 30 | value = bID + value; 31 | 32 | oram->put(key, value); 33 | } 34 | 35 | size_t roundNum = 5; 36 | for(size_t r = 0; r < roundNum; r ++) { 37 | for(size_t i = 0; i < N; i ++) { 38 | char str[12]; 39 | sprintf(str, "%zu\n", i); 40 | std::string key(str); 41 | std::string block = oram->get(key); 42 | uint32_t value; 43 | memcpy((& value), block.c_str(), sizeof(uint32_t)); 44 | printf("%d ", value); 45 | } 46 | printf("\n=========================================================================\n"); 47 | } 48 | 49 | for(uint32_t i = 0; i < N; i ++) { 50 | char str[12]; 51 | sprintf(str, "%zu\n", (size_t)i); 52 | std::string key(str); 53 | 54 | std::string value; 55 | const uint32_t tmp_len = B - AES::BLOCKSIZE - 2 * sizeof(uint32_t); 56 | byte tmp_buffer[tmp_len]; 57 | AutoSeededRandomPool prng; 58 | prng.GenerateBlock(tmp_buffer, tmp_len); 59 | value = std::string((const char *)tmp_buffer, tmp_len); 60 | int32_t blockID = N - 1 - i; 61 | std::string bID = std::string((const char *)(& blockID), sizeof(uint32_t)); 62 | value = bID + value; 63 | 64 | oram->put(key, value); 65 | } 66 | 67 | for(size_t i = 0; i < N; i ++) { 68 | char str[12]; 69 | sprintf(str, "%zu\n", i); 70 | std::string key(str); 71 | std::string block = oram->get(key); 72 | uint32_t value; 73 | memcpy((& value), block.c_str(), sizeof(uint32_t)); 74 | printf("%d ", value); 75 | } 76 | 77 | printf("\n=========================================================================\n"); 78 | 79 | delete oram; 80 | mongo::client::shutdown(); 81 | return 0; 82 | } -------------------------------------------------------------------------------- /PathORAM_main.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Dong Xie on 7/6/2016. 3 | // 4 | 5 | #include 6 | #include 7 | #include "PathORAM.h" 8 | #include "Config.h" 9 | 10 | using namespace mongo; 11 | using namespace CryptoPP; 12 | 13 | int main() { 14 | mongo::client::initialize(); 15 | 16 | srand((uint32_t)time(NULL)); 17 | 18 | uint32_t N = 1024; 19 | ORAM* oram = new PathORAM(N); 20 | 21 | for(uint32_t i = 0; i < N; i ++) { 22 | char str[12]; 23 | sprintf(str, "%zu\n", (size_t)i); 24 | std::string key(str); 25 | 26 | std::string value; 27 | const uint32_t tmp_len = B - AES::BLOCKSIZE - 2 * sizeof(uint32_t); 28 | byte tmp_buffer[tmp_len]; 29 | AutoSeededRandomPool prng; 30 | prng.GenerateBlock(tmp_buffer, tmp_len); 31 | value = std::string((const char *)tmp_buffer, tmp_len); 32 | int32_t blockID = i; 33 | std::string bID = std::string((const char *)(& blockID), sizeof(uint32_t)); 34 | value = bID + value; 35 | 36 | oram->put(key, value); 37 | } 38 | 39 | size_t roundNum = 5; 40 | for(size_t r = 0; r < roundNum; r ++) { 41 | for(size_t i = 0; i < N; i ++) { 42 | char str[12]; 43 | sprintf(str, "%zu\n", i); 44 | std::string key(str); 45 | std::string block = oram->get(key); 46 | uint32_t value; 47 | memcpy((& value), block.c_str(), sizeof(uint32_t)); 48 | printf("%d ", value); 49 | } 50 | printf("\n=========================================================================\n"); 51 | } 52 | 53 | for(uint32_t i = 0; i < N; i ++) { 54 | char str[12]; 55 | sprintf(str, "%zu\n", (size_t)i); 56 | std::string key(str); 57 | 58 | std::string value; 59 | const uint32_t tmp_len = B - AES::BLOCKSIZE - 2 * sizeof(uint32_t); 60 | byte tmp_buffer[tmp_len]; 61 | AutoSeededRandomPool prng; 62 | prng.GenerateBlock(tmp_buffer, tmp_len); 63 | value = std::string((const char *)tmp_buffer, tmp_len); 64 | int32_t blockID = N - 1 - i; 65 | std::string bID = std::string((const char *)(& blockID), sizeof(uint32_t)); 66 | value = bID + value; 67 | 68 | oram->put(key, value); 69 | } 70 | 71 | for(size_t i = 0; i < N; i ++) { 72 | char str[12]; 73 | sprintf(str, "%zu\n", i); 74 | std::string key(str); 75 | std::string block = oram->get(key); 76 | uint32_t value; 77 | memcpy((& value), block.c_str(), sizeof(uint32_t)); 78 | printf("%d ", value); 79 | } 80 | 81 | printf("\n=========================================================================\n"); 82 | 83 | delete oram; 84 | mongo::client::shutdown(); 85 | return 0; 86 | } -------------------------------------------------------------------------------- /BinaryORAM_main.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Dong Xie on 7/10/2016. 3 | // 4 | 5 | #include 6 | #include 7 | #include "BinaryORAM.h" 8 | #include "Config.h" 9 | 10 | using namespace mongo; 11 | using namespace CryptoPP; 12 | 13 | int main() { 14 | mongo::client::initialize(); 15 | 16 | srand((uint32_t)time(NULL)); 17 | 18 | uint32_t N = 1024; 19 | ORAM* oram = new BinaryORAM(N); 20 | 21 | for(uint32_t i = 0; i < N; i ++) { 22 | char str[12]; 23 | sprintf(str, "%zu\n", (size_t)i); 24 | std::string key(str); 25 | 26 | std::string value; 27 | const uint32_t tmp_len = B - AES::BLOCKSIZE - 2 * sizeof(uint32_t); 28 | byte tmp_buffer[tmp_len]; 29 | AutoSeededRandomPool prng; 30 | prng.GenerateBlock(tmp_buffer, tmp_len); 31 | value = std::string((const char *)tmp_buffer, tmp_len); 32 | int32_t blockID = i; 33 | std::string bID = std::string((const char *)(& blockID), sizeof(uint32_t)); 34 | value = bID + value; 35 | 36 | oram->put(key, value); 37 | } 38 | 39 | size_t roundNum = 5; 40 | for(size_t r = 0; r < roundNum; r ++) { 41 | for(size_t i = 0; i < N; i ++) { 42 | char str[12]; 43 | sprintf(str, "%zu\n", i); 44 | std::string key(str); 45 | std::string block = oram->get(key); 46 | uint32_t value; 47 | memcpy((& value), block.c_str(), sizeof(uint32_t)); 48 | printf("%d ", value); 49 | } 50 | printf("\n=========================================================================\n"); 51 | } 52 | 53 | for(uint32_t i = 0; i < N; i ++) { 54 | char str[12]; 55 | sprintf(str, "%zu\n", (size_t)i); 56 | std::string key(str); 57 | 58 | std::string value; 59 | const uint32_t tmp_len = B - AES::BLOCKSIZE - 2 * sizeof(uint32_t); 60 | byte tmp_buffer[tmp_len]; 61 | AutoSeededRandomPool prng; 62 | prng.GenerateBlock(tmp_buffer, tmp_len); 63 | value = std::string((const char *)tmp_buffer, tmp_len); 64 | int32_t blockID = N - 1 - i; 65 | std::string bID = std::string((const char *)(& blockID), sizeof(uint32_t)); 66 | value = bID + value; 67 | 68 | oram->put(key, value); 69 | } 70 | 71 | for(size_t i = 0; i < N; i ++) { 72 | char str[12]; 73 | sprintf(str, "%zu\n", i); 74 | std::string key(str); 75 | std::string block = oram->get(key); 76 | uint32_t value; 77 | memcpy((& value), block.c_str(), sizeof(uint32_t)); 78 | printf("%d ", value); 79 | } 80 | 81 | printf("\n=========================================================================\n"); 82 | 83 | delete oram; 84 | mongo::client::shutdown(); 85 | return 0; 86 | } -------------------------------------------------------------------------------- /SRORAM_main.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Dong Xie on 7/10/2016. 3 | // 4 | 5 | #include 6 | #include 7 | #include "ORAM.h" 8 | #include "SRORAM.h" 9 | #include "Config.h" 10 | 11 | using namespace mongo; 12 | using namespace CryptoPP; 13 | 14 | int main() { 15 | mongo::client::initialize(); 16 | 17 | srand((uint32_t)time(NULL)); 18 | 19 | uint32_t N = 1024; 20 | ORAM* oram = new SRORAM(N); 21 | 22 | for(uint32_t i = 0; i < N; i ++) { 23 | char str[12]; 24 | sprintf(str, "%zu\n", (size_t)i); 25 | std::string key(str); 26 | 27 | std::string value; 28 | const uint32_t tmp_len = B - AES::BLOCKSIZE - 2 * sizeof(uint32_t); 29 | byte tmp_buffer[tmp_len]; 30 | AutoSeededRandomPool prng; 31 | prng.GenerateBlock(tmp_buffer, tmp_len); 32 | value = std::string((const char *)tmp_buffer, tmp_len); 33 | int32_t blockID = i; 34 | std::string bID = std::string((const char *)(& blockID), sizeof(uint32_t)); 35 | value = bID + value; 36 | 37 | oram->put(key, value); 38 | } 39 | 40 | size_t roundNum = 5; 41 | for(size_t r = 0; r < roundNum; r ++) { 42 | for(size_t i = 0; i < N; i ++) { 43 | char str[12]; 44 | sprintf(str, "%zu\n", i); 45 | std::string key(str); 46 | std::string block = oram->get(key); 47 | uint32_t value; 48 | memcpy((& value), block.c_str(), sizeof(uint32_t)); 49 | printf("%d ", value); 50 | } 51 | printf("\n=========================================================================\n"); 52 | } 53 | 54 | for(uint32_t i = 0; i < N; i ++) { 55 | char str[12]; 56 | sprintf(str, "%zu\n", (size_t)i); 57 | std::string key(str); 58 | 59 | std::string value; 60 | const uint32_t tmp_len = B - AES::BLOCKSIZE - 2 * sizeof(uint32_t); 61 | byte tmp_buffer[tmp_len]; 62 | AutoSeededRandomPool prng; 63 | prng.GenerateBlock(tmp_buffer, tmp_len); 64 | value = std::string((const char *)tmp_buffer, tmp_len); 65 | int32_t blockID = N - 1 - i; 66 | std::string bID = std::string((const char *)(& blockID), sizeof(uint32_t)); 67 | value = bID + value; 68 | 69 | oram->put(key, value); 70 | } 71 | 72 | for(size_t i = 0; i < N; i ++) { 73 | char str[12]; 74 | sprintf(str, "%zu\n", i); 75 | std::string key(str); 76 | std::string block = oram->get(key); 77 | uint32_t value; 78 | memcpy((& value), block.c_str(), sizeof(uint32_t)); 79 | printf("%d ", value); 80 | } 81 | 82 | printf("\n=========================================================================\n"); 83 | 84 | delete oram; 85 | mongo::client::shutdown(); 86 | return 0; 87 | } -------------------------------------------------------------------------------- /RecursivePathORAM_main.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Dong Xie on 7/16/2016. 3 | // 4 | 5 | #include 6 | #include 7 | #include "RecursivePathORAM.h" 8 | #include "Config.h" 9 | 10 | using namespace mongo; 11 | using namespace CryptoPP; 12 | 13 | int main() { 14 | mongo::client::initialize(); 15 | 16 | srand((uint32_t)time(NULL)); 17 | 18 | uint32_t N = 1024; 19 | ORAM *oram = new RecursivePathORAM(N); 20 | 21 | for(uint32_t i = 0; i < N; i ++) { 22 | char str[12]; 23 | sprintf(str, "%zu\n", (size_t)i); 24 | std::string key(str); 25 | 26 | std::string value; 27 | const uint32_t tmp_len = B - AES::BLOCKSIZE - 2 * sizeof(uint32_t); 28 | byte tmp_buffer[tmp_len]; 29 | AutoSeededRandomPool prng; 30 | prng.GenerateBlock(tmp_buffer, tmp_len); 31 | value = std::string((const char *)tmp_buffer, tmp_len); 32 | int32_t blockID = i; 33 | std::string bID = std::string((const char *)(& blockID), sizeof(uint32_t)); 34 | value = bID + value; 35 | 36 | oram->put(key, value); 37 | } 38 | 39 | size_t roundNum = 5; 40 | for(size_t r = 0; r < roundNum; r ++) { 41 | for(size_t i = 0; i < N; i ++) { 42 | char str[12]; 43 | sprintf(str, "%zu\n", i); 44 | std::string key(str); 45 | std::string block = oram->get(key); 46 | uint32_t value; 47 | memcpy((& value), block.c_str(), sizeof(uint32_t)); 48 | printf("%d ", value); 49 | } 50 | printf("\n=========================================================================\n"); 51 | } 52 | 53 | for(uint32_t i = 0; i < N; i ++) { 54 | char str[12]; 55 | sprintf(str, "%zu\n", (size_t)i); 56 | std::string key(str); 57 | 58 | std::string value; 59 | const uint32_t tmp_len = B - AES::BLOCKSIZE - 2 * sizeof(uint32_t); 60 | byte tmp_buffer[tmp_len]; 61 | AutoSeededRandomPool prng; 62 | prng.GenerateBlock(tmp_buffer, tmp_len); 63 | value = std::string((const char *)tmp_buffer, tmp_len); 64 | int32_t blockID = N - 1 - i; 65 | std::string bID = std::string((const char *)(& blockID), sizeof(uint32_t)); 66 | value = bID + value; 67 | 68 | oram->put(key, value); 69 | } 70 | 71 | for(size_t i = 0; i < N; i ++) { 72 | char str[12]; 73 | sprintf(str, "%zu\n", i); 74 | std::string key(str); 75 | std::string block = oram->get(key); 76 | uint32_t value; 77 | memcpy((& value), block.c_str(), sizeof(uint32_t)); 78 | printf("%d ", value); 79 | } 80 | 81 | printf("\n=========================================================================\n"); 82 | 83 | delete oram; 84 | mongo::client::shutdown(); 85 | return 0; 86 | } -------------------------------------------------------------------------------- /include/ServerConnector.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 by SEAL-ORAM Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | // 18 | // Created by dong on 1/27/16. 19 | // Abstract Server Connector 20 | // 21 | 22 | #ifndef SEAL_ORAM_SERVER_CONNECTOR_H 23 | #define SEAL_ORAM_SERVER_CONNECTOR_H 24 | 25 | #include 26 | #include 27 | 28 | class ServerConnector { 29 | public: 30 | ServerConnector() {} 31 | virtual ~ServerConnector() {} 32 | 33 | struct iterator { 34 | virtual ~iterator() {} 35 | virtual bool hasNext() = 0; 36 | virtual std::string next() = 0; 37 | }; 38 | 39 | virtual void clear(const std::string& ns = "") = 0; 40 | virtual void insert(const uint32_t& id, const std::string& encrypted_block, const std::string& ns = "") = 0; 41 | virtual void insert(const std::vector< std::pair >& blocks, const std::string& ns = "") = 0; 42 | virtual void insert(const std::string* sbuffer, const uint32_t& low, const size_t& len, const std::string& ns = "") = 0; 43 | virtual void insert(const std::vector< std::pair >& blocks, const std::string& ns = "") = 0; 44 | virtual void insertWithTag(const std::vector< std::pair >& blocks, const std::string& ns = "") = 0; 45 | virtual iterator* scan() = 0; 46 | virtual std::string find(const uint32_t& id, const std::string& ns = "") = 0; 47 | virtual void find(const std::vector& ids, std::string* sbuffer, size_t& length, const std::string& ns = "") = 0; 48 | virtual std::string fetch(const std::string& id, const std::string& ns = "") = 0; 49 | virtual void find(const uint32_t& low, const uint32_t& high, std::vector& blocks, const std::string& ns = "") = 0; 50 | virtual void findByTag(const uint32_t& tag, std::string* sbuffer, size_t& length, const std::string& ns = "") = 0; 51 | virtual void update(const uint32_t& id, const std::string& data, const std::string& ns = "") = 0; 52 | virtual void update(const std::string* sbuffer, const uint32_t& low, const size_t& len, const std::string& ns = "") = 0; 53 | virtual void update(const std::vector< std::pair > blocks, const std::string& ns = "") = 0; 54 | }; 55 | 56 | #endif //SEAL_ORAM_SERVER_CONNECTOR_H -------------------------------------------------------------------------------- /RecursiveBinaryORAM_main.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Dong Xie on 7/16/2016. 3 | // 4 | 5 | #include 6 | #include 7 | #include "RecursiveBinaryORAM.h" 8 | #include "Config.h" 9 | 10 | using namespace mongo; 11 | using namespace CryptoPP; 12 | 13 | int main() { 14 | mongo::client::initialize(); 15 | 16 | srand((uint32_t)time(NULL)); 17 | 18 | uint32_t N = 4096; 19 | ORAM* oram = new RecursiveBinaryORAM(N); 20 | 21 | for(uint32_t i = 0; i < N; i ++) { 22 | char str[12]; 23 | sprintf(str, "%zu\n", (size_t)i); 24 | std::string key(str); 25 | 26 | std::string value; 27 | const uint32_t tmp_len = B - AES::BLOCKSIZE - 2 * sizeof(uint32_t); 28 | byte tmp_buffer[tmp_len]; 29 | AutoSeededRandomPool prng; 30 | prng.GenerateBlock(tmp_buffer, tmp_len); 31 | value = std::string((const char *)tmp_buffer, tmp_len); 32 | int32_t blockID = i; 33 | std::string bID = std::string((const char *)(& blockID), sizeof(uint32_t)); 34 | value = bID + value; 35 | 36 | oram->put(key, value); 37 | } 38 | 39 | size_t roundNum = 5; 40 | for(size_t r = 0; r < roundNum; r ++) { 41 | for(size_t i = 0; i < N; i ++) { 42 | char str[12]; 43 | sprintf(str, "%zu\n", i); 44 | std::string key(str); 45 | std::string block = oram->get(key); 46 | uint32_t value; 47 | memcpy((& value), block.c_str(), sizeof(uint32_t)); 48 | printf("%d ", value); 49 | } 50 | printf("\n=========================================================================\n"); 51 | } 52 | 53 | for(uint32_t i = 0; i < N; i ++) { 54 | char str[12]; 55 | sprintf(str, "%zu\n", (size_t)i); 56 | std::string key(str); 57 | 58 | std::string value; 59 | const uint32_t tmp_len = B - AES::BLOCKSIZE - 2 * sizeof(uint32_t); 60 | byte tmp_buffer[tmp_len]; 61 | AutoSeededRandomPool prng; 62 | prng.GenerateBlock(tmp_buffer, tmp_len); 63 | value = std::string((const char *)tmp_buffer, tmp_len); 64 | int32_t blockID = N - 1 - i; 65 | std::string bID = std::string((const char *)(& blockID), sizeof(uint32_t)); 66 | value = bID + value; 67 | 68 | oram->put(key, value); 69 | } 70 | 71 | for(size_t i = 0; i < N; i ++) { 72 | char str[12]; 73 | sprintf(str, "%zu\n", i); 74 | std::string key(str); 75 | std::string block = oram->get(key); 76 | uint32_t value; 77 | memcpy((& value), block.c_str(), sizeof(uint32_t)); 78 | printf("%d ", value); 79 | } 80 | 81 | printf("\n=========================================================================\n"); 82 | 83 | delete oram; 84 | mongo::client::shutdown(); 85 | return 0; 86 | } -------------------------------------------------------------------------------- /TPORAM_main.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Dong Xie on 7/13/2016. 3 | // 4 | 5 | #include 6 | #include 7 | #include "ORAM.h" 8 | #include "TPPartitionORAMInstance.h" 9 | #include "PartitionORAM.h" 10 | #include "Config.h" 11 | 12 | using namespace mongo; 13 | using namespace CryptoPP; 14 | 15 | int main() { 16 | mongo::client::initialize(); 17 | 18 | srand((uint32_t)time(NULL)); 19 | 20 | uint32_t N = 1024; 21 | ORAM *oram = new PartitionORAM(N, R); 22 | 23 | for(uint32_t i = 0; i < N; i ++) { 24 | char str[12]; 25 | sprintf(str, "%zu\n", (size_t)i); 26 | std::string key(str); 27 | 28 | std::string value; 29 | const uint32_t tmp_len = B - AES::BLOCKSIZE - 2 * sizeof(uint32_t); 30 | byte tmp_buffer[tmp_len]; 31 | AutoSeededRandomPool prng; 32 | prng.GenerateBlock(tmp_buffer, tmp_len); 33 | value = std::string((const char *)tmp_buffer, tmp_len); 34 | int32_t blockID = i; 35 | std::string bID = std::string((const char *)(& blockID), sizeof(uint32_t)); 36 | value = bID + value; 37 | 38 | oram->put(key, value); 39 | } 40 | 41 | size_t roundNum = 5; 42 | for(size_t r = 0; r < roundNum; r ++) { 43 | for(size_t i = 0; i < N; i ++) { 44 | char str[12]; 45 | sprintf(str, "%zu\n", i); 46 | std::string key(str); 47 | std::string block = oram->get(key); 48 | uint32_t value; 49 | memcpy((& value), block.c_str(), sizeof(uint32_t)); 50 | printf("%d ", value); 51 | } 52 | printf("\n=========================================================================\n"); 53 | } 54 | 55 | for(uint32_t i = 0; i < N; i ++) { 56 | char str[12]; 57 | sprintf(str, "%zu\n", (size_t)i); 58 | std::string key(str); 59 | 60 | std::string value; 61 | const uint32_t tmp_len = B - AES::BLOCKSIZE - 2 * sizeof(uint32_t); 62 | byte tmp_buffer[tmp_len]; 63 | AutoSeededRandomPool prng; 64 | prng.GenerateBlock(tmp_buffer, tmp_len); 65 | value = std::string((const char *)tmp_buffer, tmp_len); 66 | int32_t blockID = N - 1 - i; 67 | std::string bID = std::string((const char *)(& blockID), sizeof(uint32_t)); 68 | value = bID + value; 69 | 70 | oram->put(key, value); 71 | } 72 | 73 | for(size_t i = 0; i < N; i ++) { 74 | char str[12]; 75 | sprintf(str, "%zu\n", i); 76 | std::string key(str); 77 | std::string block = oram->get(key); 78 | uint32_t value; 79 | memcpy((& value), block.c_str(), sizeof(uint32_t)); 80 | printf("%d ", value); 81 | } 82 | 83 | printf("\n=========================================================================\n"); 84 | 85 | delete oram; 86 | mongo::client::shutdown(); 87 | return 0; 88 | } -------------------------------------------------------------------------------- /RecursiveTPORAM_main.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Dong Xie on 7/16/2016. 3 | // 4 | 5 | #include 6 | #include 7 | #include "RecursivePartitionORAM.h" 8 | #include "RecursiveTPPartitionORAMInstance.h" 9 | #include "Config.h" 10 | 11 | using namespace mongo; 12 | using namespace CryptoPP; 13 | 14 | int main() { 15 | mongo::client::initialize(); 16 | 17 | srand((uint32_t)time(NULL)); 18 | 19 | uint32_t N = 4096; 20 | ORAM *oram = new RecursivePartitionORAM(N, R); 21 | 22 | for(uint32_t i = 0; i < N; i ++) { 23 | char str[12]; 24 | sprintf(str, "%zu\n", (size_t)i); 25 | std::string key(str); 26 | 27 | std::string value; 28 | const uint32_t tmp_len = B - AES::BLOCKSIZE - 2 * sizeof(uint32_t); 29 | byte tmp_buffer[tmp_len]; 30 | AutoSeededRandomPool prng; 31 | prng.GenerateBlock(tmp_buffer, tmp_len); 32 | value = std::string((const char *)tmp_buffer, tmp_len); 33 | int32_t blockID = i; 34 | std::string bID = std::string((const char *)(& blockID), sizeof(uint32_t)); 35 | value = bID + value; 36 | 37 | oram->put(key, value); 38 | } 39 | 40 | size_t roundNum = 5; 41 | for(size_t r = 0; r < roundNum; r ++) { 42 | for(size_t i = 0; i < N; i ++) { 43 | char str[12]; 44 | sprintf(str, "%zu\n", i); 45 | std::string key(str); 46 | std::string block = oram->get(key); 47 | uint32_t value; 48 | memcpy((& value), block.c_str(), sizeof(uint32_t)); 49 | printf("%d ", value); 50 | } 51 | printf("\n=========================================================================\n"); 52 | } 53 | 54 | for(uint32_t i = 0; i < N; i ++) { 55 | char str[12]; 56 | sprintf(str, "%zu\n", (size_t)i); 57 | std::string key(str); 58 | 59 | std::string value; 60 | const uint32_t tmp_len = B - AES::BLOCKSIZE - 2 * sizeof(uint32_t); 61 | byte tmp_buffer[tmp_len]; 62 | AutoSeededRandomPool prng; 63 | prng.GenerateBlock(tmp_buffer, tmp_len); 64 | value = std::string((const char *)tmp_buffer, tmp_len); 65 | int32_t blockID = N - 1 - i; 66 | std::string bID = std::string((const char *)(& blockID), sizeof(uint32_t)); 67 | value = bID + value; 68 | 69 | oram->put(key, value); 70 | } 71 | 72 | for(size_t i = 0; i < N; i ++) { 73 | char str[12]; 74 | sprintf(str, "%zu\n", i); 75 | std::string key(str); 76 | std::string block = oram->get(key); 77 | uint32_t value; 78 | memcpy((& value), block.c_str(), sizeof(uint32_t)); 79 | printf("%d ", value); 80 | } 81 | 82 | printf("\n=========================================================================\n"); 83 | 84 | delete oram; 85 | mongo::client::shutdown(); 86 | return 0; 87 | } -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.3) 2 | project(SEAL_ORAM) 3 | 4 | include_directories(include) 5 | 6 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -O3") 7 | 8 | set(GENERAL_SOURCE_FILES 9 | include/ServerConnector.h 10 | include/MongoConnector.h 11 | include/Config.h 12 | include/Util.h 13 | include/ORAM.h 14 | src/MongoConnector.cpp 15 | src/Util.cpp) 16 | 17 | set(IBSOS_SOURCE_FILES 18 | include/IBSOS.h 19 | src/IBSOS.cpp) 20 | 21 | set(PATHORAM_SOURCE_FILES 22 | include/PathORAM.h 23 | include/RecursivePathORAM.h 24 | src/PathORAM.cpp 25 | src/RecursivePathORAM.cpp) 26 | 27 | set(BINARYORAM_SOURCE_FILES 28 | include/BinaryORAM.h 29 | include/RecursiveBinaryORAM.h 30 | src/BinaryORAM.cpp 31 | src/RecursiveBinaryORAM.cpp) 32 | 33 | set(SRORAM_SOURCE_FILES 34 | include/SRORAM.h 35 | src/SRORAM.cpp) 36 | 37 | set(TPORAM_SOURCE_FILES 38 | include/PartitionORAM.h 39 | include/PartitionORAMInstance.h 40 | include/TPPartitionORAMInstance.h 41 | include/RecursivePartitionORAM.h 42 | include/RecursiveTPPartitionORAMInstance.h 43 | src/TPPartitionORAMInstance.cpp 44 | src/RecursiveTPPartitionORAMInstance.cpp) 45 | 46 | add_executable(IBSOS_main IBSOS_main.cpp ${GENERAL_SOURCE_FILES} ${IBSOS_SOURCE_FILES}) 47 | target_link_libraries(IBSOS_main cryptopp pthread mongoclient boost_thread boost_system boost_regex) 48 | 49 | add_executable(PathORAM_main PathORAM_main.cpp ${GENERAL_SOURCE_FILES} ${PATHORAM_SOURCE_FILES}) 50 | target_link_libraries(PathORAM_main cryptopp pthread mongoclient boost_thread boost_system boost_regex) 51 | 52 | add_executable(BinaryORAM_main BinaryORAM_main.cpp ${GENERAL_SOURCE_FILES} ${BINARYORAM_SOURCE_FILES}) 53 | target_link_libraries(BinaryORAM_main cryptopp pthread mongoclient boost_thread boost_system boost_regex) 54 | 55 | add_executable(SRORAM_main SRORAM_main.cpp ${GENERAL_SOURCE_FILES} ${SRORAM_SOURCE_FILES}) 56 | target_link_libraries(SRORAM_main cryptopp pthread mongoclient boost_thread boost_system boost_regex) 57 | 58 | add_executable(TPORAM_main TPORAM_main.cpp ${GENERAL_SOURCE_FILES} ${TPORAM_SOURCE_FILES}) 59 | target_link_libraries(TPORAM_main cryptopp pthread mongoclient boost_thread boost_system boost_regex) 60 | 61 | add_executable(RecursivePathORAM_main RecursivePathORAM_main.cpp ${GENERAL_SOURCE_FILES} ${PATHORAM_SOURCE_FILES}) 62 | target_link_libraries(RecursivePathORAM_main cryptopp pthread mongoclient boost_thread boost_system boost_regex) 63 | 64 | add_executable(RecursiveBinaryORAM_main RecursiveBinaryORAM_main.cpp ${GENERAL_SOURCE_FILES} ${BINARYORAM_SOURCE_FILES}) 65 | target_link_libraries(RecursiveBinaryORAM_main cryptopp pthread mongoclient boost_thread boost_system boost_regex) 66 | 67 | add_executable(RecursiveTPORAM_main RecursiveTPORAM_main.cpp ${GENERAL_SOURCE_FILES} ${TPORAM_SOURCE_FILES}) 68 | target_link_libraries(RecursiveTPORAM_main cryptopp pthread mongoclient boost_thread boost_system boost_regex) 69 | -------------------------------------------------------------------------------- /include/SRORAM.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 by SEAL-ORAM Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | // 18 | // Created by Dong Xie on 7/10/2016. 19 | // 20 | 21 | #ifndef SEAL_ORAM_SRORAM_H 22 | #define SEAL_ORAM_SRORAM_H 23 | 24 | #ifndef __SRORAM_H__ 25 | #define __SRORAM_H__ 26 | 27 | #include "Config.h" 28 | #include "Util.h" 29 | #include "ORAM.h" 30 | #include "MongoConnector.h" 31 | 32 | #include 33 | #include 34 | #include 35 | 36 | using namespace CryptoPP; 37 | 38 | class SRORAM: public ORAM { 39 | public: 40 | SRORAM(uint32_t numofBlocks) { 41 | N = numofBlocks; 42 | D = (uint32_t) ceil(sqrt((double) N)); 43 | C = N + 2 * D; 44 | conn = new MongoConnector(server_host, "oram.basicsr"); 45 | count = 0; 46 | 47 | AutoSeededRandomPool prng; 48 | encKey = new byte[AES::DEFAULT_KEYLENGTH]; 49 | prng.GenerateBlock(encKey, AES::DEFAULT_KEYLENGTH); 50 | 51 | byte temp[AES::DEFAULT_KEYLENGTH]; 52 | prng.GenerateBlock(temp, AES::DEFAULT_KEYLENGTH); 53 | salt = std::string((const char*)temp, AES::DEFAULT_KEYLENGTH); 54 | sbuffer = new std::string[2]; 55 | initialize(); 56 | } 57 | 58 | ~SRORAM() { 59 | delete []encKey; 60 | delete []sbuffer; 61 | delete conn; 62 | } 63 | 64 | 65 | virtual std::string get(const std::string & key); 66 | virtual void put(const std::string& key, const std::string & value); 67 | 68 | virtual std::string get(const uint32_t & key); 69 | virtual void put(const uint32_t & key, const std::string & value); 70 | private: 71 | void initialize(); 72 | void access(char op, uint32_t blockID, std::string &data); 73 | 74 | std::string readBlock(uint32_t blockID); 75 | void writeBlock(uint32_t blockID, std::string &data); 76 | 77 | void oddeven_merge(uint32_t lo, uint32_t hi, uint32_t r, uint32_t len, char order); 78 | void oddeven_merge_sort_range(uint32_t lo, uint32_t hi, uint32_t len, char order); 79 | void compare_and_swap(uint32_t a, uint32_t b, char order); 80 | void obliviSort(uint32_t len, char order); 81 | void rehash(); 82 | 83 | ServerConnector* conn; 84 | 85 | uint32_t N; //# of real blocks 86 | uint32_t D; //# of blocks in shelters 87 | uint32_t C; //The capacity of the whole server 88 | 89 | uint32_t count; 90 | byte *encKey; //Encryption Key 91 | std::string salt; //Hash Salt 92 | std::string *sbuffer; //Buffer for shuffling 93 | }; 94 | 95 | #endif 96 | 97 | 98 | #endif //SEAL_ORAM_SRORAM_H 99 | -------------------------------------------------------------------------------- /include/MongoConnector.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 by SEAL-ORAM Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | // 18 | // Created by Dong Xie on 7/6/2016. 19 | // Mongo Server Connector 20 | // 21 | 22 | #ifndef SEAL_ORAM_MONGOCONNECTOR_H 23 | #define SEAL_ORAM_MONGOCONNECTOR_H 24 | 25 | #include 26 | #include "ServerConnector.h" 27 | 28 | using namespace mongo; 29 | 30 | class MongoConnector: public ServerConnector { 31 | public: 32 | MongoConnector(const std::string& url, const std::string& collection_name, const bool flag = false); 33 | MongoConnector(const std::string& url); 34 | virtual ~MongoConnector(); 35 | 36 | struct iterator: public ServerConnector::iterator { 37 | iterator(std::unique_ptr c): cursor(std::move(c)) {} 38 | 39 | virtual ~iterator() {} 40 | 41 | virtual bool hasNext() { 42 | return cursor->more(); 43 | } 44 | 45 | virtual std::string next() { 46 | BSONObj p = cursor->next(); 47 | int len; 48 | const char* raw_data = p.getField("data").binData(len); 49 | return std::string(raw_data, (size_t)len); 50 | } 51 | 52 | std::unique_ptr cursor; 53 | }; 54 | 55 | virtual void clear(const std::string& ns = ""); 56 | virtual void insert(const uint32_t& id, const std::string& encrypted_block, const std::string& ns = ""); 57 | virtual void insert(const std::vector< std::pair >& blocks, const std::string& ns = ""); 58 | virtual void insert(const std::string* sbuffer, const uint32_t& low, const size_t& len, const std::string& ns = ""); 59 | virtual void insert(const std::vector< std::pair >& blocks, const std::string& ns = ""); 60 | virtual void insertWithTag(const std::vector< std::pair >& blocks, const std::string& ns = ""); 61 | virtual iterator* scan(); 62 | virtual std::string find(const uint32_t& id, const std::string& ns = ""); 63 | virtual void find(const std::vector& ids, std::string* sbuffer, size_t& length, const std::string& ns = ""); 64 | virtual std::string fetch(const std::string& id, const std::string& ns = ""); 65 | virtual void find(const uint32_t& low, const uint32_t& high, std::vector& blocks, const std::string& ns = ""); 66 | virtual void findByTag(const uint32_t& tag, std::string* sbuffer, size_t& length, const std::string& ns = ""); 67 | virtual void update(const uint32_t& id, const std::string& data, const std::string& ns = ""); 68 | virtual void update(const std::string* sbuffer, const uint32_t& low, const size_t& len, const std::string& ns = ""); 69 | virtual void update(const std::vector< std::pair > blocks, const std::string& ns = ""); 70 | 71 | void initialize(const std::string& ns); 72 | void finalize(const std::string& ns); 73 | 74 | private: 75 | DBClientConnection mongo; 76 | std::string collection_name; 77 | bool by_tag; 78 | }; 79 | 80 | #endif //SEAL_ORAM_MONGOCONNECTOR_H 81 | -------------------------------------------------------------------------------- /src/PathORAM.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 by SEAL-ORAM Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | // 18 | // Created by Dong Xie on 7/6/2016. 19 | // 20 | 21 | #include "PathORAM.h" 22 | 23 | #include 24 | #include 25 | #include "MongoConnector.h" 26 | #include "Config.h" 27 | 28 | using namespace CryptoPP; 29 | 30 | PathORAM::PathORAM(const uint32_t& n) { 31 | height = (uint32_t)ceil(log2((double)n)) + 1; 32 | n_blocks = (uint32_t)1 << (height - 1); 33 | stash.clear(); 34 | pos_map = new uint32_t[n]; 35 | conn = new MongoConnector(server_host, "oram.path"); 36 | 37 | key = new byte[Util::key_length]; 38 | Util::prng.GenerateBlock(key, Util::key_length); 39 | sbuffer = new std::string[height * PathORAM_Z]; 40 | 41 | for (uint32_t i = 0; i < (1 << height) - 1; ++i) { 42 | for (uint32_t j = 0; j < PathORAM_Z; ++j) { 43 | std::string tmp = Util::generate_random_block(B - Util::aes_block_size - sizeof(uint32_t)); 44 | int32_t dummyID = -1; 45 | std::string dID = std::string((const char *)(& dummyID), sizeof(uint32_t)); 46 | std::string cipher; 47 | Util::aes_encrypt(dID + tmp, key, cipher); 48 | conn->insert(i * PathORAM_Z + j, cipher); 49 | } 50 | } 51 | 52 | for (size_t i = 0; i < n_blocks; ++i) pos_map[i] = Util::rand_int(n_blocks); 53 | } 54 | 55 | PathORAM::~PathORAM() { 56 | delete[] key; 57 | delete[] sbuffer; 58 | delete[] pos_map; 59 | delete conn; 60 | } 61 | 62 | std::string PathORAM::get(const std::string & key) { 63 | std::string res; 64 | uint32_t int_key; 65 | sscanf(key.c_str(), "%d", &int_key); 66 | access('r', int_key, res); 67 | return res; 68 | } 69 | 70 | void PathORAM::put(const std::string & key, const std::string & value) { 71 | uint32_t int_key; 72 | sscanf(key.c_str(), "%d", &int_key); 73 | std::string value2 = value; 74 | access('w', int_key, value2); 75 | } 76 | 77 | std::string PathORAM::get(const uint32_t & key) { 78 | std::string res; 79 | access('r', key, res); 80 | return res; 81 | } 82 | 83 | void PathORAM::put(const uint32_t & key, const std::string & value) { 84 | std::string value2 = value; 85 | access('w', key, value2); 86 | } 87 | 88 | void PathORAM::access(const char& op, const uint32_t& block_id, std::string& data) { 89 | uint32_t x = pos_map[block_id]; 90 | pos_map[block_id] = Util::rand_int(n_blocks); 91 | 92 | size_t length; 93 | fetchAlongPath(x, sbuffer, length); 94 | for (size_t i = 0; i < length; ++i) { 95 | std::string plain; 96 | Util::aes_decrypt(sbuffer[i], key, plain); 97 | 98 | int32_t b_id; 99 | memcpy(&b_id, plain.c_str(), sizeof(uint32_t)); 100 | if (b_id != -1) { 101 | stash[b_id] = plain.substr(sizeof(uint32_t)); 102 | } 103 | } 104 | 105 | if (op == 'r') data = stash[block_id]; 106 | else stash[block_id] = data; 107 | 108 | for (uint32_t i = 0; i < height; ++i) { 109 | uint32_t tot = 0; 110 | uint32_t base = i * PathORAM_Z; 111 | std::unordered_map::iterator j, tmp; 112 | j = stash.begin(); 113 | while (j != stash.end() && tot < PathORAM_Z) { 114 | if (check(pos_map[j->first], x, i)) { 115 | std::string b_id = std::string((const char *)(&(j->first)), sizeof(uint32_t)); 116 | sbuffer[base + tot] = b_id + j->second; 117 | tmp = j; ++j; stash.erase(tmp); 118 | ++tot; 119 | } else ++j; 120 | } 121 | for (int k = tot; k < PathORAM_Z; ++k) { 122 | std::string tmp_block = Util::generate_random_block(B - Util::aes_block_size - sizeof(uint32_t)); 123 | int32_t dummyID = -1; 124 | std::string dID = std::string((const char *)(& dummyID), sizeof(uint32_t)); 125 | sbuffer[base + k] = dID + tmp_block; 126 | } 127 | } 128 | 129 | for (size_t i = 0; i < height * PathORAM_Z; ++i) { 130 | std::string cipher; 131 | Util::aes_encrypt(sbuffer[i], key, cipher); 132 | sbuffer[i] = cipher; 133 | } 134 | loadAlongPath(x, sbuffer, height * PathORAM_Z); 135 | } 136 | 137 | bool PathORAM::check(int x, int y, int l) { 138 | return (x >> l) == (y >> l); 139 | } 140 | 141 | void PathORAM::fetchAlongPath(const uint32_t& x, std::string* sbuffer, size_t& length) { 142 | uint32_t cur_pos = x + (1 << (height - 1)); 143 | std::vector ids; 144 | while (cur_pos > 0) { 145 | for (uint32_t i = 0; i < PathORAM_Z; ++i) 146 | ids.push_back((cur_pos - 1) * PathORAM_Z + i); 147 | cur_pos >>= 1; 148 | } 149 | conn->find(ids, sbuffer, length); 150 | } 151 | 152 | void PathORAM::loadAlongPath(const uint32_t& x, const std::string* sbuffer, const size_t& length) { 153 | uint32_t cur_pos = x + (1 << (height - 1)); 154 | uint32_t offset = 0; 155 | insert_buffer.clear(); 156 | while (cur_pos > 0) { 157 | for (uint32_t i = 0; i < PathORAM_Z; ++i) 158 | insert_buffer.emplace_back(std::make_pair((cur_pos - 1) * PathORAM_Z + i, sbuffer[offset + i])); 159 | offset += PathORAM_Z; 160 | cur_pos >>= 1; 161 | } 162 | conn->update(insert_buffer); 163 | } -------------------------------------------------------------------------------- /include/PartitionORAM.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 by SEAL-ORAM Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | // 18 | // Created by Dong Xie on 7/13/2016. 19 | // 20 | 21 | #ifndef SEAL_ORAM_PARTITIONORAM_H 22 | #define SEAL_ORAM_PARTITIONORAM_H 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include "PartitionORAMInstance.h" 31 | #include "TPPartitionORAMInstance.h" 32 | #include "Util.h" 33 | #include "Config.h" 34 | #include "ORAM.h" 35 | #include "MongoConnector.h" 36 | 37 | using namespace CryptoPP; 38 | 39 | template 40 | class PartitionORAM: public ORAM { 41 | public: 42 | PartitionORAM(const uint32_t& n, const double& rate); 43 | virtual ~PartitionORAM(); 44 | 45 | virtual std::string get(const std::string & key); 46 | virtual void put(const std::string & key, const std::string & value); 47 | 48 | virtual std::string get(const uint32_t & key); 49 | virtual void put(const uint32_t & key, const std::string & value); 50 | private: 51 | void evict(uint32_t pid); 52 | void sequentialEvict(); 53 | 54 | void access(char op, uint32_t block_id, std::string & data); 55 | 56 | uint32_t n_blocks; 57 | uint32_t n_partitions; 58 | uint64_t counter; 59 | double rate; 60 | uint32_t cur_partition; 61 | Position* pos_map; 62 | 63 | MongoConnector* conn; 64 | 65 | /******/ 66 | std::string *sbuffer; 67 | /******/ 68 | std::unordered_map * slots; 69 | PartitionORAMInstance** partitions; 70 | //TPPartitionORAMInstance** partitions; 71 | }; 72 | 73 | template 74 | PartitionORAM::PartitionORAM(const uint32_t& n, const double& rate) : ORAM(), n_blocks(n), rate(rate) { 75 | n_partitions = (uint32_t) ceil(sqrt((double) n_blocks)); 76 | uint32_t numofReals = (uint32_t) ceil(((double) n_blocks) / n_partitions); 77 | n_blocks = numofReals * n_partitions; 78 | 79 | conn = new MongoConnector(server_host); 80 | partitions = new PartitionORAMInstance*[n_partitions]; 81 | 82 | counter = 0; 83 | cur_partition = 0; 84 | slots = new std::unordered_map[n_partitions]; 85 | pos_map = new Position[n_blocks]; 86 | 87 | if (numofReals < 6) sbuffer = new std::string[(uint32_t) ceil(small_capacity_parameter * numofReals)]; 88 | else sbuffer = new std::string[(uint32_t) ceil(capacity_parameter * numofReals)]; 89 | 90 | size_t real_ind = 0; 91 | for (uint32_t i = 0; i < n_partitions; ++i) 92 | partitions[i] = new T(numofReals, real_ind, i, sbuffer, pos_map, conn); 93 | } 94 | 95 | template 96 | PartitionORAM::~PartitionORAM() { 97 | for (size_t i = 0; i < n_partitions; ++i) delete partitions[i]; 98 | delete[] slots; 99 | delete[] partitions; 100 | delete[] pos_map; 101 | delete conn; 102 | delete[] sbuffer; 103 | } 104 | 105 | template 106 | std::string PartitionORAM::get(const std::string & key) { 107 | std::string res; 108 | uint32_t int_key; 109 | sscanf(key.c_str(), "%d", &int_key); 110 | access('r', int_key, res); 111 | return res; 112 | } 113 | 114 | template 115 | void PartitionORAM::put(const std::string & key, const std::string & value) { 116 | uint32_t int_key; 117 | sscanf(key.c_str(), "%d", &int_key); 118 | std::string value2 = value; 119 | access('w', int_key, value2); 120 | } 121 | 122 | template 123 | std::string PartitionORAM::get(const uint32_t & key) { 124 | std::string res; 125 | access('r', key, res); 126 | return res; 127 | } 128 | 129 | template 130 | void PartitionORAM::put(const uint32_t & key, const std::string & value) { 131 | std::string value2 = value; 132 | access('w', key, value2); 133 | } 134 | 135 | template 136 | void PartitionORAM::evict(uint32_t pid) { 137 | 138 | if (!slots[pid].empty()) { 139 | auto got = slots[pid].begin(); 140 | partitions[pid]->put(got->first, got->second); 141 | slots[pid].erase(got); 142 | } else { 143 | std::string dummy = Util::generate_random_block(B - AES::BLOCKSIZE - sizeof(uint32_t)); 144 | int32_t dummyID = -1; 145 | std::string dID = std::string((const char *)(& dummyID), sizeof(uint32_t)); 146 | dummy = dID + dummy; 147 | partitions[pid] -> put(-1, dummy); 148 | } 149 | } 150 | 151 | template 152 | void PartitionORAM::sequentialEvict() { 153 | if ((uint64_t) (counter * rate) > (uint64_t) ((counter - 1) * rate)) { 154 | evict(cur_partition); 155 | cur_partition = (cur_partition + 1) % n_partitions; 156 | } 157 | } 158 | 159 | template 160 | void PartitionORAM::access(char op, uint32_t block_id, std::string & data) { 161 | uint32_t r = (uint32_t)Util::rand_int(n_partitions); 162 | uint32_t p = pos_map[block_id].part; 163 | auto got = slots[p].find(block_id); 164 | std::string data2; 165 | if (got != slots[p].end()) { 166 | data2 = got->second; 167 | slots[p].erase(got); 168 | partitions[p]->get(-1); 169 | } else data2 = partitions[p]->get(block_id); 170 | pos_map[block_id].part = r; 171 | pos_map[block_id].level = -1; 172 | pos_map[block_id].offset = -1; 173 | uint32_t block_id2 = block_id; 174 | std::string bID = std::string((const char*)(& block_id2), sizeof(uint32_t)); 175 | if (op == 'w') data2 = bID + data; 176 | else if (op == 'r') data = data2.substr(sizeof(uint32_t)); 177 | slots[r][block_id] = data2; 178 | 179 | evict(p); 180 | 181 | counter++; 182 | sequentialEvict(); 183 | } 184 | 185 | #endif //SEAL_ORAM_PARTITIONORAM_H 186 | -------------------------------------------------------------------------------- /src/IBSOS.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 by SEAL-ORAM Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | // 18 | // Created by Dong Xie on 7/6/2016. 19 | // 20 | 21 | #include 22 | #include 23 | #include "IBSOS.h" 24 | #include "Config.h" 25 | #include "Util.h" 26 | #include "MongoConnector.h" 27 | 28 | using namespace CryptoPP; 29 | 30 | IBSOS::IBSOS(uint32_t n, uint32_t Alpha) : n_real(n) { 31 | alpha = Alpha; 32 | n_cache = (uint32_t)(ceil(sqrt(n_real + alpha * sqrt(n_real)))); 33 | n_blocks = n_cache * n_cache; 34 | conn = new MongoConnector(server_host, "oram.squareroot"); 35 | ibs_conn = new MongoConnector(server_host, "oram.ibs", true); 36 | stash.clear(); 37 | insert_buffer.clear(); 38 | 39 | AutoSeededRandomPool prng; 40 | key = new byte[AES::DEFAULT_KEYLENGTH]; 41 | prng.GenerateBlock(key, Util::key_length); 42 | int32_t dummy_count = 0; 43 | salt = Util::generate_random_block(Util::aes_block_size); 44 | 45 | for (uint32_t i = 0; i < n_blocks; ++i) { 46 | std::string tmp = Util::generate_random_block(B - AES::BLOCKSIZE - sizeof(int32_t)); 47 | int32_t b_id; 48 | if (i < n_real) b_id = i; 49 | else { 50 | --dummy_count; 51 | b_id = dummy_count; 52 | } 53 | std::string s_id = std::string((const char *)(&b_id), sizeof(int32_t)); 54 | std::string cipher; 55 | Util::aes_encrypt(s_id + tmp, key, cipher); 56 | insert_buffer.emplace_back(std::make_pair(Util::sha256_hash(s_id, salt), cipher)); 57 | if (insert_buffer.size() == n_cache) { 58 | conn->insert(insert_buffer); 59 | insert_buffer.clear(); 60 | } 61 | } 62 | 63 | n_cache = alpha * n_cache; 64 | sbuffer = new std::string[n_cache]; 65 | IBS(); 66 | op_counter = 0; 67 | dummy_counter = 0; 68 | } 69 | 70 | IBSOS::~IBSOS() { 71 | delete[] key; 72 | delete[] sbuffer; 73 | delete conn; 74 | delete ibs_conn; 75 | } 76 | 77 | std::string IBSOS::get(const std::string & key) { 78 | std::string res; 79 | uint32_t int_key; 80 | sscanf(key.c_str(), "%d", &int_key); 81 | access('r', int_key, res); 82 | return res; 83 | } 84 | 85 | void IBSOS::put(const std::string & key, const std::string & value) { 86 | uint32_t int_key; 87 | sscanf(key.c_str(), "%d", &int_key); 88 | std::string value2 = value; 89 | access('w', int_key, value2); 90 | } 91 | 92 | std::string IBSOS::get(const uint32_t & key) { 93 | std::string res; 94 | access('r', key, res); 95 | return res; 96 | } 97 | 98 | void IBSOS::put(const uint32_t & key, const std::string & value) { 99 | std::string value2 = value; 100 | access('w', key, value2); 101 | } 102 | 103 | void IBSOS::IBS() { 104 | insert_buffer.clear(); 105 | for (auto&& item: stash) { 106 | std::string s_id = std::string((const char *)(&(item.first)), sizeof(int32_t)); 107 | std::string cipher; 108 | Util::aes_encrypt(s_id + item.second, key, cipher); 109 | insert_buffer.emplace_back(std::make_pair(Util::sha256_hash(s_id, salt), cipher)); 110 | } 111 | 112 | conn->insert(insert_buffer); 113 | stash.clear(); 114 | uint32_t m = (uint32_t)(sqrt(n_blocks)); 115 | ServerConnector::iterator* it = conn->scan(); 116 | 117 | salt = Util::generate_random_block(Util::aes_block_size); 118 | for (uint32_t i = 0; i < m; ++i) { 119 | for (uint32_t j = 0; j < m; ++j) { 120 | assert(it->hasNext()); 121 | std::string plain; 122 | Util::aes_decrypt(it->next(), key, plain); 123 | sbuffer[j] = plain; 124 | } 125 | 126 | Util::psuedo_random_permute(sbuffer, m); 127 | 128 | insert_buffer.clear(); 129 | for (uint32_t j = 0; j < m; ++j) { 130 | int32_t b_id; 131 | memcpy(&b_id, sbuffer[j].c_str(), sizeof(int32_t)); 132 | std::string s_id = std::string((const char *)(&b_id), sizeof(int32_t)); 133 | std::string cipher; 134 | Util::aes_encrypt(sbuffer[j] ,key, cipher); 135 | insert_buffer.emplace_back(std::make_pair(Util::sha256_hash(s_id, salt), cipher)); 136 | } 137 | ibs_conn->insertWithTag(insert_buffer); 138 | } 139 | delete it; 140 | conn->clear(); 141 | 142 | salt = Util::generate_random_block(Util::aes_block_size); 143 | for (uint32_t i = 0; i < m; ++i) { 144 | size_t length; 145 | ibs_conn->findByTag(i, sbuffer, length); 146 | assert(length == m); 147 | for (size_t j = 0; j < m; ++j) { 148 | std::string plain; 149 | Util::aes_decrypt(sbuffer[j], key, plain); 150 | sbuffer[j] = plain; 151 | } 152 | 153 | Util::psuedo_random_permute(sbuffer, m); 154 | 155 | insert_buffer.clear(); 156 | for (uint32_t j = 0; j < m; ++j) { 157 | int32_t b_id; 158 | memcpy(&b_id, sbuffer[j].c_str(), sizeof(int32_t)); 159 | std::string s_id = std::string((const char *)(&b_id), sizeof(int32_t)); 160 | std::string cipher; 161 | Util::aes_encrypt(sbuffer[j] ,key, cipher); 162 | insert_buffer.emplace_back(std::make_pair(Util::sha256_hash(s_id, salt), cipher)); 163 | } 164 | conn->insert(insert_buffer); 165 | } 166 | ibs_conn->clear(); 167 | } 168 | 169 | void IBSOS::access(const char& op, const uint32_t& block_id, std::string& data) { 170 | if (op_counter == n_cache) { 171 | IBS(); 172 | op_counter = 0; 173 | dummy_counter = 0; 174 | } 175 | 176 | if (stash.find(block_id) == stash.end()) stash[block_id] = fetchBlock(block_id); 177 | else { 178 | --dummy_counter; 179 | stash[dummy_counter] = fetchBlock(dummy_counter); 180 | } 181 | if (op == 'r') data = stash[block_id]; 182 | else stash[block_id] = data; 183 | ++op_counter; 184 | } 185 | 186 | std::string IBSOS::fetchBlock(int32_t block_id) { 187 | std::string s_id = std::string((const char *)(&block_id), sizeof(int32_t)); 188 | std::string plain; 189 | Util::aes_decrypt(conn->fetch(Util::sha256_hash(s_id, salt)), key, plain); 190 | return plain.substr(sizeof(int32_t)); 191 | } -------------------------------------------------------------------------------- /include/RecursivePartitionORAM.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Dong Xie on 7/16/2016. 3 | // 4 | 5 | #ifndef SEAL_ORAM_RECURSIVEPARTITIONORAM_H 6 | #define SEAL_ORAM_RECURSIVEPARTITIONORAM_H 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include "PartitionORAMInstance.h" 15 | #include "RecursiveTPPartitionORAMInstance.h" 16 | #include "Util.h" 17 | #include "Config.h" 18 | #include "ORAM.h" 19 | #include "MongoConnector.h" 20 | 21 | using namespace CryptoPP; 22 | 23 | template 24 | class RecursivePartitionORAM: public ORAM { 25 | public: 26 | RecursivePartitionORAM(const uint32_t& n, const double& rate); 27 | virtual ~RecursivePartitionORAM(); 28 | 29 | virtual std::string get(const std::string & key); 30 | virtual void put(const std::string & key, const std::string & value); 31 | 32 | virtual std::string get(const uint32_t& block_id); 33 | virtual void put(const uint32_t& block_id, const std::string& data); 34 | private: 35 | /********/ 36 | void evict(uint32_t pid); 37 | /********/ 38 | void sequentialEvict(); 39 | 40 | void access(char op, uint32_t block_id, std::string & data); 41 | 42 | void updatePosMap(const uint32_t& id, const uint32_t& part, const uint32_t& level, const uint32_t& offset); 43 | uint32_t getPosMapPart(const uint32_t& id); 44 | 45 | uint32_t n_blocks; 46 | uint32_t n_partitions; 47 | uint64_t counter; 48 | double rate; 49 | uint32_t cur_partition; 50 | ORAM* pos_map; 51 | uint32_t pos_base = (B - Util::aes_block_size - 2 * sizeof(uint32_t)) / (3 * sizeof(uint32_t)); 52 | 53 | MongoConnector* conn; 54 | 55 | /******/ 56 | std::string *sbuffer; 57 | /******/ 58 | std::unordered_map * slots; 59 | PartitionORAMInstance** partitions; 60 | }; 61 | 62 | template 63 | RecursivePartitionORAM::RecursivePartitionORAM(const uint32_t& n, const double& rate) : ORAM(), n_blocks(n), rate(rate) { 64 | n_partitions = (uint32_t) ceil(sqrt((double) n_blocks)); 65 | uint32_t numofReals = (uint32_t) ceil(((double) n_blocks) / n_partitions); 66 | n_blocks = numofReals * n_partitions; 67 | 68 | conn = new MongoConnector(server_host); 69 | 70 | /******/ 71 | partitions = new PartitionORAMInstance*[n_partitions]; 72 | /******/ 73 | 74 | counter = 0; 75 | cur_partition = 0; 76 | slots = new std::unordered_map[n_partitions]; 77 | 78 | pos_map = new PartitionORAM(n_blocks / pos_base + 1, rate); 79 | 80 | if (numofReals < 6) sbuffer = new std::string[(uint32_t) ceil(small_capacity_parameter * numofReals)]; 81 | else sbuffer = new std::string[(uint32_t) ceil(capacity_parameter * numofReals)]; 82 | 83 | size_t real_ind = 0; 84 | //size_t last_ind = 0; 85 | for (uint32_t i = 0; i < n_partitions; ++i) { 86 | partitions[i] = new T(numofReals, real_ind, i, sbuffer, pos_map, conn); 87 | } 88 | } 89 | 90 | template 91 | RecursivePartitionORAM::~RecursivePartitionORAM() { 92 | for (size_t i = 0; i < n_partitions; ++i) 93 | delete partitions[i]; 94 | delete[] slots; 95 | delete[] partitions; 96 | delete pos_map; 97 | 98 | delete conn; 99 | delete[] sbuffer; 100 | } 101 | 102 | template 103 | std::string RecursivePartitionORAM::get(const std::string & key) { 104 | std::string res; 105 | uint32_t int_key; 106 | sscanf(key.c_str(), "%d", &int_key); 107 | access('r', int_key, res); 108 | return res; 109 | } 110 | 111 | template 112 | void RecursivePartitionORAM::put(const std::string & key, const std::string & value) { 113 | uint32_t int_key; 114 | sscanf(key.c_str(), "%d", &int_key); 115 | std::string value2 = value; 116 | access('w', int_key, value2); 117 | } 118 | 119 | template 120 | std::string RecursivePartitionORAM::get(const uint32_t & key) { 121 | std::string res; 122 | access('r', key, res); 123 | return res; 124 | } 125 | 126 | template 127 | void RecursivePartitionORAM::put(const uint32_t & key, const std::string & value) { 128 | std::string value2 = value; 129 | access('w', key, value2); 130 | } 131 | 132 | template 133 | void RecursivePartitionORAM::evict(uint32_t pid) { 134 | if (!slots[pid].empty()) { 135 | auto got = slots[pid].begin(); 136 | partitions[pid]->put(got->first, got->second); 137 | slots[pid].erase(got); 138 | } else { 139 | std::string dummy = Util::generate_random_block(B - AES::BLOCKSIZE - sizeof(uint32_t)); 140 | int32_t dummyID = -1; 141 | std::string dID = std::string((const char *)(& dummyID), sizeof(uint32_t)); 142 | dummy = dID + dummy; 143 | partitions[pid] -> put(-1, dummy); 144 | } 145 | } 146 | 147 | template 148 | void RecursivePartitionORAM::sequentialEvict() { 149 | if ((uint64_t) (counter * rate) > (uint64_t) ((counter - 1) * rate)) { 150 | evict(cur_partition); 151 | cur_partition = (cur_partition + 1) % n_partitions; 152 | } 153 | } 154 | 155 | template 156 | void RecursivePartitionORAM::access(char op, uint32_t block_id, std::string & data) { 157 | uint32_t r = (uint32_t)Util::rand_int(n_partitions); 158 | uint32_t p = getPosMapPart(block_id); 159 | auto got = slots[p].find(block_id); 160 | std::string data2; 161 | if (got != slots[p].end()) { 162 | data2 = got->second; 163 | slots[p].erase(got); 164 | partitions[p]->get(-1); 165 | } else data2 = partitions[p]->get(block_id); 166 | 167 | updatePosMap(block_id, r, -1, -1); 168 | uint32_t block_id2 = block_id; 169 | std::string bID = std::string((const char*)(& block_id2), sizeof(uint32_t)); 170 | if (op == 'w') data2 = bID + data; 171 | else if (op == 'r') data = data2.substr(sizeof(uint32_t)); 172 | slots[r][block_id] = data2; 173 | 174 | evict(p); 175 | 176 | counter++; 177 | sequentialEvict(); 178 | } 179 | 180 | template 181 | void RecursivePartitionORAM::updatePosMap(const uint32_t& id, const uint32_t& part, const uint32_t& level, const uint32_t& offset) { 182 | std::string cur = pos_map->get(id / pos_base); 183 | cur.replace(sizeof(uint32_t) * 3 * (id % pos_base), sizeof(uint32_t), (const char*)&part, sizeof(uint32_t)); 184 | cur.replace(sizeof(uint32_t) * 3 * (id % pos_base) + sizeof(uint32_t), sizeof(uint32_t), (const char*)&level, sizeof(uint32_t)); 185 | cur.replace(sizeof(uint32_t) * 3 * (id % pos_base) + sizeof(uint32_t) * 2, sizeof(uint32_t), (const char*)&offset, sizeof(uint32_t)); 186 | pos_map->put(id / pos_base, cur); 187 | } 188 | 189 | template 190 | uint32_t RecursivePartitionORAM::getPosMapPart(const uint32_t& id) { 191 | std::string cur = pos_map->get(id / pos_base); 192 | uint32_t ans; 193 | memcpy(&ans, cur.c_str() + sizeof(uint32_t) * 3 * (id % pos_base), sizeof(uint32_t)); 194 | return ans; 195 | } 196 | 197 | #endif //SEAL_ORAM_RECURSIVEPARTITIONORAM_H 198 | -------------------------------------------------------------------------------- /src/RecursivePathORAM.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 by SEAL-ORAM Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | // 18 | // Created by Dong Xie on 7/16/2016. 19 | // 20 | 21 | #include "RecursivePathORAM.h" 22 | 23 | #include 24 | #include 25 | #include "MongoConnector.h" 26 | #include "Util.h" 27 | 28 | using namespace CryptoPP; 29 | 30 | RecursivePathORAM::RecursivePathORAM(const uint32_t& n) { 31 | height = (uint32_t)ceil(log2((double)n)) + 1; 32 | n_blocks = (uint32_t)1 << (height - 1); 33 | stash.clear(); 34 | stash_posmap.clear(); 35 | pos_map = new PathORAM(n / pos_base + 1); 36 | conn = new MongoConnector(server_host, "oram.newrecursivepath"); 37 | 38 | key = new byte[Util::key_length]; 39 | Util::prng.GenerateBlock(key, Util::key_length); 40 | sbuffer = new std::string[height * PathORAM_Z]; 41 | 42 | for (uint32_t i = 0; i < (1 << (height - 1)) - 1; ++i) { 43 | for(size_t j = 0; j < PathORAM_Z; j ++) { 44 | std::string tmp = Util::generate_random_block(B - Util::aes_block_size - sizeof(uint32_t)); 45 | int32_t dummyID = -1; 46 | std::string dID = std::string((const char *)(& dummyID), sizeof(uint32_t)); 47 | std::string cipher; 48 | Util::aes_encrypt(dID + tmp, key, cipher); 49 | conn->insert(i * PathORAM_Z + j, cipher); 50 | } 51 | } 52 | uint32_t cur_id = 0; 53 | for (uint32_t i = (1 << (height - 1)) - 1; i < (1 << height) - 1; ++i) { 54 | if (cur_id < n) { 55 | //need to save pos_map 56 | std::string tmp = Util::generate_random_block(B - Util::aes_block_size - 3 * sizeof(uint32_t)); 57 | std::string bID = std::string((const char *)(& cur_id), sizeof(uint32_t)); 58 | std::string cipher; 59 | Util::aes_encrypt(bID + bID + bID + tmp, key, cipher); 60 | conn->insert(i * PathORAM_Z, cipher); 61 | checkAndUpdatePosMap(cur_id, cur_id); 62 | cur_id ++; 63 | } else { 64 | std::string tmp = Util::generate_random_block(B - Util::aes_block_size - sizeof(uint32_t)); 65 | int32_t dummyID = -1; 66 | std::string dID = std::string((const char *)(& dummyID), sizeof(uint32_t)); 67 | std::string cipher; 68 | Util::aes_encrypt(dID + tmp, key, cipher); 69 | conn->insert(i * PathORAM_Z, cipher); 70 | } 71 | 72 | for(size_t j = 1; j < PathORAM_Z; j ++) { 73 | std::string tmp = Util::generate_random_block(B - Util::aes_block_size - sizeof(uint32_t)); 74 | int32_t dummyID = -1; 75 | std::string dID = std::string((const char *)(& dummyID), sizeof(uint32_t)); 76 | std::string cipher; 77 | Util::aes_encrypt(dID + tmp, key, cipher); 78 | conn->insert(i * PathORAM_Z + j, cipher); 79 | } 80 | } 81 | } 82 | 83 | RecursivePathORAM::~RecursivePathORAM() { 84 | delete pos_map; 85 | delete[] key; 86 | delete[] sbuffer; 87 | delete conn; 88 | } 89 | 90 | std::string RecursivePathORAM::get(const std::string & key) { 91 | std::string res; 92 | uint32_t int_key; 93 | sscanf(key.c_str(), "%d", &int_key); 94 | access('r', int_key, res); 95 | return res; 96 | } 97 | 98 | void RecursivePathORAM::put(const std::string & key, const std::string & value) { 99 | uint32_t int_key; 100 | sscanf(key.c_str(), "%d", &int_key); 101 | std::string value2 = value; 102 | access('w', int_key, value2); 103 | } 104 | 105 | std::string RecursivePathORAM::get(const uint32_t & key) { 106 | std::string res; 107 | access('r', key, res); 108 | return res; 109 | } 110 | 111 | void RecursivePathORAM::put(const uint32_t & key, const std::string & value) { 112 | std::string value2 = value; 113 | access('w', key, value2); 114 | } 115 | 116 | void RecursivePathORAM::access(const char& op, const uint32_t& block_id, std::string& data) { 117 | uint32_t new_x = Util::rand_int(n_blocks); 118 | std::string str_newx = std::string((const char *)(& new_x), sizeof(uint32_t)); 119 | uint32_t x = checkAndUpdatePosMap(block_id, new_x); 120 | 121 | size_t length; 122 | fetchAlongPath(x, sbuffer, length); 123 | for (size_t i = 0; i < length; ++i) { 124 | std::string plain; 125 | Util::aes_decrypt(sbuffer[i], key, plain); 126 | int32_t b_id; 127 | memcpy(&b_id, plain.c_str(), sizeof(uint32_t)); 128 | if (b_id != -1) { 129 | std::string content; 130 | if (b_id == block_id) { 131 | content = plain.substr(sizeof(uint32_t), sizeof(uint32_t)) + str_newx + plain.substr(3 * sizeof(uint32_t)); 132 | } 133 | else content = plain.substr(sizeof(uint32_t)); 134 | stash[b_id] = content; 135 | uint32_t tmp_pos_map; 136 | memcpy(&tmp_pos_map, content.substr(sizeof(uint32_t)).c_str(), sizeof(uint32_t)); 137 | stash_posmap[b_id] = tmp_pos_map; 138 | } 139 | } 140 | 141 | //avoid the case that block_id is not in the retrieved path 142 | stash_posmap[block_id] = new_x; 143 | if (op == 'r') { 144 | data = stash[block_id]; 145 | } 146 | std::string content = data.substr(0, sizeof(uint32_t)) + str_newx + data.substr(2 * sizeof(uint32_t)); 147 | stash[block_id] = content; 148 | 149 | for (uint32_t i = 0; i < height; ++i) { 150 | uint32_t tot = 0; 151 | uint32_t base = i * PathORAM_Z; 152 | std::unordered_map::iterator j, tmp; 153 | j = stash.begin(); 154 | while (j != stash.end() && tot < PathORAM_Z) { 155 | if (check(stash_posmap[j->first], x, i)) { 156 | std::string b_id = std::string((const char *)(&(j->first)), sizeof(uint32_t)); 157 | sbuffer[base + tot] = b_id + j->second; 158 | tmp = j; ++j; 159 | stash_posmap.erase(tmp->first); 160 | stash.erase(tmp); 161 | ++tot; 162 | } else ++j; 163 | } 164 | for (int k = tot; k < PathORAM_Z; ++k) { 165 | std::string tmp_block = Util::generate_random_block(B - Util::aes_block_size - sizeof(uint32_t)); 166 | int32_t dummyID = -1; 167 | std::string dID = std::string((const char *)(& dummyID), sizeof(uint32_t)); 168 | sbuffer[base + k] = dID + tmp_block; 169 | } 170 | } 171 | 172 | for (size_t i = 0; i < height * PathORAM_Z; ++i) { 173 | std::string cipher; 174 | Util::aes_encrypt(sbuffer[i], key, cipher); 175 | sbuffer[i] = cipher; 176 | } 177 | loadAlongPath(x, sbuffer, height * PathORAM_Z); 178 | } 179 | 180 | bool RecursivePathORAM::check(int x, int y, int l) { 181 | return (x >> l) == (y >> l); 182 | } 183 | 184 | void RecursivePathORAM::fetchAlongPath(const uint32_t& x, std::string* sbuffer, size_t& length) { 185 | uint32_t cur_pos = x + (1 << (height - 1)); 186 | std::vector ids; 187 | while (cur_pos > 0) { 188 | for (uint32_t i = 0; i < PathORAM_Z; ++i) 189 | ids.push_back((cur_pos - 1) * PathORAM_Z + i); 190 | cur_pos >>= 1; 191 | } 192 | conn->find(ids, sbuffer, length); 193 | } 194 | 195 | void RecursivePathORAM::loadAlongPath(const uint32_t& x, const std::string* sbuffer, const size_t& length) { 196 | uint32_t cur_pos = x + (1 << (height - 1)); 197 | uint32_t offset = 0; 198 | insert_buffer.clear(); 199 | while (cur_pos > 0) { 200 | for (uint32_t i = 0; i < PathORAM_Z; ++i) 201 | insert_buffer.emplace_back(std::make_pair((cur_pos - 1) * PathORAM_Z + i, sbuffer[offset + i])); 202 | offset += PathORAM_Z; 203 | cur_pos >>= 1; 204 | } 205 | conn->update(insert_buffer); 206 | } 207 | 208 | uint32_t RecursivePathORAM::checkAndUpdatePosMap(const uint32_t& id, const uint32_t& pos) { 209 | std::string cur = pos_map->get(id / pos_base); 210 | uint32_t ans; 211 | memcpy(&ans, cur.c_str() + sizeof(uint32_t) * (id % pos_base), sizeof(uint32_t)); 212 | cur.replace(sizeof(uint32_t) * (id % pos_base), sizeof(uint32_t), (const char*)&pos, sizeof(uint32_t)); 213 | pos_map->put(id / pos_base, cur); 214 | return ans; 215 | } 216 | 217 | uint32_t RecursivePathORAM::getPosMap(const uint32_t& id) { 218 | std::string cur = pos_map->get(id / pos_base); 219 | uint32_t ans; 220 | memcpy(&ans, cur.c_str() + sizeof(uint32_t) * (id % pos_base), sizeof(uint32_t)); 221 | return ans; 222 | } 223 | -------------------------------------------------------------------------------- /src/MongoConnector.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 by SEAL-ORAM Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | // 18 | // Created by Dong Xie on 7/6/2016. 19 | // 20 | 21 | #include 22 | #include "MongoConnector.h" 23 | 24 | MongoConnector::MongoConnector(const std::string& url, const std::string& collection_name, const bool flag) 25 | :ServerConnector(), mongo(), collection_name(collection_name) { 26 | mongo.connect(url); 27 | mongo.createCollection(collection_name); 28 | by_tag = flag; 29 | if (!by_tag) mongo.createIndex(collection_name, BSON("id" << 1)); 30 | else mongo.createIndex(collection_name, BSON("tag" << 1)); 31 | } 32 | 33 | MongoConnector::MongoConnector(const std::string& url) 34 | :ServerConnector(), mongo(), collection_name("") { 35 | mongo.connect(url); 36 | } 37 | 38 | void MongoConnector::initialize(const std::string& ns) { 39 | mongo.createCollection(ns); 40 | mongo.createIndex(ns, BSON("id" << 1)); 41 | } 42 | 43 | 44 | void MongoConnector::finalize(const std::string& ns) { 45 | mongo.dropIndex(ns, BSON("id" << 1)); 46 | mongo.dropCollection(ns); 47 | } 48 | 49 | MongoConnector::~MongoConnector() { 50 | if (collection_name == "") return; 51 | if (!by_tag) mongo.dropIndex(collection_name, BSON("id" << 1)); 52 | else mongo.dropIndex(collection_name, BSON("tag" << 1)); 53 | mongo.dropCollection(collection_name); 54 | } 55 | 56 | void MongoConnector::clear(const std::string& ns) { 57 | std::string mongo_collection = (ns == "") ? collection_name : ns; 58 | mongo.dropCollection(mongo_collection); 59 | mongo.createCollection(mongo_collection); 60 | if (!by_tag) mongo.createIndex(mongo_collection, BSON("id" << 1)); 61 | else mongo.createIndex(mongo_collection, BSON("tag" << 1)); 62 | } 63 | 64 | void MongoConnector::insert(const uint32_t& id, const std::string& encrypted_block, const std::string& ns) { 65 | std::string mongo_collection = (ns == "") ? collection_name : ns; 66 | BinDataType bin_type = BinDataGeneral; 67 | BSONObj obj = BSONObjBuilder().append("id", id) 68 | .appendBinData("data", (int)encrypted_block.size(), bin_type, (const void*)encrypted_block.c_str()).obj(); 69 | mongo.insert(mongo_collection, obj); 70 | } 71 | 72 | void MongoConnector::insert(const std::vector< std::pair >& blocks, const std::string& ns) { 73 | std::string mongo_collection = (ns == "") ? collection_name : ns; 74 | std::vector objs; 75 | BinDataType bin_type = BinDataGeneral; 76 | for (size_t i = 0; i < blocks.size(); ++i) 77 | objs.push_back(BSONObjBuilder().append("id", blocks[i].first) 78 | .appendBinData("data", (int)blocks[i].second.size(), bin_type, 79 | (const void*)blocks[i].second.c_str()).obj()); 80 | mongo.insert(mongo_collection, objs); 81 | } 82 | 83 | void MongoConnector::insert(const std::string* sbuffer, const uint32_t& low, const size_t& len, const std::string& ns) { 84 | std::string mongo_collection = (ns == "") ? collection_name : ns; 85 | std::vector objs; 86 | BinDataType bin_type = BinDataGeneral; 87 | for (uint32_t i = low; i < low + len; ++i) { 88 | objs.push_back(BSONObjBuilder().append("id", i) 89 | .appendBinData("data", (int)sbuffer[i - low].length(), bin_type, 90 | (const void*)sbuffer[i - low].c_str()).obj()); 91 | } 92 | mongo.insert(mongo_collection, objs); 93 | } 94 | 95 | void MongoConnector::insert(const std::vector< std::pair >& blocks, const std::string& ns) { 96 | std::string mongo_collection = (ns == "") ? collection_name : ns; 97 | std::vector objs; 98 | BinDataType bin_type = BinDataGeneral; 99 | for (size_t i = 0; i < blocks.size(); ++i) 100 | objs.push_back(BSONObjBuilder().append("id", blocks[i].first) 101 | .appendBinData("data", (int)blocks[i].second.size(), bin_type, 102 | (const void*)blocks[i].second.c_str()).obj()); 103 | mongo.insert(mongo_collection, objs); 104 | } 105 | 106 | void MongoConnector::insertWithTag(const std::vector< std::pair >& blocks, const std::string& ns) { 107 | std::string mongo_collection = (ns == "") ? collection_name : ns; 108 | std::vector objs; 109 | BinDataType bin_type = BinDataGeneral; 110 | for (uint32_t i = 0; i < blocks.size(); ++i) 111 | objs.push_back(BSONObjBuilder().append("id", blocks[i].first) 112 | .appendBinData("data", (int)blocks[i].second.size(), bin_type, 113 | (const void*)blocks[i].second.c_str()) 114 | .append("tag", i).obj()); 115 | mongo.insert(mongo_collection, objs); 116 | } 117 | 118 | MongoConnector::iterator* MongoConnector::scan() { 119 | return new iterator(std::move((std::unique_ptr)mongo.query(collection_name, BSONObj()))); 120 | } 121 | 122 | std::string MongoConnector::find(const uint32_t& id, const std::string& ns) { 123 | std::string mongo_collection = (ns == "") ? collection_name : ns; 124 | std::unique_ptr cursor = mongo.query(mongo_collection, MONGO_QUERY("id" << id)); 125 | while (cursor->more()) { 126 | BSONObj p = cursor->next(); 127 | int len; 128 | const char* raw_data = p.getField("data").binData(len); 129 | return std::string(raw_data, (size_t)len); 130 | } 131 | return std::string(); 132 | } 133 | 134 | void MongoConnector::find(const std::vector& ids, std::string* sbuffer, size_t& length, const std::string& ns) { 135 | std::string mongo_collection = (ns == "") ? collection_name : ns; 136 | BSONArrayBuilder id_arr; 137 | for (auto item: ids) id_arr.append(item); 138 | std::unique_ptr cursor = mongo.query(mongo_collection, BSON("id" << BSON("$in" << id_arr.arr()))); 139 | length = 0; 140 | while (cursor->more()) { 141 | BSONObj p = cursor->next(); 142 | int block_len; 143 | const char* raw_data = p.getField("data").binData(block_len); 144 | sbuffer[length] = std::string(raw_data, (size_t)block_len); 145 | ++length; 146 | } 147 | } 148 | 149 | std::string MongoConnector::fetch(const std::string& id, const std::string& ns) { 150 | std::string mongo_collection = (ns == "") ? collection_name : ns; 151 | BSONObj p = mongo.findAndRemove(mongo_collection, BSON("id" << id)); 152 | int len; 153 | const char* raw_data = p.getField("data").binData(len); 154 | return std::string(raw_data, (size_t)len); 155 | } 156 | 157 | void MongoConnector::find(const uint32_t& low, const uint32_t& high, std::vector& blocks, const std::string& ns) { 158 | std::string mongo_collection = (ns == "") ? collection_name : ns; 159 | char buf[100]; 160 | sprintf(buf, "{id: {$gte: %d, $lte: %d}}", low, high); 161 | std::unique_ptr cursor = mongo.query(mongo_collection, Query(buf).sort("id")); 162 | while (cursor->more()) { 163 | BSONObj p = cursor->next(); 164 | int len; 165 | const char* raw_data = p.getField("data").binData(len); 166 | blocks.push_back(std::string(raw_data, (size_t)len)); 167 | } 168 | } 169 | 170 | void MongoConnector::findByTag(const uint32_t& tag, std::string* sbuffer, size_t& length, const std::string& ns) { 171 | std::string mongo_collection = (ns == "") ? collection_name : ns; 172 | std::unique_ptr cursor = mongo.query(mongo_collection, MONGO_QUERY("tag" << tag)); 173 | length = 0; 174 | while (cursor->more()) { 175 | BSONObj p = cursor->next(); 176 | int len; 177 | const char* raw_data = p.getField("data").binData(len); 178 | sbuffer[length] = std::string(raw_data, (size_t) len); 179 | length++; 180 | } 181 | } 182 | 183 | void MongoConnector::update(const uint32_t& id, const std::string& data, const std::string& ns) { 184 | std::string mongo_collection = (ns == "") ? collection_name : ns; 185 | BinDataType bin_type = BinDataGeneral; 186 | mongo.update(mongo_collection, BSON("id" << id), 187 | BSON("$set" << BSONObjBuilder().appendBinData("data", (int)data.length(), bin_type, 188 | (const void*)data.c_str()).obj())); 189 | } 190 | 191 | void MongoConnector::update(const std::string* sbuffer, const uint32_t& low, const size_t& len, const std::string& ns) { 192 | std::string mongo_collection = (ns == "") ? collection_name : ns; 193 | char buf[100]; 194 | sprintf(buf, "{id: {$gte: %d, $lte: %ld}}", low, low + len - 1); 195 | mongo.remove(mongo_collection, Query(buf)); 196 | insert(sbuffer, low, len, ns); 197 | } 198 | 199 | void MongoConnector::update(const std::vector< std::pair > blocks, const std::string& ns) { 200 | std::string mongo_collection = (ns == "") ? collection_name : ns; 201 | BSONArrayBuilder id_arr; 202 | for (auto item: blocks) id_arr.append(item.first); 203 | mongo.remove(mongo_collection, BSON("id" << BSON("$in" << id_arr.arr()))); 204 | insert(blocks); 205 | } -------------------------------------------------------------------------------- /src/TPPartitionORAMInstance.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 by SEAL-ORAM Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | // 18 | // Created by Dong Xie on 7/13/2016. 19 | // 20 | 21 | #include "TPPartitionORAMInstance.h" 22 | #include "Util.h" 23 | #include "MongoConnector.h" 24 | 25 | using namespace CryptoPP; 26 | 27 | TPPartitionORAMInstance::TPPartitionORAMInstance(const uint32_t& numofReals, size_t& real_ind, 28 | const uint32_t& PID, std::string* s_buffer, Position* p_map, 29 | MongoConnector * Conn) 30 | : PartitionORAMInstance(), PID(PID), pos_map(p_map) { 31 | n_levels = (uint32_t) (log((double) numofReals) / log(2.0)) + 1; 32 | if (numofReals < 6) capacity = (uint32_t)ceil(small_capacity_parameter * numofReals); 33 | else capacity = (uint32_t) ceil(capacity_parameter * numofReals); 34 | top_level_len = capacity - (1 << n_levels) + 2; 35 | flag = new bool[capacity]; 36 | sbuffer = s_buffer; 37 | key = new byte[n_levels * AES::DEFAULT_KEYLENGTH]; 38 | Util::prng.GenerateBlock(key, n_levels * AES::DEFAULT_KEYLENGTH); 39 | dummy = new uint32_t[(1 << n_levels) - 1]; 40 | filled = new bool[n_levels]; 41 | counter = 0; 42 | 43 | memset(flag, false, sizeof(bool) * capacity); 44 | char buf[100]; 45 | sprintf(buf, "oram.test%d", PID); 46 | 47 | ns = std::string(buf); 48 | conn = Conn; 49 | conn->initialize(ns); 50 | 51 | for (uint32_t i = 0; i < n_levels - 1; ++i) { 52 | for (uint32_t j = 0; j < (1 << (i + 1)); ++j) { 53 | sbuffer[j] = Util::generate_random_block(B - AES::BLOCKSIZE - sizeof(uint32_t)); 54 | int32_t dummyID = -1; 55 | std::string dID = std::string((const char *)(& dummyID), sizeof(uint32_t)); 56 | sbuffer[j] = dID + sbuffer[j]; 57 | dummy[(1 << i) - 1 + j] = j; 58 | } 59 | 60 | Util::psuedo_random_permute(&(dummy[(1 << i) - 1]), (size_t)(1 << (i + 1))); 61 | 62 | for (uint32_t j = 0; j < (1 << (i + 1)); ++j) { 63 | std::string cipher; 64 | Util::aes_encrypt(sbuffer[j], &(key[i * AES::DEFAULT_KEYLENGTH]), cipher); 65 | sbuffer[j] = cipher; 66 | } 67 | 68 | loadLevel(i, sbuffer, (size_t)(1 << (i + 1)), true); 69 | } 70 | 71 | for(uint32_t k = 0; k < numofReals; k ++) { 72 | sbuffer[k] = Util::generate_random_block(B - AES::BLOCKSIZE - 2 * sizeof(uint32_t)); 73 | std::string dID = std::string((const char *)(& real_ind), sizeof(uint32_t)); 74 | sbuffer[k] = dID + dID + sbuffer[k]; 75 | 76 | real_ind ++; 77 | } 78 | 79 | for(uint32_t k = numofReals; k < top_level_len; k ++) { 80 | sbuffer[k] = Util::generate_random_block(B - AES::BLOCKSIZE - sizeof(uint32_t)); 81 | int32_t dummyID = -1 + numofReals - k; 82 | std::string dID = std::string((const char *)(& dummyID), sizeof(uint32_t)); 83 | sbuffer[k] = dID + sbuffer[k]; 84 | } 85 | Util::psuedo_random_permute(sbuffer, top_level_len); 86 | 87 | for(uint32_t k = 0; k < top_level_len; k ++) { 88 | std::string bID = sbuffer[k].substr(0, sizeof(uint32_t)); 89 | int32_t bID2; 90 | memcpy(&bID2, bID.c_str(), sizeof(uint32_t)); 91 | if (bID2 < 0) { 92 | if (bID2 >= -(1 << (n_levels - 1))) 93 | dummy[((1 << (n_levels - 1)) - 1) - bID2 - 1] = k; 94 | int32_t dummyID2 = -1; 95 | sbuffer[k] = std::string((const char*)(& dummyID2), sizeof(uint32_t)) + sbuffer[k].substr(sizeof(uint32_t)); 96 | } else { 97 | pos_map[bID2].part = PID; 98 | pos_map[bID2].level = n_levels - 1; 99 | pos_map[bID2].offset = k; 100 | } 101 | std::string cipher; 102 | Util::aes_encrypt(sbuffer[k], &(key[(n_levels - 1) * AES::DEFAULT_KEYLENGTH]), cipher); 103 | sbuffer[k] = cipher; 104 | } 105 | 106 | loadLevel(n_levels - 1, sbuffer, top_level_len, true); 107 | 108 | memset(filled, false, sizeof(bool) * (n_levels - 1)); 109 | filled[n_levels- 1] = true; 110 | } 111 | 112 | TPPartitionORAMInstance::~TPPartitionORAMInstance() { 113 | delete[] flag; 114 | conn->finalize(ns); 115 | delete[] key; 116 | delete[] dummy; 117 | delete[] filled; 118 | } 119 | 120 | std::string TPPartitionORAMInstance::get(const int32_t& block_id) { 121 | std::string res; 122 | for (uint32_t l = 0; l < n_levels; l ++) { 123 | if (filled[l]) { 124 | if (block_id != -1 && pos_map[block_id].level == l) { 125 | std::string cipher; 126 | cipher = readBlock(l, pos_map[block_id].offset); 127 | Util::aes_decrypt(cipher, &(key[l * AES::DEFAULT_KEYLENGTH]), res); 128 | 129 | } else readBlock(l, dummy[(1 << l) - 1 + (counter % (1 << l))]); 130 | } 131 | } 132 | //pos_map.erase(block_id); 133 | return res; 134 | } 135 | 136 | void TPPartitionORAMInstance::put(const int32_t& block_id, const std::string& data) { 137 | uint32_t level = n_levels - 1; 138 | for (uint32_t l = 0; l < n_levels - 1; ++l) { 139 | if (!filled[l]) { 140 | level = l - 1; 141 | break; 142 | } 143 | } 144 | uint32_t begin_id = 0; 145 | uint32_t cur_id = begin_id; 146 | int32_t dID; 147 | size_t length; 148 | if (level != -1) { 149 | for (uint32_t l = 0; l <= level; l ++) { 150 | fetchLevel(l, sbuffer, begin_id, length); 151 | cur_id = begin_id; 152 | for (size_t i = begin_id; i < begin_id + length; i ++) { 153 | std::string plainBlocks; 154 | Util::aes_decrypt(sbuffer[i], &(key[l * AES::DEFAULT_KEYLENGTH]), plainBlocks); 155 | sbuffer[i] = plainBlocks; 156 | memcpy(&dID, sbuffer[i].c_str(), sizeof(uint32_t)); 157 | if (pos_map[dID].part == PID && dID != -1 && dID != block_id && pos_map[dID].level == l) { 158 | sbuffer[cur_id] = sbuffer[i]; 159 | cur_id ++; 160 | } 161 | } 162 | begin_id = cur_id; 163 | } 164 | } 165 | sbuffer[cur_id] = data; 166 | cur_id++; 167 | if (level != n_levels - 1) ++level; 168 | //AutoSeededRandomPool prng; 169 | Util::prng.GenerateBlock(&(key[level * Util::key_length]), Util::key_length); 170 | size_t sbuffer_len; 171 | if (level != n_levels - 1) sbuffer_len = (size_t)(1 << (level + 1)); 172 | else sbuffer_len = top_level_len; 173 | for (uint32_t i = cur_id; i < sbuffer_len; i ++) { 174 | sbuffer[i] = Util::generate_random_block(B - AES::BLOCKSIZE - sizeof(uint32_t)); 175 | int32_t dummyID = cur_id - i - 1; 176 | std::string s_id = std::string((const char *)(& dummyID), sizeof(uint32_t)); 177 | sbuffer[i] = s_id + sbuffer[i]; 178 | } 179 | Util::psuedo_random_permute(sbuffer, sbuffer_len); 180 | 181 | for (uint32_t i = 0; i < sbuffer_len; i ++) { 182 | std::string bID = sbuffer[i].substr(0, sizeof(uint32_t)); 183 | int32_t bID2; 184 | memcpy(&bID2, bID.c_str(), sizeof(uint32_t)); 185 | if (bID2 < 0) { 186 | if (bID2 >= -(1 << level)) dummy[((1 << level) - 1) - bID2 - 1] = i; 187 | int32_t s_id = -1; 188 | sbuffer[i] = std::string((const char*)(& s_id), sizeof(uint32_t)) + sbuffer[i].substr(sizeof(uint32_t)); 189 | } else { 190 | pos_map[bID2].part = PID; 191 | pos_map[bID2].level = level; 192 | pos_map[bID2].offset = i; 193 | } 194 | 195 | std::string cipher; 196 | Util::aes_encrypt(sbuffer[i], &(key[level * AES::DEFAULT_KEYLENGTH]), cipher); 197 | sbuffer[i] = cipher; 198 | } 199 | 200 | loadLevel(level, sbuffer, sbuffer_len, false); 201 | 202 | for (size_t i = 0; i < level; i ++) 203 | filled[i] = false; 204 | filled[level] = true; 205 | counter = (counter + 1) % (1 << (n_levels - 1)); 206 | } 207 | 208 | std::string TPPartitionORAMInstance::readBlock(uint32_t level, uint32_t offset) { 209 | uint32_t index = (1 << (level + 1)) - 2 + offset; 210 | flag[index] = true; 211 | return conn->find(index, ns); 212 | } 213 | 214 | void TPPartitionORAMInstance::fetchLevel(uint32_t level, std::string* sbuffer, uint32_t beginIndex, size_t & length) { 215 | uint32_t begin = (uint32_t)(1 << (level + 1)) - 2; 216 | uint32_t end; 217 | if (level != n_levels - 1) { 218 | end = begin + (1 << (level + 1)); 219 | } else end = capacity; 220 | 221 | std::vector blocks; 222 | 223 | conn->find(begin, end - 1, blocks, ns); 224 | 225 | length = 0; 226 | for (size_t i = 0; i < blocks.size(); i ++) 227 | if (!(flag[begin + i])) { 228 | sbuffer[beginIndex + length] = blocks[i]; 229 | length++; 230 | } 231 | memset(&(flag[begin]), false, sizeof(bool) * (end - begin)); 232 | } 233 | 234 | void TPPartitionORAMInstance::loadLevel(uint32_t level, std::string * sbuffer, size_t length, bool insert) { 235 | uint32_t begin = (uint32_t)(1 << (level + 1)) - 2; 236 | 237 | if (insert) conn->insert(sbuffer, begin, length, ns); 238 | else conn->update(sbuffer, begin, length, ns); 239 | 240 | memset(flag, false, sizeof(bool) * length); 241 | } 242 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | -------------------------------------------------------------------------------- /src/RecursiveTPPartitionORAMInstance.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Dong Xie on 7/16/2016. 3 | // 4 | 5 | #include "RecursiveTPPartitionORAMInstance.h" 6 | #include "Util.h" 7 | #include "MongoConnector.h" 8 | 9 | using namespace CryptoPP; 10 | 11 | RecursiveTPPartitionORAMInstance::RecursiveTPPartitionORAMInstance(const uint32_t& numofReals, size_t& real_ind, 12 | const uint32_t& PID, std::string* s_buffer, 13 | ORAM* p_map, MongoConnector * Conn) 14 | : PartitionORAMInstance(), PID(PID), pos_map(p_map) { 15 | n_levels = (uint32_t) (log((double) numofReals) / log(2.0)) + 1; 16 | if (numofReals < 6) capacity = (uint32_t)ceil(small_capacity_parameter * numofReals); 17 | else capacity = (uint32_t) ceil(capacity_parameter * numofReals); 18 | top_level_len = capacity - (1 << n_levels) + 2; 19 | flag = new bool[capacity]; 20 | sbuffer = s_buffer; 21 | key = new byte[n_levels * AES::DEFAULT_KEYLENGTH]; 22 | Util::prng.GenerateBlock(key, n_levels * AES::DEFAULT_KEYLENGTH); 23 | dummy = new uint32_t[(1 << n_levels) - 1]; 24 | filled = new bool[n_levels]; 25 | counter = 0; 26 | 27 | memset(flag, false, sizeof(bool) * capacity); 28 | char buf[100]; 29 | sprintf(buf, "oram.recursive_test%d", PID); 30 | 31 | ns = std::string(buf); 32 | conn = Conn; 33 | conn->initialize(ns); 34 | for (uint32_t i = 0; i < n_levels - 1; ++i) { 35 | for (uint32_t j = 0; j < (1 << (i + 1)); ++j) { 36 | sbuffer[j] = Util::generate_random_block(B - AES::BLOCKSIZE - sizeof(uint32_t)); 37 | int32_t dummyID = -1; 38 | std::string dID = std::string((const char *)(& dummyID), sizeof(uint32_t)); 39 | sbuffer[j] = dID + sbuffer[j]; 40 | dummy[(1 << i) - 1 + j] = j; 41 | } 42 | 43 | Util::psuedo_random_permute(&(dummy[(1 << i) - 1]), (size_t)(1 << (i + 1))); 44 | 45 | for (uint32_t j = 0; j < (1 << (i + 1)); ++j) { 46 | std::string cipher; 47 | Util::aes_encrypt(sbuffer[j], &(key[i * AES::DEFAULT_KEYLENGTH]), cipher); 48 | sbuffer[j] = cipher; 49 | } 50 | 51 | loadLevel(i, sbuffer, (size_t)(1 << (i + 1)), true); 52 | } 53 | 54 | for(uint32_t k = 0; k < numofReals; k ++) { 55 | sbuffer[k] = Util::generate_random_block(B - AES::BLOCKSIZE - 2 * sizeof(uint32_t)); 56 | std::string dID = std::string((const char *)(& real_ind), sizeof(uint32_t)); 57 | sbuffer[k] = dID + dID + sbuffer[k]; 58 | 59 | real_ind ++; 60 | } 61 | 62 | for(uint32_t k = numofReals; k < top_level_len; k ++) { 63 | sbuffer[k] = Util::generate_random_block(B - AES::BLOCKSIZE - sizeof(uint32_t)); 64 | int32_t dummyID = -1 + numofReals - k; 65 | std::string dID = std::string((const char *)(& dummyID), sizeof(uint32_t)); 66 | sbuffer[k] = dID + sbuffer[k]; 67 | } 68 | Util::psuedo_random_permute(sbuffer, top_level_len); 69 | 70 | for(uint32_t k = 0; k < top_level_len; k ++) { 71 | std::string bID = sbuffer[k].substr(0, sizeof(uint32_t)); 72 | int32_t bID2; 73 | memcpy(&bID2, bID.c_str(), sizeof(uint32_t)); 74 | if (bID2 < 0) { 75 | if (bID2 >= -(1 << (n_levels - 1))) 76 | dummy[((1 << (n_levels - 1)) - 1) - bID2 - 1] = k; 77 | int32_t dummyID2 = -1; 78 | sbuffer[k] = std::string((const char*)(& dummyID2), sizeof(uint32_t)) + sbuffer[k].substr(sizeof(uint32_t)); 79 | } 80 | else updatePosMap(bID2, PID, n_levels - 1, k); 81 | 82 | std::string cipher; 83 | Util::aes_encrypt(sbuffer[k], &(key[(n_levels - 1) * AES::DEFAULT_KEYLENGTH]), cipher); 84 | sbuffer[k] = cipher; 85 | } 86 | 87 | loadLevel(n_levels - 1, sbuffer, top_level_len, true); 88 | 89 | memset(filled, false, sizeof(bool) * (n_levels - 1)); 90 | filled[n_levels- 1] = true; 91 | } 92 | 93 | RecursiveTPPartitionORAMInstance::~RecursiveTPPartitionORAMInstance() { 94 | delete[] flag; 95 | 96 | conn->finalize(ns); 97 | 98 | delete[] key; 99 | delete[] dummy; 100 | delete[] filled; 101 | } 102 | 103 | std::string RecursiveTPPartitionORAMInstance::get(const int32_t& block_id) { 104 | uint32_t cur_part, cur_level, cur_offset; 105 | getPosMap(block_id, cur_part, cur_level, cur_offset); 106 | 107 | std::string res; 108 | for (uint32_t l = 0; l < n_levels; l ++) { 109 | if (filled[l]) { 110 | if (block_id != -1 && cur_level == l) { 111 | std::string cipher = readBlock(l, cur_offset); 112 | Util::aes_decrypt(cipher, &(key[l * AES::DEFAULT_KEYLENGTH]), res); 113 | } else readBlock(l, dummy[(1 << l) - 1 + (counter % (1 << l))]); 114 | } 115 | } 116 | return res; 117 | } 118 | 119 | void RecursiveTPPartitionORAMInstance::put(const int32_t& block_id, const std::string& data) { 120 | uint32_t level = n_levels - 1; 121 | for (uint32_t l = 0; l < n_levels - 1; ++l) { 122 | if (!filled[l]) { 123 | level = l - 1; 124 | break; 125 | } 126 | } 127 | uint32_t begin_id = 0; 128 | uint32_t cur_id = begin_id; 129 | int32_t dID; 130 | size_t length; 131 | if (level != -1) { 132 | for (uint32_t l = 0; l <= level; l ++) { 133 | fetchLevel(l, sbuffer, begin_id, length); 134 | cur_id = begin_id; 135 | 136 | uint32_t cur_part, cur_level, cur_offset; 137 | 138 | uint32_t n_getPosMaps = 0; 139 | for (size_t i = begin_id; i < begin_id + length; i ++) { 140 | std::string plainBlocks; 141 | Util::aes_decrypt(sbuffer[i], &(key[l * AES::DEFAULT_KEYLENGTH]), plainBlocks); 142 | sbuffer[i] = plainBlocks; 143 | memcpy(&dID, sbuffer[i].c_str(), sizeof(uint32_t)); 144 | if (dID != -1 && dID != block_id) { 145 | getPosMap(dID, cur_part, cur_level, cur_offset); 146 | n_getPosMaps ++; 147 | if (cur_part == PID && cur_level == l) { 148 | sbuffer[cur_id] = sbuffer[i]; 149 | cur_id ++; 150 | } 151 | } 152 | } 153 | begin_id = cur_id; 154 | 155 | uint32_t level_length; 156 | if(l < n_levels) 157 | level_length = 1 << l; 158 | else level_length = top_level_len; 159 | int32_t dummyInt = -1; 160 | while (n_getPosMaps <= (level_length + 1) / 2) { 161 | getPosMap(dummyInt, cur_part, cur_level, cur_offset); 162 | n_getPosMaps ++; 163 | } 164 | } 165 | } 166 | sbuffer[cur_id] = data; 167 | cur_id++; 168 | if (level != n_levels - 1) ++level; 169 | Util::prng.GenerateBlock(&(key[level * Util::key_length]), Util::key_length); 170 | size_t sbuffer_len; 171 | if (level != n_levels - 1) sbuffer_len = (size_t)(1 << (level + 1)); 172 | else sbuffer_len = top_level_len; 173 | for (uint32_t i = cur_id; i < sbuffer_len; i ++) { 174 | sbuffer[i] = Util::generate_random_block(B - AES::BLOCKSIZE - sizeof(uint32_t)); 175 | int32_t dummyID = cur_id - i - 1; 176 | std::string s_id = std::string((const char *)(& dummyID), sizeof(uint32_t)); 177 | sbuffer[i] = s_id + sbuffer[i]; 178 | } 179 | Util::psuedo_random_permute(sbuffer, sbuffer_len); 180 | 181 | 182 | uint32_t n_updatePosMaps = 0; 183 | for (uint32_t i = 0; i < sbuffer_len; i ++) { 184 | std::string bID = sbuffer[i].substr(0, sizeof(uint32_t)); 185 | int32_t bID2; 186 | memcpy(&bID2, bID.c_str(), sizeof(uint32_t)); 187 | if (bID2 < 0) { 188 | if (bID2 >= -(1 << level)) dummy[((1 << level) - 1) - bID2 - 1] = i; 189 | int32_t s_id = -1; 190 | sbuffer[i] = std::string((const char*)(& s_id), sizeof(uint32_t)) + sbuffer[i].substr(sizeof(uint32_t)); 191 | } 192 | else { 193 | updatePosMap(bID2, PID, level, i); 194 | n_updatePosMaps ++; 195 | } 196 | 197 | std::string cipher; 198 | Util::aes_encrypt(sbuffer[i], &(key[level * AES::DEFAULT_KEYLENGTH]), cipher); 199 | sbuffer[i] = cipher; 200 | } 201 | 202 | uint32_t level_length; 203 | if(level < n_levels) 204 | level_length = 1 << level; 205 | else level_length = top_level_len; 206 | int32_t dummyInt = -1; 207 | while (n_updatePosMaps <= (level_length + 1) / 2) { 208 | updatePosMap(dummyInt, dummyInt, dummyInt, dummyInt); 209 | n_updatePosMaps ++; 210 | } 211 | 212 | loadLevel(level, sbuffer, sbuffer_len, false); 213 | 214 | for (size_t i = 0; i < level; i ++) 215 | filled[i] = false; 216 | filled[level] = true; 217 | counter = (counter + 1) % (1 << (n_levels - 1)); 218 | } 219 | 220 | std::string RecursiveTPPartitionORAMInstance::readBlock(uint32_t level, uint32_t offset) { 221 | uint32_t index = (1 << (level + 1)) - 2 + offset; 222 | flag[index] = true; 223 | return conn->find(index, ns);; 224 | } 225 | 226 | void RecursiveTPPartitionORAMInstance::fetchLevel(uint32_t level, std::string* sbuffer, uint32_t beginIndex, size_t & length) { 227 | uint32_t begin = (uint32_t)(1 << (level + 1)) - 2; 228 | uint32_t end; 229 | if (level != n_levels - 1) { 230 | end = begin + (1 << (level + 1)); 231 | } else end = capacity; 232 | 233 | std::vector blocks; 234 | conn->find(begin, end - 1, blocks, ns); 235 | 236 | length = 0; 237 | for (size_t i = 0; i < blocks.size(); i ++) 238 | if (!(flag[begin + i])) { 239 | sbuffer[beginIndex + length] = blocks[i]; 240 | length++; 241 | } 242 | memset(&(flag[begin]), false, sizeof(bool) * (end - begin)); 243 | } 244 | 245 | void RecursiveTPPartitionORAMInstance::loadLevel(uint32_t level, std::string * sbuffer, size_t length, bool insert) { 246 | uint32_t begin = (uint32_t)(1 << (level + 1)) - 2; 247 | 248 | if (insert) conn->insert(sbuffer, begin, length, ns); 249 | else conn->update(sbuffer, begin, length, ns); 250 | 251 | memset(flag, false, sizeof(bool) * length); 252 | } 253 | 254 | void RecursiveTPPartitionORAMInstance::updatePosMap(const uint32_t& id, const uint32_t& part, const uint32_t& level, const uint32_t& offset) { 255 | int32_t ID = id; 256 | if(ID >= 0) { 257 | std::string cur = pos_map->get(id / pos_base); 258 | cur.replace(sizeof(uint32_t) * 3 * (id % pos_base), sizeof(uint32_t), (const char*)&part, sizeof(uint32_t)); 259 | cur.replace(sizeof(uint32_t) * 3 * (id % pos_base) + sizeof(uint32_t), sizeof(uint32_t), (const char*)&level, sizeof(uint32_t)); 260 | cur.replace(sizeof(uint32_t) * 3 * (id % pos_base) + sizeof(uint32_t) * 2, sizeof(uint32_t), (const char*)&offset, sizeof(uint32_t)); 261 | pos_map->put(id / pos_base, cur); 262 | } 263 | else{ 264 | uint32_t dummyInt = -1; 265 | getPosMap(ID, dummyInt, dummyInt, dummyInt); 266 | } 267 | } 268 | 269 | void RecursiveTPPartitionORAMInstance::getPosMap(const uint32_t& id, uint32_t& part, uint32_t& level, uint32_t& offset) { 270 | int32_t ID = id; 271 | if(ID >= 0) { 272 | std::string cur = pos_map->get(id / pos_base); 273 | memcpy(&part, cur.c_str() + sizeof(uint32_t) * 3 * (id % pos_base), sizeof(uint32_t)); 274 | memcpy(&level, cur.c_str() + sizeof(uint32_t) * 3 * (id % pos_base) + sizeof(uint32_t), sizeof(uint32_t)); 275 | memcpy(&offset, cur.c_str() + sizeof(uint32_t) * 3 * (id % pos_base) + sizeof(uint32_t) * 2, sizeof(uint32_t)); 276 | } 277 | else { 278 | pos_map->get(0); 279 | } 280 | } 281 | -------------------------------------------------------------------------------- /src/BinaryORAM.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 by SEAL-ORAM Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | // 18 | // Created by Dong Xie on 7/10/2016. 19 | // 20 | 21 | #include "BinaryORAM.h" 22 | 23 | #include 24 | #include 25 | #include "MongoConnector.h" 26 | #include "Config.h" 27 | 28 | using namespace CryptoPP; 29 | 30 | BinaryORAM::BinaryORAM(const uint32_t& n) { 31 | height = (uint32_t)ceil(log2((double) n)) + 1; 32 | n_buckets = (uint32_t)1 << (height - 1); 33 | bucket_size = Alpha * (uint32_t)ceil(log2((double)n)); 34 | 35 | pos_map = new uint32_t[n]; 36 | conn = new MongoConnector(server_host, "oram.binary"); 37 | 38 | key = new byte[Util::key_length]; 39 | Util::prng.GenerateBlock(key, Util::key_length); 40 | sbuffer = new std::string[2]; 41 | 42 | for (uint32_t i = 0; i < (1 << (height - 1)) - 1; ++i) { 43 | for(size_t j = 0; j < bucket_size; j ++) { 44 | std::string tmp = Util::generate_random_block(B - Util::aes_block_size - sizeof(uint32_t)); 45 | int32_t dummyID = -1; 46 | std::string dID = std::string((const char *)(& dummyID), sizeof(uint32_t)); 47 | std::string cipher; 48 | Util::aes_encrypt(dID + tmp, key, cipher); 49 | conn->insert(i * bucket_size + j, cipher); 50 | } 51 | } 52 | uint32_t cur_id = 0; 53 | for (uint32_t i = (1 << (height - 1)) - 1; i < (1 << height) - 1; ++i) { 54 | if(cur_id < n) { 55 | std::string tmp = Util::generate_random_block(B - Util::aes_block_size - 2 * sizeof(uint32_t)); 56 | std::string bID = std::string((const char *)(& cur_id), sizeof(uint32_t)); 57 | std::string cipher; 58 | Util::aes_encrypt(bID + bID + tmp, key, cipher); 59 | conn->insert(i * bucket_size, cipher); 60 | pos_map[cur_id] = cur_id; 61 | cur_id ++; 62 | } 63 | else { 64 | std::string tmp = Util::generate_random_block(B - Util::aes_block_size - sizeof(uint32_t)); 65 | int32_t dummyID = -1; 66 | std::string dID = std::string((const char *)(& dummyID), sizeof(uint32_t)); 67 | std::string cipher; 68 | Util::aes_encrypt(dID + tmp, key, cipher); 69 | conn->insert(i * bucket_size, cipher); 70 | } 71 | for(size_t j = 1; j < bucket_size; j ++) { 72 | std::string tmp = Util::generate_random_block(B - Util::aes_block_size - sizeof(uint32_t)); 73 | int32_t dummyID = -1; 74 | std::string dID = std::string((const char *)(& dummyID), sizeof(uint32_t)); 75 | std::string cipher; 76 | Util::aes_encrypt(dID + tmp, key, cipher); 77 | conn->insert(i * bucket_size + j, cipher); 78 | } 79 | } 80 | } 81 | 82 | BinaryORAM::~BinaryORAM() { 83 | delete[] key; 84 | delete[] sbuffer; 85 | delete[] pos_map; 86 | delete conn; 87 | } 88 | 89 | std::string BinaryORAM::get(const std::string & key) { 90 | std::string res; 91 | uint32_t int_key; 92 | sscanf(key.c_str(), "%d", &int_key); 93 | access('r', int_key, res); 94 | return res; 95 | } 96 | 97 | void BinaryORAM::put(const std::string & key, const std::string & value) { 98 | uint32_t int_key; 99 | sscanf(key.c_str(), "%d", &int_key); 100 | std::string value2 = value; 101 | access('w', int_key, value2); 102 | } 103 | 104 | std::string BinaryORAM::get(const uint32_t & key) { 105 | std::string res; 106 | access('r', key, res); 107 | return res; 108 | } 109 | 110 | void BinaryORAM::put(const uint32_t & key, const std::string & value) { 111 | std::string value2 = value; 112 | access('w', key, value2); 113 | } 114 | 115 | void BinaryORAM::access(const char& op, const uint32_t& block_id, std::string& data) { 116 | uint32_t x = pos_map[block_id]; 117 | pos_map[block_id] = Util::rand_int(n_buckets); 118 | 119 | fetchAlongPath(block_id, x); 120 | 121 | if (op == 'r') { 122 | data = sbuffer[0].substr(sizeof(uint32_t)); 123 | } 124 | else { 125 | std::string blockID = std::string((const char *)(& block_id), sizeof(uint32_t)); 126 | sbuffer[0] = blockID + data; 127 | } 128 | 129 | bool find = false; 130 | for (uint32_t i = 0; i < bucket_size; ++ i) { 131 | readBlock(0, 0, i); 132 | 133 | std::string plain; 134 | Util::aes_decrypt(sbuffer[1], key, plain); 135 | 136 | if(!find) { 137 | int32_t b_id; 138 | memcpy(&b_id, plain.c_str(), sizeof(uint32_t)); 139 | if (b_id != -1) { 140 | std::string cipher; 141 | Util::aes_encrypt(plain, key, cipher); 142 | 143 | sbuffer[1] = cipher; 144 | writeBlock(0, 0, i); 145 | } 146 | else { 147 | find = true; 148 | 149 | std::string cipher; 150 | Util::aes_encrypt(sbuffer[0], key, cipher); 151 | 152 | sbuffer[1] = cipher; 153 | writeBlock(0, 0, i); 154 | } 155 | } 156 | else { 157 | std::string cipher; 158 | Util::aes_encrypt(plain, key, cipher); 159 | 160 | sbuffer[1] = cipher; 161 | writeBlock(0, 0, i); 162 | } 163 | } 164 | 165 | evict(); 166 | } 167 | 168 | void BinaryORAM::readBlock(const uint32_t level, const uint32_t bucket, const uint32_t piece) { 169 | uint32_t bid = ((1 << level) - 1 + bucket) * bucket_size + piece; 170 | sbuffer[1] = conn->find(bid); 171 | } 172 | 173 | void BinaryORAM::writeBlock(const uint32_t level, const uint32_t bucket, const uint32_t piece) { 174 | uint32_t bid = ((1 << level) - 1 + bucket) * bucket_size + piece; 175 | conn->update(bid, sbuffer[1]); 176 | } 177 | 178 | void BinaryORAM::fetchAlongPath(const uint32_t& block_id, const uint32_t& x) { 179 | bool find = false; 180 | uint32_t cur_pos = x + (1 << (height - 1)); 181 | while (cur_pos > 0) { 182 | uint32_t id = (cur_pos - 1) * bucket_size; 183 | for (uint32_t i = 0; i < bucket_size; ++ i) { 184 | sbuffer[1] = conn->find(id + i); 185 | 186 | std::string plain; 187 | Util::aes_decrypt(sbuffer[1], key, plain); 188 | 189 | if(!find) { 190 | int32_t b_id; 191 | memcpy(&b_id, plain.c_str(), sizeof(uint32_t)); 192 | 193 | if (b_id != block_id) { 194 | std::string cipher; 195 | Util::aes_encrypt(plain, key, cipher); 196 | conn->update(id + i, cipher); 197 | } 198 | else { 199 | find = true; 200 | sbuffer[0] = plain; 201 | 202 | std::string plain = Util::generate_random_block(B - Util::aes_block_size - sizeof(uint32_t)); 203 | int32_t dummyID = -1; 204 | std::string dID = std::string((const char *)(& dummyID), sizeof(uint32_t)); 205 | std::string cipher; 206 | Util::aes_encrypt(dID + plain, key, cipher); 207 | conn->update(id + i, cipher); 208 | } 209 | } 210 | else { 211 | std::string cipher; 212 | Util::aes_encrypt(plain, key, cipher); 213 | conn->update(id + i, cipher); 214 | } 215 | } 216 | cur_pos >>= 1; 217 | } 218 | } 219 | 220 | void BinaryORAM::evict(const uint32_t level, const uint32_t bucket) { 221 | bool find = false; 222 | int32_t blockID = -1; 223 | 224 | //read 225 | for(uint32_t piece = 0; piece < bucket_size; piece ++) { 226 | readBlock(level, bucket, piece); 227 | 228 | std::string plain; 229 | Util::aes_decrypt(sbuffer[1], key, plain); 230 | 231 | if(!find) { 232 | int32_t b_id; 233 | memcpy(&b_id, plain.c_str(), sizeof(uint32_t)); 234 | if (b_id == -1) { 235 | std::string cipher; 236 | Util::aes_encrypt(plain, key, cipher); 237 | 238 | sbuffer[1] = cipher; 239 | writeBlock(level, bucket, piece); 240 | } 241 | else { 242 | find = true; 243 | blockID = b_id; 244 | sbuffer[0] = plain; 245 | 246 | std::string plain = Util::generate_random_block(B - Util::aes_block_size - sizeof(uint32_t)); 247 | int32_t dummyID = -1; 248 | std::string dID = std::string((const char *)(& dummyID), sizeof(uint32_t)); 249 | std::string cipher; 250 | Util::aes_encrypt(dID + plain, key, cipher); 251 | 252 | sbuffer[1] = cipher; 253 | writeBlock(level, bucket, piece); 254 | } 255 | } 256 | else { 257 | std::string cipher; 258 | Util::aes_encrypt(plain, key, cipher); 259 | sbuffer[1] = cipher; 260 | writeBlock(level, bucket, piece); 261 | } 262 | } 263 | 264 | if(!find) { 265 | std::string plain = Util::generate_random_block(B - Util::aes_block_size - sizeof(uint32_t)); 266 | int32_t dummyID = -1; 267 | std::string dID = std::string((const char *)(& dummyID), sizeof(uint32_t)); 268 | sbuffer[0] = dID + plain; 269 | } 270 | 271 | //write 272 | uint32_t bit; 273 | if(blockID != -1) 274 | bit = pos_map[blockID] & (1 << (height - level - 2)); 275 | else bit = 1; 276 | 277 | uint32_t lBucket = bucket << 1; 278 | for(uint32_t nextBucket = 0; nextBucket < 2; nextBucket ++) { 279 | uint32_t thisBucket = lBucket + nextBucket; 280 | 281 | if(bit != 0 && nextBucket != 0 || bit == 0 && nextBucket == 0) { 282 | bool find2 = false; 283 | for (uint32_t i = 0; i < bucket_size; ++ i) { 284 | readBlock(level + 1, thisBucket, i); 285 | 286 | std::string plain; 287 | Util::aes_decrypt(sbuffer[1], key, plain); 288 | 289 | if(!find2) { 290 | int32_t b_id; 291 | memcpy(&b_id, plain.c_str(), sizeof(uint32_t)); 292 | if (b_id != -1) { 293 | std::string cipher; 294 | Util::aes_encrypt(plain, key, cipher); 295 | 296 | sbuffer[1] = cipher; 297 | writeBlock(level + 1, thisBucket, i); 298 | } 299 | else { 300 | find2 = true; 301 | 302 | std::string cipher; 303 | Util::aes_encrypt(sbuffer[0], key, cipher); 304 | 305 | sbuffer[1] = cipher; 306 | writeBlock(level + 1, thisBucket, i); 307 | } 308 | } 309 | else { 310 | std::string cipher; 311 | Util::aes_encrypt(plain, key, cipher); 312 | 313 | sbuffer[1] = cipher; 314 | writeBlock(level + 1, thisBucket, i); 315 | } 316 | } 317 | } 318 | else { 319 | for (uint32_t i = 0; i < bucket_size; ++ i) { 320 | readBlock(level + 1, thisBucket, i); 321 | 322 | std::string plain; 323 | Util::aes_decrypt(sbuffer[1], key, plain); 324 | 325 | std::string cipher; 326 | Util::aes_encrypt(plain, key, cipher); 327 | 328 | sbuffer[1] = cipher; 329 | writeBlock(level + 1, thisBucket, i); 330 | } 331 | } 332 | } 333 | } 334 | 335 | void BinaryORAM::evict() { 336 | /* Suppose the eviction rate is not less than 2. */ 337 | //Level 0: 338 | if(height > 1) 339 | evict(0, 0); 340 | 341 | //Level 1: 342 | if(height > 2) { 343 | for(uint32_t bucket = 0; bucket < 2; bucket ++) { 344 | evict(1, bucket); 345 | } 346 | } 347 | 348 | //The following levels: 349 | for(uint32_t level = 2; level < height - 1; level ++) { 350 | for(size_t i = 0; i < Gamma; i ++) { 351 | uint32_t bucket = Util::rand_int(1 << level); 352 | evict(level, bucket); 353 | } 354 | } 355 | } -------------------------------------------------------------------------------- /src/RecursiveBinaryORAM.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 by SEAL-ORAM Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | // 18 | // Created by Dong Xie on 7/16/2016. 19 | // 20 | 21 | #include "RecursiveBinaryORAM.h" 22 | 23 | #include 24 | #include 25 | #include "MongoConnector.h" 26 | #include "Util.h" 27 | 28 | using namespace CryptoPP; 29 | 30 | RecursiveBinaryORAM::RecursiveBinaryORAM(const uint32_t& n) { 31 | height = (uint32_t)ceil(log2((double)n)) + 1; 32 | n_buckets = (uint32_t)1 << (height - 1); 33 | bucket_size = Alpha * (uint32_t)ceil(log2((double)n)); 34 | 35 | pos_map = new BinaryORAM(n / pos_base + 1); 36 | conn = new MongoConnector(server_host, "oram.newrecursivebinary"); 37 | 38 | key = new byte[Util::key_length]; 39 | Util::prng.GenerateBlock(key, Util::key_length); 40 | sbuffer = new std::string[2]; 41 | 42 | for (uint32_t i = 0; i < (1 << (height - 1)) - 1; ++i) { 43 | for (size_t j = 0; j < bucket_size; j ++) { 44 | std::string tmp = Util::generate_random_block(B - Util::aes_block_size - sizeof(uint32_t)); 45 | int32_t dummyID = -1; 46 | std::string dID = std::string((const char *)(& dummyID), sizeof(uint32_t)); 47 | std::string cipher; 48 | Util::aes_encrypt(dID + tmp, key, cipher); 49 | conn->insert(i * bucket_size + j, cipher); 50 | } 51 | } 52 | 53 | uint32_t cur_id = 0; 54 | for (uint32_t i = (1 << (height - 1)) - 1; i < (1 << height) - 1; ++i) { 55 | if (cur_id < n) { 56 | std::string tmp = Util::generate_random_block(B - Util::aes_block_size - 3 * sizeof(uint32_t)); 57 | std::string bID = std::string((const char *)(& cur_id), sizeof(uint32_t)); 58 | std::string cipher; 59 | Util::aes_encrypt(bID + bID + bID + tmp, key, cipher); 60 | conn->insert(i * bucket_size, cipher); 61 | checkAndUpdatePosMap(cur_id, cur_id); 62 | cur_id ++; 63 | } else { 64 | std::string tmp = Util::generate_random_block(B - Util::aes_block_size - sizeof(uint32_t)); 65 | int32_t dummyID = -1; 66 | std::string dID = std::string((const char *)(& dummyID), sizeof(uint32_t)); 67 | std::string cipher; 68 | Util::aes_encrypt(dID + tmp, key, cipher); 69 | conn->insert(i * bucket_size, cipher); 70 | } 71 | for (size_t j = 1; j < bucket_size; j ++) { 72 | std::string tmp = Util::generate_random_block(B - Util::aes_block_size - sizeof(uint32_t)); 73 | int32_t dummyID = -1; 74 | std::string dID = std::string((const char *)(& dummyID), sizeof(uint32_t)); 75 | std::string cipher; 76 | Util::aes_encrypt(dID + tmp, key, cipher); 77 | conn->insert(i * bucket_size + j, cipher); 78 | } 79 | } 80 | } 81 | 82 | RecursiveBinaryORAM::~RecursiveBinaryORAM() { 83 | delete[] key; 84 | delete[] sbuffer; 85 | delete pos_map; 86 | delete conn; 87 | } 88 | 89 | std::string RecursiveBinaryORAM::get(const std::string & key) { 90 | std::string res; 91 | uint32_t int_key; 92 | sscanf(key.c_str(), "%d", &int_key); 93 | access('r', int_key, res); 94 | return res; 95 | } 96 | 97 | void RecursiveBinaryORAM::put(const std::string & key, const std::string & value) { 98 | uint32_t int_key; 99 | sscanf(key.c_str(), "%d", &int_key); 100 | std::string value2 = value; 101 | access('w', int_key, value2); 102 | } 103 | 104 | std::string RecursiveBinaryORAM::get(const uint32_t & key) { 105 | std::string res; 106 | access('r', key, res); 107 | return res; 108 | } 109 | 110 | void RecursiveBinaryORAM::put(const uint32_t & key, const std::string & value) { 111 | std::string value2 = value; 112 | access('w', key, value2); 113 | } 114 | 115 | void RecursiveBinaryORAM::access(const char& op, const uint32_t& block_id, std::string& data) { 116 | uint32_t new_x = Util::rand_int(n_buckets); 117 | std::string str_newx = std::string((const char *)(& new_x), sizeof(uint32_t)); 118 | uint32_t x = checkAndUpdatePosMap(block_id, new_x); 119 | 120 | fetchAlongPath(block_id, x); 121 | 122 | if (op == 'r') { 123 | data = sbuffer[0].substr(sizeof(uint32_t)); 124 | } 125 | std::string blockID = std::string((const char *)(& block_id), sizeof(uint32_t)); 126 | sbuffer[0] = blockID + data.substr(0, sizeof(uint32_t)) + str_newx + data.substr(2 * sizeof(uint32_t), sizeof(uint32_t)); 127 | 128 | bool find = false; 129 | for (uint32_t i = 0; i < bucket_size; ++ i) { 130 | readBlock(0, 0, i); 131 | 132 | std::string plain; 133 | Util::aes_decrypt(sbuffer[1], key, plain); 134 | 135 | if (!find) { 136 | int32_t b_id; 137 | memcpy(&b_id, plain.c_str(), sizeof(uint32_t)); 138 | if (b_id != -1) { 139 | std::string cipher; 140 | Util::aes_encrypt(plain, key, cipher); 141 | 142 | sbuffer[1] = cipher; 143 | writeBlock(0, 0, i); 144 | } else { 145 | find = true; 146 | 147 | std::string cipher; 148 | Util::aes_encrypt(sbuffer[0], key, cipher); 149 | 150 | sbuffer[1] = cipher; 151 | writeBlock(0, 0, i); 152 | } 153 | } else { 154 | std::string cipher; 155 | Util::aes_encrypt(plain, key, cipher); 156 | 157 | sbuffer[1] = cipher; 158 | writeBlock(0, 0, i); 159 | } 160 | } 161 | 162 | evict(); 163 | } 164 | 165 | void RecursiveBinaryORAM::fetchAlongPath(const uint32_t& block_id, const uint32_t& x) { 166 | bool find = false; 167 | uint32_t cur_pos = x + (1 << (height - 1)); 168 | while (cur_pos > 0) { 169 | uint32_t id = (cur_pos - 1) * bucket_size; 170 | for (uint32_t i = 0; i < bucket_size; ++ i) { 171 | sbuffer[1] = conn->find(id + i); 172 | 173 | std::string plain; 174 | Util::aes_decrypt(sbuffer[1], key, plain); 175 | 176 | if (!find) { 177 | int32_t b_id; 178 | memcpy(&b_id, plain.c_str(), sizeof(uint32_t)); 179 | 180 | if (b_id != block_id) { 181 | std::string cipher; 182 | Util::aes_encrypt(plain, key, cipher); 183 | conn->update(id + i, cipher); 184 | } else { 185 | find = true; 186 | sbuffer[0] = plain; 187 | 188 | std::string plain = Util::generate_random_block(B - Util::aes_block_size - sizeof(uint32_t)); 189 | int32_t dummyID = -1; 190 | std::string dID = std::string((const char *)(& dummyID), sizeof(uint32_t)); 191 | std::string cipher; 192 | Util::aes_encrypt(dID + plain, key, cipher); 193 | conn->update(id + i, cipher); 194 | } 195 | } else { 196 | std::string cipher; 197 | Util::aes_encrypt(plain, key, cipher); 198 | conn->update(id + i, cipher); 199 | } 200 | } 201 | cur_pos >>= 1; 202 | } 203 | } 204 | 205 | void RecursiveBinaryORAM::readBlock(const uint32_t level, const uint32_t bucket, const uint32_t piece) { 206 | uint32_t bid = ((1 << level) - 1 + bucket) * bucket_size + piece; 207 | sbuffer[1] = conn->find(bid); 208 | } 209 | 210 | void RecursiveBinaryORAM::writeBlock(const uint32_t level, const uint32_t bucket, const uint32_t piece) { 211 | uint32_t bid = ((1 << level) - 1 + bucket) * bucket_size + piece; 212 | conn->update(bid, sbuffer[1]); 213 | } 214 | 215 | void RecursiveBinaryORAM::evict(const uint32_t level, const uint32_t bucket) { 216 | bool find = false; 217 | int32_t blockID = -1; 218 | 219 | //read 220 | for (uint32_t piece = 0; piece < bucket_size; piece ++) { 221 | readBlock(level, bucket, piece); 222 | 223 | std::string plain; 224 | Util::aes_decrypt(sbuffer[1], key, plain); 225 | 226 | if (!find) { 227 | int32_t b_id; 228 | memcpy(&b_id, plain.c_str(), sizeof(uint32_t)); 229 | if (b_id == -1) { 230 | std::string cipher; 231 | Util::aes_encrypt(plain, key, cipher); 232 | sbuffer[1] = cipher; 233 | writeBlock(level, bucket, piece); 234 | } else { 235 | find = true; 236 | blockID = b_id; 237 | sbuffer[0] = plain; 238 | 239 | std::string plain = Util::generate_random_block(B - Util::aes_block_size - sizeof(uint32_t)); 240 | int32_t dummyID = -1; 241 | std::string dID = std::string((const char *)(& dummyID), sizeof(uint32_t)); 242 | std::string cipher; 243 | Util::aes_encrypt(dID + plain, key, cipher); 244 | sbuffer[1] = cipher; 245 | writeBlock(level, bucket, piece); 246 | } 247 | } else { 248 | std::string cipher; 249 | Util::aes_encrypt(plain, key, cipher); 250 | sbuffer[1] = cipher; 251 | writeBlock(level, bucket, piece); 252 | } 253 | } 254 | 255 | if (!find) { 256 | std::string plain = Util::generate_random_block(B - Util::aes_block_size - sizeof(uint32_t)); 257 | int32_t dummyID = -1; 258 | std::string dID = std::string((const char *)(& dummyID), sizeof(uint32_t)); 259 | sbuffer[0] = dID + plain; 260 | } 261 | 262 | //write 263 | uint32_t bit; 264 | if (blockID != -1) { 265 | uint32_t bit1; 266 | memcpy(&bit1, sbuffer[0].substr(2 * sizeof(uint32_t)).c_str(), sizeof(uint32_t)); 267 | uint32_t bit2 = 1 << (height - level - 2); 268 | bit = bit1 & bit2; 269 | } else bit = 1; 270 | 271 | uint32_t lBucket = bucket << 1; 272 | for (uint32_t nextBucket = 0; nextBucket < 2; nextBucket ++) { 273 | uint32_t thisBucket = lBucket + nextBucket; 274 | 275 | if (bit != 0 && nextBucket != 0 || bit == 0 && nextBucket == 0) { 276 | bool find2 = false; 277 | for (uint32_t i = 0; i < bucket_size; ++ i) { 278 | readBlock(level + 1, thisBucket, i); 279 | 280 | std::string plain; 281 | Util::aes_decrypt(sbuffer[1], key, plain); 282 | if (!find2) { 283 | int32_t b_id; 284 | memcpy(&b_id, plain.c_str(), sizeof(uint32_t)); 285 | if (b_id != -1) { 286 | std::string cipher; 287 | Util::aes_encrypt(plain, key, cipher); 288 | sbuffer[1] = cipher; 289 | writeBlock(level + 1, thisBucket, i); 290 | } else { 291 | find2 = true; 292 | std::string cipher; 293 | Util::aes_encrypt(sbuffer[0], key, cipher); 294 | sbuffer[1] = cipher; 295 | writeBlock(level + 1, thisBucket, i); 296 | } 297 | } else { 298 | std::string cipher; 299 | Util::aes_encrypt(plain, key, cipher); 300 | sbuffer[1] = cipher; 301 | writeBlock(level + 1, thisBucket, i); 302 | } 303 | } 304 | } else { 305 | for (uint32_t i = 0; i < bucket_size; ++ i) { 306 | readBlock(level + 1, thisBucket, i); 307 | std::string plain; 308 | Util::aes_decrypt(sbuffer[1], key, plain); 309 | std::string cipher; 310 | Util::aes_encrypt(plain, key, cipher); 311 | sbuffer[1] = cipher; 312 | writeBlock(level + 1, thisBucket, i); 313 | } 314 | } 315 | } 316 | } 317 | 318 | void RecursiveBinaryORAM::evict() { 319 | /* Suppose the eviction rate is not less than 2. */ 320 | //Level 0: 321 | evict(0, 0); 322 | 323 | //Level 1: 324 | for (uint32_t bucket = 0; bucket < 2; bucket ++) { 325 | evict(1, bucket); 326 | } 327 | 328 | //The following levels: 329 | for (uint32_t level = 2; level < height - 1; level ++) { 330 | for (size_t i = 0; i < Gamma; i ++) { 331 | uint32_t bucket = Util::rand_int(1 << level); 332 | evict(level, bucket); 333 | } 334 | } 335 | } 336 | 337 | uint32_t RecursiveBinaryORAM::checkAndUpdatePosMap(const uint32_t& id, const uint32_t& pos) { 338 | std::string cur = pos_map->get(id / pos_base); 339 | uint32_t ans; 340 | memcpy(&ans, cur.c_str() + sizeof(uint32_t) * (id % pos_base), sizeof(uint32_t)); 341 | cur.replace(sizeof(uint32_t) * (id % pos_base), sizeof(uint32_t), (const char*)&pos, sizeof(uint32_t)); 342 | pos_map->put(id / pos_base, cur); 343 | return ans; 344 | } 345 | 346 | uint32_t RecursiveBinaryORAM::getPosMap(const uint32_t& id) { 347 | std::string cur = pos_map->get(id / pos_base); 348 | uint32_t ans; 349 | memcpy(&ans, cur.c_str() + sizeof(uint32_t) * (id % pos_base), sizeof(uint32_t)); 350 | return ans; 351 | } 352 | -------------------------------------------------------------------------------- /src/SRORAM.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 by SEAL-ORAM Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | // 18 | // Created by Dong Xie on 7/10/2016. 19 | // 20 | 21 | #include "SRORAM.h" 22 | 23 | using namespace CryptoPP; 24 | 25 | void SRORAM::initialize() { 26 | AutoSeededRandomPool prng; 27 | const uint32_t tmp_len = B - AES::BLOCKSIZE - 3 * sizeof(uint32_t); 28 | 29 | for(uint32_t k = 0; k < N; k ++) { 30 | byte tmp_buffer[tmp_len]; 31 | prng.GenerateBlock(tmp_buffer, tmp_len); 32 | sbuffer[0] = std::string((const char*)tmp_buffer, tmp_len); 33 | 34 | int32_t bID = k; 35 | std::string blockID = std::string((const char*)(& bID), sizeof(uint32_t)); 36 | sbuffer[0] = blockID + blockID + sbuffer[0]; 37 | 38 | std::string hValue = Util::sha256_hash(blockID, salt); 39 | uint32_t h = std::hash()(hValue); 40 | 41 | hValue = std::string((const char *)(&h), sizeof(uint32_t)); 42 | sbuffer[0] = hValue + sbuffer[0]; 43 | 44 | std::string cipher; 45 | Util::aes_encrypt(sbuffer[0], encKey, cipher); 46 | sbuffer[0] = cipher; 47 | 48 | conn->insert(k, sbuffer[0]); 49 | } 50 | 51 | for(uint32_t k = N; k < N + D; k ++) { 52 | byte tmp_buffer[tmp_len]; 53 | prng.GenerateBlock(tmp_buffer, tmp_len); 54 | sbuffer[0] = std::string((const char*)tmp_buffer, tmp_len); 55 | 56 | int32_t bID = k; 57 | std::string blockID = std::string((const char*)(& bID), sizeof(uint32_t)); 58 | int32_t dummy = -1; 59 | std::string dummyValue = std::string((const char*)(& dummy), sizeof(uint32_t)); 60 | 61 | sbuffer[0] = blockID + dummyValue + sbuffer[0]; 62 | 63 | std::string hValue = Util::sha256_hash(blockID, salt); 64 | uint32_t h = std::hash()(hValue); 65 | hValue = std::string((const char *)(&h), sizeof(uint32_t)); 66 | sbuffer[0] = hValue + sbuffer[0]; 67 | 68 | std::string cipher; 69 | Util::aes_encrypt(sbuffer[0], encKey, cipher); 70 | sbuffer[0] = cipher; 71 | 72 | conn->insert(k, sbuffer[0]); 73 | } 74 | for(uint32_t k = N + D; k < C; k ++) { 75 | 76 | byte tmp_buffer[tmp_len]; 77 | prng.GenerateBlock(tmp_buffer, tmp_len); 78 | sbuffer[0] = std::string((const char*)tmp_buffer, tmp_len); 79 | 80 | int32_t dID = -1; 81 | std::string blockID = std::string((const char*)(& dID), sizeof(uint32_t)); 82 | 83 | sbuffer[0] = blockID + blockID + sbuffer[0]; 84 | 85 | std::string hValue = Util::sha256_hash(blockID, salt); 86 | uint32_t h = std::hash()(hValue); 87 | hValue = std::string((const char *)(&h), sizeof(uint32_t)); 88 | sbuffer[0] = hValue + sbuffer[0]; 89 | 90 | std::string cipher; 91 | Util::aes_encrypt(sbuffer[0], encKey, cipher); 92 | sbuffer[0] = cipher; 93 | 94 | conn->insert(k, sbuffer[0]); 95 | } 96 | } 97 | 98 | void SRORAM::oddeven_merge(uint32_t lo, uint32_t hi, uint32_t r, uint32_t len, char order) { 99 | uint32_t step = r * 2; 100 | if(step < hi - lo) { 101 | oddeven_merge(lo, hi, step, len, order); 102 | oddeven_merge(lo + r, hi, step, len, order); 103 | for(uint32_t i = lo + r; i < hi - r; i += step) { 104 | if(i + r < len) 105 | compare_and_swap(i, i + r, order); 106 | } 107 | } 108 | else { 109 | if(lo + r < len) 110 | compare_and_swap(lo, lo + r, order); 111 | } 112 | } 113 | 114 | void SRORAM::oddeven_merge_sort_range(uint32_t lo, uint32_t hi, uint32_t len, char order) { 115 | if(hi - lo >= 1) { 116 | uint32_t mid = lo + (hi - lo) / 2; 117 | oddeven_merge_sort_range(lo, mid, len, order); 118 | oddeven_merge_sort_range(mid + 1, hi, len, order); 119 | oddeven_merge(lo, hi, 1, len, order); 120 | } 121 | } 122 | 123 | void SRORAM::compare_and_swap(uint32_t a, uint32_t b, char order) { 124 | sbuffer[0] = readBlock(a); 125 | sbuffer[1] = readBlock(b); 126 | if(order == 's') { 127 | uint32_t hValue1; 128 | memcpy(&hValue1, sbuffer[0].c_str(), sizeof(uint32_t)); 129 | uint32_t hValue2; 130 | memcpy(&hValue2, sbuffer[1].c_str(), sizeof(uint32_t)); 131 | if(hValue1 > hValue2) { 132 | std::string temp = sbuffer[0]; 133 | sbuffer[0] = sbuffer[1]; 134 | sbuffer[1] = temp; 135 | } 136 | } 137 | else if(order == 'r') { 138 | int32_t bID1; 139 | memcpy(&bID1, sbuffer[0].substr(sizeof(uint32_t)).c_str(), sizeof(uint32_t)); 140 | int32_t bID2; 141 | memcpy(&bID2, sbuffer[1].substr(sizeof(uint32_t)).c_str(), sizeof(uint32_t)); 142 | if(bID1 == -1) { 143 | if(bID2 != -1) { 144 | std::string temp = sbuffer[0]; 145 | sbuffer[0] = sbuffer[1]; 146 | sbuffer[1] = temp; 147 | } 148 | } 149 | else if (bID2 != -1 && bID1 > bID2) { 150 | std::string temp = sbuffer[0]; 151 | sbuffer[0] = sbuffer[1]; 152 | sbuffer[1] = temp; 153 | } 154 | } 155 | writeBlock(a, sbuffer[0]); 156 | writeBlock(b, sbuffer[1]); 157 | } 158 | 159 | void SRORAM::obliviSort(uint32_t len, char order) { 160 | uint32_t test = len; 161 | uint32_t upper = 0; 162 | while(test != 0) { 163 | test >>= 1; 164 | upper ++; 165 | } 166 | oddeven_merge_sort_range(0, (1 << upper) - 1, len, order); 167 | } 168 | 169 | void SRORAM::rehash() { 170 | AutoSeededRandomPool prng; 171 | byte temp[AES::DEFAULT_KEYLENGTH]; 172 | prng.GenerateBlock(temp, AES::DEFAULT_KEYLENGTH); 173 | salt = std::string((const char*)temp, AES::DEFAULT_KEYLENGTH); 174 | 175 | for(uint32_t i = 0; i < N + D; i ++) { 176 | sbuffer[0] = readBlock(i); 177 | std::string hValue = Util::sha256_hash(sbuffer[0].substr(sizeof(int32_t), sizeof(int32_t)), salt); 178 | uint32_t h = std::hash()(hValue); 179 | hValue = std::string((const char *)(&h), sizeof(uint32_t)); 180 | sbuffer[0] = hValue + sbuffer[0].substr(sizeof(int32_t)); 181 | writeBlock(i, sbuffer[0]); 182 | } 183 | } 184 | 185 | std::string SRORAM::readBlock(uint32_t blockID) { 186 | std::string cipher = conn->find(blockID); 187 | std::string plain; 188 | Util::aes_decrypt(cipher, encKey, plain); 189 | return plain; 190 | } 191 | 192 | void SRORAM::writeBlock(uint32_t blockID, std::string &data) { 193 | std::string plain = data; 194 | std::string cipher; 195 | Util::aes_encrypt(plain, encKey, cipher); 196 | conn->update(blockID, cipher); 197 | } 198 | 199 | /* 200 | op: 'r' means read, 'w' means write; 201 | blockID: block ID; 202 | data: block content 203 | */ 204 | void SRORAM::access(char op, uint32_t blockID, std::string &data) { 205 | 206 | if(count == 0) { 207 | obliviSort(N + D, 's'); 208 | } 209 | 210 | bool find = false; 211 | for(uint32_t i = N + D; i < N + D + count; i ++) { 212 | std::string temp = readBlock(i); 213 | int32_t bID; 214 | memcpy(&bID, temp.substr(sizeof(uint32_t)).c_str(), sizeof(int32_t)); 215 | if(!find && bID == blockID) { 216 | find = true; 217 | sbuffer[0] = temp; 218 | if(op == 'r') { 219 | writeBlock(i, temp); 220 | } 221 | else if(op == 'w') { 222 | temp = temp.substr(0, sizeof(uint32_t)) + std::string((const char *)(&blockID), sizeof(uint32_t)) + data; 223 | writeBlock(i, temp); 224 | } 225 | } 226 | else { 227 | writeBlock(i, temp); 228 | } 229 | } 230 | 231 | if(find) { 232 | bool find_dummy = false; 233 | 234 | uint32_t dummyID = N + count; 235 | std::string hKey = std::string((const char *)(&dummyID), sizeof(uint32_t)); 236 | std::string hValue = Util::sha256_hash(hKey, salt); 237 | uint32_t h = std::hash()(hValue); 238 | hValue = std::string((const char *)(&h), sizeof(uint32_t)); 239 | uint32_t hV; 240 | memcpy(&hV, hValue.c_str(), sizeof(uint32_t)); 241 | 242 | //Binary Search 243 | uint32_t lo = 0; 244 | uint32_t hi = N + D - 1; 245 | uint32_t mid = -1; 246 | std::string temp; 247 | while(hi > lo + 1) { 248 | mid = (lo + hi) / 2; 249 | temp = readBlock(mid); 250 | uint32_t hV2; 251 | memcpy(&hV2, temp.c_str(), sizeof(uint32_t)); 252 | if(hV == hV2) { 253 | find_dummy = true; 254 | break; 255 | } 256 | else if(hV < hV2) { 257 | hi = mid; 258 | } 259 | else lo = mid; 260 | } 261 | if(!find_dummy) { 262 | temp = readBlock(lo); 263 | uint32_t hV2; 264 | memcpy(&hV2, temp.c_str(), sizeof(uint32_t)); 265 | if(hV == hV2) { 266 | find_dummy = true; 267 | mid = lo; 268 | } 269 | } 270 | if(!find_dummy) { 271 | temp = readBlock(hi); 272 | uint32_t hV2; 273 | memcpy(&hV2, temp.c_str(), sizeof(uint32_t)); 274 | if(hV == hV2) { 275 | find_dummy = true; 276 | mid = hi; 277 | } 278 | } 279 | 280 | writeBlock(mid, temp); 281 | } 282 | else { 283 | bool find_real = false; 284 | std::string hKey = std::string((const char *)(&blockID), sizeof(uint32_t)); 285 | std::string hValue = Util::sha256_hash(hKey, salt); 286 | uint32_t hV = std::hash()(hValue); 287 | 288 | //Binary Search 289 | uint32_t lo = 0; 290 | uint32_t hi = N + D - 1; 291 | uint32_t mid = -1; 292 | std::string temp; 293 | while(hi > lo + 1) { 294 | mid = (lo + hi) / 2; 295 | temp = readBlock(mid); 296 | uint32_t hV2; 297 | memcpy(&hV2, temp.c_str(), sizeof(uint32_t)); 298 | 299 | if(hV == hV2) { 300 | find_real = true; 301 | sbuffer[0] = temp; 302 | break; 303 | } 304 | else if(hV < hV2) { 305 | hi = mid; 306 | } 307 | else { 308 | lo = mid; 309 | } 310 | } 311 | if(!find_real) { 312 | temp = readBlock(lo); 313 | uint32_t hV2; 314 | memcpy(&hV2, temp.c_str(), sizeof(uint32_t)); 315 | if(hV == hV2) { 316 | find_real = true; 317 | sbuffer[0] = temp; 318 | mid = lo; 319 | } 320 | } 321 | if(!find_real) { 322 | temp = readBlock(hi); 323 | uint32_t hV2; 324 | memcpy(&hV2, temp.c_str(), sizeof(uint32_t)); 325 | if(hV == hV2) { 326 | find_real = true; 327 | sbuffer[0] = temp; 328 | mid = hi; 329 | } 330 | } 331 | 332 | std::string temp2; 333 | AutoSeededRandomPool prng; 334 | const uint32_t tmp_len = B - AES::BLOCKSIZE - 3 * sizeof(uint32_t); 335 | byte tmp_buffer[tmp_len]; 336 | prng.GenerateBlock(tmp_buffer, tmp_len); 337 | temp2 = std::string((const char*)tmp_buffer, tmp_len); 338 | 339 | int32_t dID = -1; 340 | std::string dummyID = std::string((const char*)(& dID), sizeof(uint32_t)); 341 | temp = temp.substr(0, sizeof(uint32_t)) + dummyID + dummyID + temp2; 342 | writeBlock(mid, temp); 343 | } 344 | 345 | uint32_t index = N + D + count; 346 | if(find) { 347 | std::string temp; 348 | AutoSeededRandomPool prng; 349 | const uint32_t tmp_len = B - AES::BLOCKSIZE - 3 * sizeof(uint32_t); 350 | byte tmp_buffer[tmp_len]; 351 | prng.GenerateBlock(tmp_buffer, tmp_len); 352 | temp = std::string((const char*)tmp_buffer, tmp_len); 353 | 354 | int32_t dID = -1; 355 | std::string dummyID = std::string((const char*)(& dID), sizeof(uint32_t)); 356 | prng.GenerateBlock(tmp_buffer, sizeof(uint32_t)); 357 | std::string hashKey = std::string((const char*)tmp_buffer, sizeof(uint32_t)); 358 | temp = hashKey + dummyID + dummyID + temp; 359 | 360 | writeBlock(index, temp); 361 | } 362 | else { 363 | if(op == 'r') { 364 | writeBlock(index, sbuffer[0]); 365 | } 366 | else if(op == 'w') { 367 | sbuffer[0] = sbuffer[0].substr(0, sizeof(uint32_t)) + std::string((const char *)(&blockID), sizeof(uint32_t)) + data; 368 | writeBlock(index, sbuffer[0]); 369 | } 370 | } 371 | 372 | if(op == 'r') { 373 | data = sbuffer[0].substr(sizeof(uint32_t) * 2); 374 | } 375 | 376 | count++; 377 | if(count == D) { 378 | 379 | obliviSort(C, 'r'); 380 | 381 | rehash(); 382 | count = 0; 383 | } 384 | } 385 | 386 | std::string SRORAM::get(const std::string & key) { 387 | std::string res; 388 | uint32_t int_key; 389 | sscanf(key.c_str(), "%d", &int_key); 390 | access('r', int_key, res); 391 | return res; 392 | } 393 | 394 | void SRORAM::put(const std::string & key, const std::string & value) { 395 | uint32_t int_key; 396 | sscanf(key.c_str(), "%d", &int_key); 397 | std::string value2 = value; 398 | access('w', int_key, value2); 399 | } 400 | 401 | std::string SRORAM::get(const uint32_t & key) { 402 | std::string res; 403 | access('r', key, res); 404 | return res; 405 | } 406 | 407 | void SRORAM::put(const uint32_t & key, const std::string & value) { 408 | std::string value2 = value; 409 | access('w', key, value2); 410 | } 411 | --------------------------------------------------------------------------------