├── ABY_example
└── dectree
│ ├── CMakeLists.txt
│ ├── common
│ ├── garbledBP.h
│ ├── auxiliary-functions.h
│ ├── selection_blocks
│ │ ├── selection_block.h
│ │ ├── e_SelectionBlock.h
│ │ ├── e_SelectionBlock.cpp
│ │ ├── permutation_network.h
│ │ ├── t_SelectionBlock.h
│ │ ├── permutation_network.cpp
│ │ └── t_SelectionBlock.cpp
│ ├── crypto_party
│ │ ├── crypto_party.h
│ │ ├── paillier_party.h
│ │ ├── dgk_party.h
│ │ ├── paillier.cpp
│ │ ├── paillier.h
│ │ ├── dgk_party.cpp
│ │ └── paillier_party.cpp
│ ├── auxiliary-functions.cpp
│ ├── sndrcv.h
│ ├── sndrcv.cpp
│ ├── decision-tree-circuit.h
│ ├── dectree.h
│ ├── selection-functions.cpp
│ ├── dectree.cpp
│ └── decision-tree-circuit.cpp
│ ├── UCI_dectrees
│ ├── iris
│ ├── wine
│ ├── breast
│ └── linnerud
│ └── decision_tree_test.cpp
├── LICENSE
├── UCI_dectrees
├── iris
├── wine
├── breast
└── linnerud
├── README.md
└── XCMP_files
└── benchmark_gt
├── dectree.hpp
└── hhh.cpp
/ABY_example/dectree/CMakeLists.txt:
--------------------------------------------------------------------------------
1 |
2 | add_executable(decision_tree_test decision_tree_test.cpp common/dectree.cpp common/decision-tree-circuit.cpp common/auxiliary-functions.cpp common/sndrcv.cpp common/selection-functions.cpp common/crypto_party/dgk_party.cpp common/crypto_party/paillier_party.cpp common/crypto_party/paillier.cpp common/selection_blocks/e_SelectionBlock.cpp common/selection_blocks/t_SelectionBlock.cpp common/selection_blocks/permutation_network.cpp)
3 | target_link_libraries(decision_tree_test ABY::aby ENCRYPTO_utils::encrypto_utils)
4 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 ENCRYPTO
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/ABY_example/dectree/common/garbledBP.h:
--------------------------------------------------------------------------------
1 | /**
2 | \file garbledBP.h
3 | \author masoud.naderpour@helsinki.fi
4 | \copyright ABY - A Framework for Efficient Mixed-protocol Secure Two-party Computation
5 | Copyright (C) 2019 Engineering Cryptographic Protocols Group, TU Darmstadt
6 | This program is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU Lesser General Public License as published
8 | by the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 | ABY is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | GNU Lesser General Public License for more details.
14 | You should have received a copy of the GNU Lesser General Public License
15 | along with this program. If not, see .
16 | \brief Garbled node
17 | */
18 |
19 | #ifndef __Garbled_BP_H_
20 | #define __Garbled_BP_H_
21 |
22 | struct garbldNode{
23 | uint8_t *rnode, *lnode;
24 | };
25 |
26 | #endif /* __Garbled_BP_H_ */
27 |
--------------------------------------------------------------------------------
/ABY_example/dectree/common/auxiliary-functions.h:
--------------------------------------------------------------------------------
1 | /**
2 | \file auxiliary-functions.h
3 | \author masoud.naderpour@helsinki.fi
4 | \copyright ABY - A Framework for Efficient Mixed-protocol Secure Two-party Computation
5 | Copyright (C) 2019 Engineering Cryptographic Protocols Group, TU Darmstadt
6 | This program is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU Lesser General Public License as published
8 | by the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 | ABY is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | GNU Lesser General Public License for more details.
14 | You should have received a copy of the GNU Lesser General Public License
15 | along with this program. If not, see .
16 | \brief Auxiliary functions
17 | */
18 |
19 | #ifndef __AUX_FUNCTIONS_H_
20 | #define __AUX_FUNCTIONS_H_
21 |
22 | #include
23 | #include
24 |
25 | void print(uint8_t* s, int size);
26 |
27 | uint8_t* Xor(uint8_t* a, uint8_t* b, int size);
28 |
29 | double time_diff(struct timeval x , struct timeval y);
30 |
31 | double time_diff_microsec(struct timeval x , struct timeval y);
32 |
33 | #endif
34 |
--------------------------------------------------------------------------------
/UCI_dectrees/iris:
--------------------------------------------------------------------------------
1 | digraph Tree {
2 | node [shape=box] ;
3 | 0 [label="X[1] <= 2.45\ngini = 0.667\nsamples = 150\nvalue = [50, 50, 50]"] ;
4 | 1 [label="gini = 0.0\nsamples = 50\nvalue = [50, 0, 0]"] ;
5 | 0 -> 1 [labeldistance=2.5, labelangle=45, headlabel="True"] ;
6 | 2 [label="X[2] <= 1.75\ngini = 0.5\nsamples = 100\nvalue = [0, 50, 50]"] ;
7 | 0 -> 2 [labeldistance=2.5, labelangle=-45, headlabel="False"] ;
8 | 3 [label="X[1] <= 4.95\ngini = 0.168\nsamples = 54\nvalue = [0, 49, 5]"] ;
9 | 2 -> 3 ;
10 | 4 [label="X[2] <= 1.65\ngini = 0.041\nsamples = 48\nvalue = [0, 47, 1]"] ;
11 | 3 -> 4 ;
12 | 5 [label="gini = 0.0\nsamples = 47\nvalue = [0, 47, 0]"] ;
13 | 4 -> 5 ;
14 | 6 [label="gini = 0.0\nsamples = 1\nvalue = [0, 0, 1]"] ;
15 | 4 -> 6 ;
16 | 7 [label="X[2] <= 1.55\ngini = 0.444\nsamples = 6\nvalue = [0, 2, 4]"] ;
17 | 3 -> 7 ;
18 | 8 [label="gini = 0.0\nsamples = 3\nvalue = [0, 0, 3]"] ;
19 | 7 -> 8 ;
20 | 9 [label="X[1] <= 5.45\ngini = 0.444\nsamples = 3\nvalue = [0, 2, 1]"] ;
21 | 7 -> 9 ;
22 | 10 [label="gini = 0.0\nsamples = 2\nvalue = [0, 2, 0]"] ;
23 | 9 -> 10 ;
24 | 11 [label="gini = 0.0\nsamples = 1\nvalue = [0, 0, 1]"] ;
25 | 9 -> 11 ;
26 | 12 [label="X[1] <= 4.85\ngini = 0.043\nsamples = 46\nvalue = [0, 1, 45]"] ;
27 | 2 -> 12 ;
28 | 13 [label="X[0] <= 5.95\ngini = 0.444\nsamples = 3\nvalue = [0, 1, 2]"] ;
29 | 12 -> 13 ;
30 | 14 [label="gini = 0.0\nsamples = 1\nvalue = [0, 1, 0]"] ;
31 | 13 -> 14 ;
32 | 15 [label="gini = 0.0\nsamples = 2\nvalue = [0, 0, 2]"] ;
33 | 13 -> 15 ;
34 | 16 [label="gini = 0.0\nsamples = 43\nvalue = [0, 0, 43]"] ;
35 | 12 -> 16 ;
36 | }
37 |
--------------------------------------------------------------------------------
/ABY_example/dectree/UCI_dectrees/iris:
--------------------------------------------------------------------------------
1 | digraph Tree {
2 | node [shape=box] ;
3 | 0 [label="X[1] <= 2.45\ngini = 0.667\nsamples = 150\nvalue = [50, 50, 50]"] ;
4 | 1 [label="gini = 0.0\nsamples = 50\nvalue = [50, 0, 0]"] ;
5 | 0 -> 1 [labeldistance=2.5, labelangle=45, headlabel="True"] ;
6 | 2 [label="X[2] <= 1.75\ngini = 0.5\nsamples = 100\nvalue = [0, 50, 50]"] ;
7 | 0 -> 2 [labeldistance=2.5, labelangle=-45, headlabel="False"] ;
8 | 3 [label="X[1] <= 4.95\ngini = 0.168\nsamples = 54\nvalue = [0, 49, 5]"] ;
9 | 2 -> 3 ;
10 | 4 [label="X[2] <= 1.65\ngini = 0.041\nsamples = 48\nvalue = [0, 47, 1]"] ;
11 | 3 -> 4 ;
12 | 5 [label="gini = 0.0\nsamples = 47\nvalue = [0, 47, 0]"] ;
13 | 4 -> 5 ;
14 | 6 [label="gini = 0.0\nsamples = 1\nvalue = [0, 0, 1]"] ;
15 | 4 -> 6 ;
16 | 7 [label="X[2] <= 1.55\ngini = 0.444\nsamples = 6\nvalue = [0, 2, 4]"] ;
17 | 3 -> 7 ;
18 | 8 [label="gini = 0.0\nsamples = 3\nvalue = [0, 0, 3]"] ;
19 | 7 -> 8 ;
20 | 9 [label="X[1] <= 5.45\ngini = 0.444\nsamples = 3\nvalue = [0, 2, 1]"] ;
21 | 7 -> 9 ;
22 | 10 [label="gini = 0.0\nsamples = 2\nvalue = [0, 2, 0]"] ;
23 | 9 -> 10 ;
24 | 11 [label="gini = 0.0\nsamples = 1\nvalue = [0, 0, 1]"] ;
25 | 9 -> 11 ;
26 | 12 [label="X[1] <= 4.85\ngini = 0.043\nsamples = 46\nvalue = [0, 1, 45]"] ;
27 | 2 -> 12 ;
28 | 13 [label="X[0] <= 5.95\ngini = 0.444\nsamples = 3\nvalue = [0, 1, 2]"] ;
29 | 12 -> 13 ;
30 | 14 [label="gini = 0.0\nsamples = 1\nvalue = [0, 1, 0]"] ;
31 | 13 -> 14 ;
32 | 15 [label="gini = 0.0\nsamples = 2\nvalue = [0, 0, 2]"] ;
33 | 13 -> 15 ;
34 | 16 [label="gini = 0.0\nsamples = 43\nvalue = [0, 0, 43]"] ;
35 | 12 -> 16 ;
36 | }
37 |
--------------------------------------------------------------------------------
/ABY_example/dectree/common/selection_blocks/selection_block.h:
--------------------------------------------------------------------------------
1 | /**
2 | \file SelectionBlock.h
3 | \author masoud.naderpour@helsinki.fi
4 | \copyright ABY - A Framework for Efficient Mixed-protocol Secure Two-party Computation
5 | Copyright (C) 2019 Engineering Cryptographic Protocols Group, TU Darmstadt
6 | This program is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU Lesser General Public License as published
8 | by the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 | ABY is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | GNU Lesser General Public License for more details.
14 | You should have received a copy of the GNU Lesser General Public License
15 | along with this program. If not, see .
16 | \brief Implementation of WaksmanPermutation and SelectionBlock
17 | */
18 |
19 | #ifndef __ABY_SELECTIONBLOCK_H_
20 | #define __ABY_SELECTIONBLOCK_H_
21 |
22 | #include
23 | #include
24 | #include "stdio.h"
25 | #include
26 | #include "../../../../abycore/circuit/booleancircuits.h"
27 |
28 | class SelectionBlock {
29 | public:
30 | virtual void SelectionBlockProgram(uint32_t *p) = 0;
31 | virtual void SetControlBits() = 0;
32 | virtual std::vector > buildSelectionBlockCircuit(std::vector >& input) = 0;
33 | };
34 |
35 | #endif /* __ABY_SELECTIONBLOCK_H_ */
36 |
--------------------------------------------------------------------------------
/ABY_example/dectree/common/crypto_party/crypto_party.h:
--------------------------------------------------------------------------------
1 | /**
2 | \file crypto_party.h
3 | \author masoud.naderpour@helsinki.fi
4 | \copyright ABY - A Framework for Efficient Mixed-protocol Secure Two-party Computation
5 | Copyright (C) 2019 Engineering Cryptographic Protocols Group, TU Darmstadt
6 | This program is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU Lesser General Public License as published
8 | by the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 | ABY is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | GNU Lesser General Public License for more details.
14 | You should have received a copy of the GNU Lesser General Public License
15 | along with this program. If not, see .
16 | \brief Crypto functions
17 | */
18 |
19 | #ifndef __CRYPTO_PARTY_H__
20 | #define __CRYPTO_PARTY_H__
21 |
22 | #include
23 | #include "../../../..//abycore/ABY_utils/ABYconstants.h"
24 | #include
25 |
26 | using namespace std;
27 |
28 | // Super class
29 | class cryptoParty {
30 | public:
31 |
32 | virtual void generateKey() = 0;
33 |
34 | virtual void keyExchange(channel* &chan) = 0;
35 |
36 | virtual bool readKey() = 0;
37 |
38 | virtual void storeKey() = 0;
39 |
40 | virtual bool encrypt(vector &plaintexts, BYTE* &ciphertextsBuf) = 0;
41 |
42 | virtual void encSndRcvVec(e_role role, vector &plaintexts, mpz_t* &ciphertexts, channel* &chan) = 0;
43 |
44 | virtual void mskSndRcvVec(e_role role, mpz_t* &CTs, mpz_t* &RndMsks, vector &Mapping, mpz_t* &inputs, channel* &chan) = 0;
45 |
46 | protected:
47 |
48 | //GMP PRNG
49 | gmp_randstate_t m_randstate;
50 | };
51 |
52 |
53 | #endif //__CRYPTO_PARTY_H__
54 |
--------------------------------------------------------------------------------
/UCI_dectrees/wine:
--------------------------------------------------------------------------------
1 | digraph Tree {
2 | node [shape=box] ;
3 | 0 [label="X[6] <= 755.0\ngini = 0.658\nsamples = 178\nvalue = [59, 71, 48]"] ;
4 | 1 [label="X[5] <= 2.115\ngini = 0.492\nsamples = 111\nvalue = [2, 67, 42]"] ;
5 | 0 -> 1 [labeldistance=2.5, labelangle=45, headlabel="True"] ;
6 | 2 [label="X[4] <= 0.935\ngini = 0.227\nsamples = 46\nvalue = [0, 6, 40]"] ;
7 | 1 -> 2 ;
8 | 3 [label="X[2] <= 1.58\ngini = 0.049\nsamples = 40\nvalue = [0, 1, 39]"] ;
9 | 2 -> 3 ;
10 | 4 [label="gini = 0.0\nsamples = 39\nvalue = [0, 0, 39]"] ;
11 | 3 -> 4 ;
12 | 5 [label="gini = 0.0\nsamples = 1\nvalue = [0, 1, 0]"] ;
13 | 3 -> 5 ;
14 | 6 [label="X[1] <= 2.395\ngini = 0.278\nsamples = 6\nvalue = [0, 5, 1]"] ;
15 | 2 -> 6 ;
16 | 7 [label="gini = 0.0\nsamples = 5\nvalue = [0, 5, 0]"] ;
17 | 6 -> 7 ;
18 | 8 [label="gini = 0.0\nsamples = 1\nvalue = [0, 0, 1]"] ;
19 | 6 -> 8 ;
20 | 9 [label="X[2] <= 0.795\ngini = 0.117\nsamples = 65\nvalue = [2, 61, 2]"] ;
21 | 1 -> 9 ;
22 | 10 [label="gini = 0.0\nsamples = 2\nvalue = [0, 0, 2]"] ;
23 | 9 -> 10 ;
24 | 11 [label="X[0] <= 13.175\ngini = 0.061\nsamples = 63\nvalue = [2, 61, 0]"] ;
25 | 9 -> 11 ;
26 | 12 [label="gini = 0.0\nsamples = 58\nvalue = [0, 58, 0]"] ;
27 | 11 -> 12 ;
28 | 13 [label="X[0] <= 13.365\ngini = 0.48\nsamples = 5\nvalue = [2, 3, 0]"] ;
29 | 11 -> 13 ;
30 | 14 [label="gini = 0.0\nsamples = 2\nvalue = [2, 0, 0]"] ;
31 | 13 -> 14 ;
32 | 15 [label="gini = 0.0\nsamples = 3\nvalue = [0, 3, 0]"] ;
33 | 13 -> 15 ;
34 | 16 [label="X[2] <= 2.165\ngini = 0.265\nsamples = 67\nvalue = [57, 4, 6]"] ;
35 | 0 -> 16 [labeldistance=2.5, labelangle=-45, headlabel="False"] ;
36 | 17 [label="X[4] <= 0.803\ngini = 0.375\nsamples = 8\nvalue = [0, 2, 6]"] ;
37 | 16 -> 17 ;
38 | 18 [label="gini = 0.0\nsamples = 6\nvalue = [0, 0, 6]"] ;
39 | 17 -> 18 ;
40 | 19 [label="gini = 0.0\nsamples = 2\nvalue = [0, 2, 0]"] ;
41 | 17 -> 19 ;
42 | 20 [label="X[3] <= 3.435\ngini = 0.065\nsamples = 59\nvalue = [57, 2, 0]"] ;
43 | 16 -> 20 ;
44 | 21 [label="gini = 0.0\nsamples = 2\nvalue = [0, 2, 0]"] ;
45 | 20 -> 21 ;
46 | 22 [label="gini = 0.0\nsamples = 57\nvalue = [57, 0, 0]"] ;
47 | 20 -> 22 ;
48 | }
49 |
--------------------------------------------------------------------------------
/ABY_example/dectree/UCI_dectrees/wine:
--------------------------------------------------------------------------------
1 | digraph Tree {
2 | node [shape=box] ;
3 | 0 [label="X[6] <= 755.0\ngini = 0.658\nsamples = 178\nvalue = [59, 71, 48]"] ;
4 | 1 [label="X[5] <= 2.115\ngini = 0.492\nsamples = 111\nvalue = [2, 67, 42]"] ;
5 | 0 -> 1 [labeldistance=2.5, labelangle=45, headlabel="True"] ;
6 | 2 [label="X[4] <= 0.935\ngini = 0.227\nsamples = 46\nvalue = [0, 6, 40]"] ;
7 | 1 -> 2 ;
8 | 3 [label="X[2] <= 1.58\ngini = 0.049\nsamples = 40\nvalue = [0, 1, 39]"] ;
9 | 2 -> 3 ;
10 | 4 [label="gini = 0.0\nsamples = 39\nvalue = [0, 0, 39]"] ;
11 | 3 -> 4 ;
12 | 5 [label="gini = 0.0\nsamples = 1\nvalue = [0, 1, 0]"] ;
13 | 3 -> 5 ;
14 | 6 [label="X[1] <= 2.395\ngini = 0.278\nsamples = 6\nvalue = [0, 5, 1]"] ;
15 | 2 -> 6 ;
16 | 7 [label="gini = 0.0\nsamples = 5\nvalue = [0, 5, 0]"] ;
17 | 6 -> 7 ;
18 | 8 [label="gini = 0.0\nsamples = 1\nvalue = [0, 0, 1]"] ;
19 | 6 -> 8 ;
20 | 9 [label="X[2] <= 0.795\ngini = 0.117\nsamples = 65\nvalue = [2, 61, 2]"] ;
21 | 1 -> 9 ;
22 | 10 [label="gini = 0.0\nsamples = 2\nvalue = [0, 0, 2]"] ;
23 | 9 -> 10 ;
24 | 11 [label="X[0] <= 13.175\ngini = 0.061\nsamples = 63\nvalue = [2, 61, 0]"] ;
25 | 9 -> 11 ;
26 | 12 [label="gini = 0.0\nsamples = 58\nvalue = [0, 58, 0]"] ;
27 | 11 -> 12 ;
28 | 13 [label="X[0] <= 13.365\ngini = 0.48\nsamples = 5\nvalue = [2, 3, 0]"] ;
29 | 11 -> 13 ;
30 | 14 [label="gini = 0.0\nsamples = 2\nvalue = [2, 0, 0]"] ;
31 | 13 -> 14 ;
32 | 15 [label="gini = 0.0\nsamples = 3\nvalue = [0, 3, 0]"] ;
33 | 13 -> 15 ;
34 | 16 [label="X[2] <= 2.165\ngini = 0.265\nsamples = 67\nvalue = [57, 4, 6]"] ;
35 | 0 -> 16 [labeldistance=2.5, labelangle=-45, headlabel="False"] ;
36 | 17 [label="X[4] <= 0.803\ngini = 0.375\nsamples = 8\nvalue = [0, 2, 6]"] ;
37 | 16 -> 17 ;
38 | 18 [label="gini = 0.0\nsamples = 6\nvalue = [0, 0, 6]"] ;
39 | 17 -> 18 ;
40 | 19 [label="gini = 0.0\nsamples = 2\nvalue = [0, 2, 0]"] ;
41 | 17 -> 19 ;
42 | 20 [label="X[3] <= 3.435\ngini = 0.065\nsamples = 59\nvalue = [57, 2, 0]"] ;
43 | 16 -> 20 ;
44 | 21 [label="gini = 0.0\nsamples = 2\nvalue = [0, 2, 0]"] ;
45 | 20 -> 21 ;
46 | 22 [label="gini = 0.0\nsamples = 57\nvalue = [57, 0, 0]"] ;
47 | 20 -> 22 ;
48 | }
49 |
--------------------------------------------------------------------------------
/ABY_example/dectree/common/auxiliary-functions.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | \file auxiliary-functions.cpp
3 | \author masoud.naderpour@helsinki.fi
4 | \copyright ABY - A Framework for Efficient Mixed-protocol Secure Two-party Computation
5 | Copyright (C) 2019 Engineering Cryptographic Protocols Group, TU Darmstadt
6 | This program is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU Lesser General Public License as published
8 | by the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 | ABY is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | GNU Lesser General Public License for more details.
14 | You should have received a copy of the GNU Lesser General Public License
15 | along with this program. If not, see .
16 | \brief Auxiliary functions
17 | */
18 |
19 | #include
20 | #include
21 | #include "auxiliary-functions.h"
22 |
23 | void print(uint8_t* s, int size){
24 | for(int i = 0; i < size; i++)
25 | std::cout<< std::hex << std::setw(2) << std::setfill('0') << int(s[i]);
26 | std::cout << std::endl;
27 | }
28 |
29 | uint8_t* Xor(uint8_t* a, uint8_t* b, int size){
30 | for(int i = 0; i < size; i++)
31 | a[i] ^= b[i];
32 | return a;
33 | }
34 |
35 | double time_diff(struct timeval x , struct timeval y){
36 | double x_ms , y_ms , diff;
37 |
38 | x_ms = (double)x.tv_sec*1000 + (double)(x.tv_usec / 1000);
39 | y_ms = (double)y.tv_sec*1000 + (double)(y.tv_usec / 1000);
40 |
41 | diff = (double)y_ms - (double)x_ms;
42 |
43 | return diff;
44 | }
45 |
46 | double time_diff_microsec(struct timeval x , struct timeval y){
47 | double x_ms , y_ms , diff;
48 |
49 | x_ms = (double)x.tv_sec*1000000 + (double)(x.tv_usec);
50 | y_ms = (double)y.tv_sec*1000000 + (double)(y.tv_usec);
51 |
52 | diff = (double)y_ms - (double)x_ms;
53 |
54 | return diff;
55 | }
56 |
--------------------------------------------------------------------------------
/ABY_example/dectree/common/sndrcv.h:
--------------------------------------------------------------------------------
1 | /**
2 | \file sndrcv.h
3 | \author masoud.naderpour@helsinki.fi
4 | \copyright ABY - A Framework for Efficient Mixed-protocol Secure Two-party Computation
5 | Copyright (C) 2019 Engineering Cryptographic Protocols Group, TU Darmstadt
6 | This program is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU Lesser General Public License as published
8 | by the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 | ABY is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | GNU Lesser General Public License for more details.
14 | You should have received a copy of the GNU Lesser General Public License
15 | along with this program. If not, see .
16 | \brief Send and receive garbled DT
17 | */
18 |
19 | #ifndef __SNDRCV_H__
20 | #define __SNDRCV_H__
21 |
22 | #include
23 | #include
24 | #include
25 | #include
26 | #include
27 | #include
28 | #include "auxiliary-functions.h"
29 | #include "../../../abycore/ABY_utils/ABYconstants.h"
30 | #include
31 | #include
32 | #include
33 |
34 | #define PROGRAM_MAIN_CHANNEL 0x01
35 |
36 | class NetConnection {
37 | public:
38 | BOOL EstConnection(e_role role);
39 | BOOL PartyConnect();
40 | BOOL PartyListen();
41 | NetConnection(const std::string addr, uint16_t port);
42 |
43 | channel* commChannel;
44 |
45 | private:
46 | std::string ipaddress;
47 | uint16_t port;
48 | std::unique_ptr m_pSocket;
49 | std::unique_ptr snd_thread;
50 | std::unique_ptr rcv_thread;
51 | std::unique_ptr commlock;
52 | };
53 |
54 |
55 | BOOL sendGarbledDT(channel* chan, const int16_t &numNodes, const int16_t &nodeSize, uint8_t* serialized_garbledDT );
56 | BOOL receiveGarbledDT(channel* chan, const int16_t &numNodes, const int16_t &nodeSize, uint8_t* rcvBuff);
57 |
58 | #endif
59 |
--------------------------------------------------------------------------------
/ABY_example/dectree/common/crypto_party/paillier_party.h:
--------------------------------------------------------------------------------
1 | /**
2 | \file paillier_party.h
3 | \author masoud.naderpour@helsinki.fi
4 | \copyright ABY - A Framework for Efficient Mixed-protocol Secure Two-party Computation
5 | Copyright (C) 2019 Engineering Cryptographic Protocols Group, TU Darmstadt
6 | This program is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU Lesser General Public License as published
8 | by the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 | ABY is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | GNU Lesser General Public License for more details.
14 | You should have received a copy of the GNU Lesser General Public License
15 | along with this program. If not, see .
16 | \brief Paillier crypto
17 | */
18 |
19 |
20 | #ifndef __Paillier_Party_H__
21 | #define __Paillier_Party_H__
22 |
23 | #include
24 | #include
25 | #include
26 | #include
27 | #include
28 | #include "paillier.h"
29 | #include
30 | #include
31 | #include
32 | #include
33 | #include "crypto_party.h"
34 |
35 | using namespace std;
36 |
37 | class PaillierParty: public cryptoParty {
38 | public:
39 | PaillierParty(uint32_t PaillierBits, uint32_t readkey);
40 | ~PaillierParty();
41 |
42 | void generateKey();
43 |
44 | void keyExchange(channel* &chan);
45 |
46 | bool readKey();
47 |
48 | void storeKey();
49 |
50 | bool encrypt(vector &plaintexts, BYTE* &ciphertextsBuf);
51 |
52 | void encSndRcvVec(e_role role, vector &plaintexts, mpz_t* &ciphertexts, channel* &chan);
53 |
54 | void mskSndRcvVec(e_role role, mpz_t* &CTs, mpz_t* &RndMsks, vector &Mapping, mpz_t* &MaskedInputsVec, channel* &chan);
55 |
56 | private:
57 | uint32_t m_nPaillierBits;
58 | uint16_t m_nShareLength;
59 | uint32_t m_nBuflen;
60 |
61 | paillier_pubkey_t *m_localpub, *m_remotepub;
62 | paillier_prvkey_t *m_prv;
63 |
64 | void sendmpz_t(mpz_t t, channel* chan, BYTE * buf);
65 | void receivempz_t(mpz_t t, channel* chan, BYTE * buf);
66 |
67 | void sendmpz_t(mpz_t t, channel* chan);
68 | void receivempz_t(mpz_t t, channel* chan);
69 |
70 | void printBuf(BYTE* b, uint32_t l);
71 | };
72 |
73 | #endif //__Paillier_Party_H__
74 |
--------------------------------------------------------------------------------
/ABY_example/dectree/common/crypto_party/dgk_party.h:
--------------------------------------------------------------------------------
1 | /**
2 | \file dgk_party.h
3 | \author masoud.naderpour@helsinki.fi
4 | \copyright ABY - A Framework for Efficient Mixed-protocol Secure Two-party Computation
5 | Copyright (C) 2019 Engineering Cryptographic Protocols Group, TU Darmstadt
6 | This program is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU Lesser General Public License as published
8 | by the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 | ABY is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | GNU Lesser General Public License for more details.
14 | You should have received a copy of the GNU Lesser General Public License
15 | along with this program. If not, see .
16 | \brief DGK crypto
17 | */
18 |
19 |
20 | #ifndef __DGK_PAR_H__
21 | #define __DGK_PAR_H__
22 |
23 | #include
24 | #include
25 | #include
26 | #include
27 | #include
28 | #include
29 | #include
30 | #include
31 | #include "crypto_party.h"
32 |
33 | using namespace std;
34 |
35 | class DGK: public cryptoParty {
36 | public:
37 | DGK(uint32_t DGKbits, uint32_t sharelen, uint32_t readkey);
38 | DGK(uint32_t DGKbits, uint32_t sharelen, channel* chan, uint32_t readkey);
39 | ~DGK();
40 |
41 | void generateKey();
42 |
43 | void keyExchange(channel* &chan);
44 |
45 | bool readKey();
46 |
47 | void storeKey();
48 |
49 | bool encrypt(vector &plaintexts, BYTE* &ciphertextsBuf);
50 |
51 | void encSndRcvVec(e_role role, vector &plaintexts, mpz_t* &ciphertexts, channel* &chan);
52 |
53 | void mskSndRcvVec(e_role role, mpz_t* &CTs, mpz_t* &RndMsks, vector &Mapping, mpz_t* &inputs, channel* &chan);
54 |
55 | private:
56 | uint16_t m_nNumMTThreads;
57 | uint16_t m_nShareLength;
58 | uint32_t m_nDGKbits;
59 | uint32_t m_nBuflen;
60 |
61 | dgk_pubkey_t *m_localpub, *m_remotepub;
62 | dgk_prvkey_t *m_prv;
63 |
64 | void sendmpz_t(mpz_t t, channel* chan, BYTE * buf);
65 | void receivempz_t(mpz_t t, channel* chan, BYTE * buf);
66 |
67 | void sendmpz_t(mpz_t t, channel* chan);
68 | void receivempz_t(mpz_t t, channel* chan);
69 |
70 | void printBuf(BYTE* b, uint32_t l);
71 |
72 | };
73 |
74 | #endif //__DGK_PAR_H__
75 |
--------------------------------------------------------------------------------
/ABY_example/dectree/common/sndrcv.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | \file sndrcv.h
3 | \author masoud.naderpour@helsinki.fi
4 | \copyright ABY - A Framework for Efficient Mixed-protocol Secure Two-party Computation
5 | Copyright (C) 2019 Engineering Cryptographic Protocols Group, TU Darmstadt
6 | This program is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU Lesser General Public License as published
8 | by the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 | ABY is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | GNU Lesser General Public License for more details.
14 | You should have received a copy of the GNU Lesser General Public License
15 | along with this program. If not, see .
16 | \brief Send and receive garbled DT
17 | */
18 |
19 | #include "sndrcv.h"
20 |
21 | BOOL NetConnection::EstConnection(e_role role)
22 | {
23 | BOOL success = true;
24 | if (role == SERVER) {
25 | m_pSocket = Listen(ipaddress, port);
26 | if (!m_pSocket)
27 | success = false;
28 | } else { //CLIENT
29 | m_pSocket = Connect(ipaddress, port);
30 | if (!m_pSocket)
31 | success = false;
32 | }
33 | if (!success) {
34 | std::cout << "connection failed!" << std::endl;
35 | return false;
36 | }
37 |
38 | commlock = std::make_unique();
39 | snd_thread = std::make_unique(m_pSocket.get(), commlock.get());
40 | rcv_thread = std::make_unique(m_pSocket.get(), commlock.get());
41 | snd_thread->Start();
42 | rcv_thread->Start();
43 |
44 | commChannel = new channel(PROGRAM_MAIN_CHANNEL, rcv_thread.get(), snd_thread.get());
45 |
46 | return success;
47 | }
48 |
49 | NetConnection::NetConnection(const std::string addr, uint16_t port) {
50 | NetConnection::port = port;
51 | NetConnection::ipaddress = addr;
52 | }
53 |
54 | BOOL sendGarbledDT(channel* chan, const int16_t &numNodes, const int16_t &nodeSize, uint8_t* serialized_garbledDT ) {
55 | chan->send(serialized_garbledDT, numNodes * nodeSize * 2);
56 | return TRUE;
57 | }
58 |
59 | BOOL receiveGarbledDT(channel* chan, const int16_t &numNodes, const int16_t &nodeSize, uint8_t* rcvBuff) {
60 |
61 | timeval tbegin, tend;
62 |
63 | gettimeofday(&tbegin, NULL);
64 | chan->blocking_receive(rcvBuff, numNodes * nodeSize * 2);
65 | gettimeofday(&tend, NULL);
66 | std::cout << " Garbled tree transfer time: " << time_diff_microsec(tbegin, tend) << "us" << std::endl;
67 | return TRUE;
68 | }
69 |
--------------------------------------------------------------------------------
/ABY_example/dectree/common/decision-tree-circuit.h:
--------------------------------------------------------------------------------
1 | /**
2 | \file decision-tree-circuit.h
3 | \author masoud.naderpour@helsinki.fi
4 | \copyright ABY - A Framework for Efficient Mixed-protocol Secure Two-party Computation
5 | Copyright (C) 2019 Engineering Cryptographic Protocols Group, TU Darmstadt
6 | This program is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU Lesser General Public License as published
8 | by the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 | ABY is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | GNU Lesser General Public License for more details.
14 | You should have received a copy of the GNU Lesser General Public License
15 | along with this program. If not, see .
16 | \brief Private decision tree evaluation
17 | */
18 |
19 | #ifndef __DECISION_TREE_H_
20 | #define __DECISION_TREE_H_
21 |
22 | #include "../../../abycore/circuit/circuit.h"
23 | #include "../../../abycore/aby/abyparty.h"
24 | #include "../../../abycore/sharing/yaoserversharing.h"
25 | #include "selection_blocks/selection_block.h"
26 | #include "crypto_party/crypto_party.h"
27 | #include "crypto_party/dgk_party.h"
28 | #include "crypto_party/paillier_party.h"
29 | #include "dectree.h"
30 |
31 | #include
32 | #include
33 |
34 | #define RANDOM_TESTCASE
35 | #define MaskBitLen 104
36 | //#define BP_DEBUG
37 |
38 | enum e_sel_alg{ SEL_HE = 0, SEL_GC = 1};
39 | enum e_eval_alg{ EVAL_HE = 0, EVAL_GC = 1};
40 | enum e_HE_crypto_party { e_DGK = 0, e_PAILLIER = 1};
41 |
42 | void selction_HE(e_role role, channel* channel, vector &featureVec, seclvl seclvl, uint64_t NumDecisionNodes, uint16_t* permutation, BooleanCircuit* &Circ, share** &CircOut);
43 |
44 | void selction_GC(vector &featureVec, uint64_t numDecisionNodes, uint16_t* permutation, BooleanCircuit* &Circ, share** &CircOut);
45 |
46 | int pri_eval_decision_tree(e_role role, char* address, uint16_t port, seclvl seclvl, uint32_t nthreads, e_mt_gen_alg mt_alg, e_sharing comparesharing, e_sel_alg sel_alg, uint64_t numNodes, uint64_t dimension, DecTree &tree);
47 |
48 | uint8_t* create_garbled_tree(DecTree &dectree, seclvl seclvl, uint8_t** pointerKey, uint8_t* binPermute, uint16_t* permute);
49 |
50 | int Eval_garbled_tree(uint8_t *glbp, uint8_t **keys, uint16_t d, uint32_t keysize, uint32_t msgsize, seclvl seclvl);
51 |
52 | //void verify(vector const &featureVec, BranchingProgram* BP);
53 |
54 | #endif /* __DECISION_TREE_H_ */
55 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Private Decision Tree Evaluation (PDTE) Protocols
2 |
3 | By *Ágnes Kiss* ([ENCRYPTO](http://www.encrypto.de), TU Darmstadt), *Masoud Naderpour* (University of Helsinki), *Jian Liu* (University of California, Berkeley), *N. Asokan* (Aalto University) and *Thomas Schneider* ([ENCRYPTO](http://www.encrypto.de), TU Darmstadt) in [PoPETs'19(2)](https://petsymposium.org/2019/). Paper available [here](http://encrypto.de/papers/KNLAS19.pdf)
4 |
5 | ### Features
6 | ---
7 |
8 | Our implementation for private decision tree evaluation protocols includes the protocols HHH, HGH, GGH, GGG and HGG (it can also be used to benchmark the last and most inefficient protocol HHG). The implementation of (SelH+)CompH and PathH is based on the mcl library (https://github.com/herumi/mcl) that implements efficient lifted ElGamal encryption over elliptic curves, more specifically on the XCMP protocol implementation which implements the DGK comparison protocol (https://github.com/fionser/XCMP). The implementation of SelH, SelG, CompG and PathG are based on the ABY framework (https://github.com/encryptogroup/ABY) which provides an efficient implementation of Yao's garbled circuit protocol as well as of the Paillier homomorphic encryption scheme.
9 |
10 | This code is provided as a experimental implementation for testing purposes and should not be used in a productive environment. We cannot guarantee security and correctness.
11 |
12 | ### Requirements
13 | ---
14 | The requirements are the same as that of https://github.com/fionser/XCMP and https://github.com/encryptogroup/ABY.
15 |
16 | ### PDTE Implementation
17 | ---
18 |
19 | 1. Clone a copy of the main PDTE git repository by running:
20 | ```
21 | git clone --recursive git://github.com/encryptogroup/PDTE
22 | ```
23 | 2. Enter the UC directory: `cd PDTE`
24 |
25 | #### (SelH+)CompH and PathH Implementation
26 | 3. Clone/download the XCMP repository in the PDTE folder
27 | 4. Place/replace the files from XCMP_files into the respective location in the XCMP folder
28 | 5. Add the following lines at the enf of XCMP/benchmark_gt/CMakeLists.txt:
29 | ```
30 | add_executable(hhh hhh.cpp)
31 | target_link_libraries(hhh boost_system pthread ${ECC_LIB})
32 | ```
33 | 6. Run the following commands:
34 | ```
35 | cd benchmark_gt
36 | mkdir build & cd build
37 | cmake .. -DCMAKE_BUILD_TYPE=Release & make
38 | ```
39 | 7. In two separate terminals, run ```./hhh 0``` and ```./hhh 1``` for the server and client applications. You can configure the DT and PROT variables in the beginning of the file benchmark_dt/hhh.cpp for running different protocol parts and decision trees.
40 |
41 | #### SelG, SelH, CompG and PathG Implementation
42 | 8. Clone/download the ABY repository
43 | 9. Place the dectree folder from ABY_example in ABY/src/examples and add the line
44 | ```
45 | add_subdirectory(dectree)
46 | ```
47 | in ABY/src/examples/CMakeLists.txt.
48 | 10. Add the following line in ABY/src/abycore/sharing/yaoserversharing.h in line 74:
49 | ```
50 | CBitVector get_R(){ return m_vR;}
51 | ```
52 | 11. Add the following lines in ABY/src/abycore/circuit/booleancircuits.h in line 474:
53 | ```
54 | BYTE* GetEvaluatedKey(uint32_t gateid) { return m_vGates[gateid].gs.yval; };
55 | BYTE* GetServerRandomKey(uint32_t gateid) {return m_vGates[gateid].gs.yinput.outKey; };
56 | BYTE* GetPi(uint32_t gateid) {return m_vGates[gateid].gs.yinput.pi; };
57 | ```
58 | 12. Build ABY with the examples as indicated at https://github.com/encryptogroup/ABY.
59 |
--------------------------------------------------------------------------------
/ABY_example/dectree/common/selection_blocks/e_SelectionBlock.h:
--------------------------------------------------------------------------------
1 | /**
2 | \file e_SelectionBlock.h
3 | \author masoud.naderpour@helsinki.fi
4 | \author michael.zohner@ec-spride.de
5 | \copyright ABY - A Framework for Efficient Mixed-protocol Secure Two-party Computation
6 | Copyright (C) 2019 Engineering Cryptographic Protocols Group, TU Darmstadt
7 | This program is free software: you can redistribute it and/or modify
8 | it under the terms of the GNU Lesser General Public License as published
9 | by the Free Software Foundation, either version 3 of the License, or
10 | (at your option) any later version.
11 | ABY is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU Lesser General Public License for more details.
15 | You should have received a copy of the GNU Lesser General Public License
16 | along with this program. If not, see .
17 | \brief Implementation of extended SelectionBlock
18 | */
19 | #ifndef __ABY_E_SELECTIONBLOCK_H_
20 | #define __ABY_E_SELECTIONBLOCK_H_
21 |
22 | #include
23 | #include
24 | #include "stdio.h"
25 | #include
26 | #include "../../../../abycore/circuit/booleancircuits.h"
27 | #include "selection_block.h"
28 | #include "permutation_network.h"
29 |
30 | using namespace std;
31 |
32 | //TODO: Generate destructor methods
33 |
34 | class e_SelectionBlock : public SelectionBlock {
35 | //private:
36 | public: // TODO: Fix this!
37 | PermutationNetwork *m_Pblock1,*m_Pblock2;
38 | uint32_t m_nNumInputs, m_nNumOutputs;
39 | vector m_vYgatesProgram;
40 | vector m_vYGates;
41 | BooleanCircuit* m_cBoolCirc;
42 | //public:
43 | e_SelectionBlock (uint32_t numInputs, uint32_t numOutputs, BooleanCircuit* circ){
44 | m_nNumInputs = numInputs;
45 | m_nNumOutputs = numOutputs;
46 | m_vYgatesProgram.resize(m_nNumOutputs-1);
47 | m_vYGates.resize(m_nNumOutputs-1);
48 | m_Pblock1 = new PermutationNetwork(numInputs, numOutputs, circ); // Extended PermutationNetwork(u,v) [v>u]
49 | m_Pblock2 = new PermutationNetwork(numOutputs, numOutputs, circ);// PermutationNetwork(v,v)
50 | m_cBoolCirc = circ;
51 | }
52 |
53 | void SelectionBlockProgram(uint32_t *p);
54 | uint32_t getYGateAt(uint32_t idx) {
55 | return m_vYGates[idx];
56 | }
57 | void setYProgram(uint32_t idx, bool val) {
58 | m_vYgatesProgram[idx] = val;
59 | }
60 | void setYGates() {
61 | uint32_t val;
62 | for (uint32_t i = 0; i < m_nNumOutputs-1 ; i++){
63 | val = (uint32_t) m_vYgatesProgram[i];
64 | m_vYGates[i] = (m_cBoolCirc->PutSIMDINGate(1,val,1,SERVER))->get_wire_id(0);
65 | }
66 | }
67 | void SetControlBits(){
68 | m_Pblock1->setPermutationGates();
69 | setYGates();
70 | m_Pblock2->setPermutationGates();
71 | }
72 | vector > buildSelectionBlockCircuit(vector >& input);
73 | vector PutCondYGate(vector& a, vector& b, uint32_t s) {
74 | return {m_cBoolCirc->PutCombinerGate(m_cBoolCirc->PutMUXGate(m_cBoolCirc->PutSplitterGate(b[0]), m_cBoolCirc->PutSplitterGate(a[0]), s, true))};
75 | //return m_cBoolCirc->PutCondYGate(a, b, s, true);
76 | //return m_cBoolCirc->PutMUXGate(b, a, s, true);
77 | }
78 |
79 | };
80 |
81 | #endif /* __ABY_E_SELECTIONBLOCK_H_ */
82 |
--------------------------------------------------------------------------------
/UCI_dectrees/breast:
--------------------------------------------------------------------------------
1 | digraph Tree {
2 | node [shape=box] ;
3 | 0 [label="X[5] <= 16.795\ngini = 0.468\nsamples = 569\nvalue = [212, 357]"] ;
4 | 1 [label="X[10] <= 0.136\ngini = 0.159\nsamples = 379\nvalue = [33, 346]"] ;
5 | 0 -> 1 [labeldistance=2.5, labelangle=45, headlabel="True"] ;
6 | 2 [label="X[4] <= 0.009\ngini = 0.03\nsamples = 333\nvalue = [5, 328]"] ;
7 | 1 -> 2 ;
8 | 3 [label="gini = 0.0\nsamples = 1\nvalue = [1, 0]"] ;
9 | 2 -> 3 ;
10 | 4 [label="X[2] <= 38.605\ngini = 0.024\nsamples = 332\nvalue = [4, 328]"] ;
11 | 2 -> 4 ;
12 | 5 [label="X[3] <= 0.003\ngini = 0.012\nsamples = 319\nvalue = [2, 317]"] ;
13 | 4 -> 5 ;
14 | 6 [label="X[9] <= 0.195\ngini = 0.245\nsamples = 7\nvalue = [1, 6]"] ;
15 | 5 -> 6 ;
16 | 7 [label="gini = 0.0\nsamples = 6\nvalue = [0, 6]"] ;
17 | 6 -> 7 ;
18 | 8 [label="gini = 0.0\nsamples = 1\nvalue = [1, 0]"] ;
19 | 6 -> 8 ;
20 | 9 [label="X[6] <= 33.27\ngini = 0.006\nsamples = 312\nvalue = [1, 311]"] ;
21 | 5 -> 9 ;
22 | 10 [label="gini = 0.0\nsamples = 292\nvalue = [0, 292]"] ;
23 | 9 -> 10 ;
24 | 11 [label="X[6] <= 33.56\ngini = 0.095\nsamples = 20\nvalue = [1, 19]"] ;
25 | 9 -> 11 ;
26 | 12 [label="gini = 0.0\nsamples = 1\nvalue = [1, 0]"] ;
27 | 11 -> 12 ;
28 | 13 [label="gini = 0.0\nsamples = 19\nvalue = [0, 19]"] ;
29 | 11 -> 13 ;
30 | 14 [label="X[4] <= 0.016\ngini = 0.26\nsamples = 13\nvalue = [2, 11]"] ;
31 | 4 -> 14 ;
32 | 15 [label="gini = 0.0\nsamples = 1\nvalue = [1, 0]"] ;
33 | 14 -> 15 ;
34 | 16 [label="X[10] <= 0.117\ngini = 0.153\nsamples = 12\nvalue = [1, 11]"] ;
35 | 14 -> 16 ;
36 | 17 [label="gini = 0.0\nsamples = 11\nvalue = [0, 11]"] ;
37 | 16 -> 17 ;
38 | 18 [label="gini = 0.0\nsamples = 1\nvalue = [1, 0]"] ;
39 | 16 -> 18 ;
40 | 19 [label="X[6] <= 25.67\ngini = 0.476\nsamples = 46\nvalue = [28, 18]"] ;
41 | 1 -> 19 ;
42 | 20 [label="X[7] <= 810.3\ngini = 0.332\nsamples = 19\nvalue = [4, 15]"] ;
43 | 19 -> 20 ;
44 | 21 [label="X[8] <= 0.179\ngini = 0.124\nsamples = 15\nvalue = [1, 14]"] ;
45 | 20 -> 21 ;
46 | 22 [label="gini = 0.0\nsamples = 14\nvalue = [0, 14]"] ;
47 | 21 -> 22 ;
48 | 23 [label="gini = 0.0\nsamples = 1\nvalue = [1, 0]"] ;
49 | 21 -> 23 ;
50 | 24 [label="X[3] <= 0.005\ngini = 0.375\nsamples = 4\nvalue = [3, 1]"] ;
51 | 20 -> 24 ;
52 | 25 [label="gini = 0.0\nsamples = 1\nvalue = [0, 1]"] ;
53 | 24 -> 25 ;
54 | 26 [label="gini = 0.0\nsamples = 3\nvalue = [3, 0]"] ;
55 | 24 -> 26 ;
56 | 27 [label="X[1] <= 0.054\ngini = 0.198\nsamples = 27\nvalue = [24, 3]"] ;
57 | 19 -> 27 ;
58 | 28 [label="X[0] <= 20.455\ngini = 0.5\nsamples = 6\nvalue = [3, 3]"] ;
59 | 27 -> 28 ;
60 | 29 [label="gini = 0.0\nsamples = 3\nvalue = [0, 3]"] ;
61 | 28 -> 29 ;
62 | 30 [label="gini = 0.0\nsamples = 3\nvalue = [3, 0]"] ;
63 | 28 -> 30 ;
64 | 31 [label="gini = 0.0\nsamples = 21\nvalue = [21, 0]"] ;
65 | 27 -> 31 ;
66 | 32 [label="X[0] <= 16.11\ngini = 0.109\nsamples = 190\nvalue = [179, 11]"] ;
67 | 0 -> 32 [labeldistance=2.5, labelangle=-45, headlabel="False"] ;
68 | 33 [label="X[1] <= 0.066\ngini = 0.498\nsamples = 17\nvalue = [8, 9]"] ;
69 | 32 -> 33 ;
70 | 34 [label="gini = 0.0\nsamples = 9\nvalue = [0, 9]"] ;
71 | 33 -> 34 ;
72 | 35 [label="gini = 0.0\nsamples = 8\nvalue = [8, 0]"] ;
73 | 33 -> 35 ;
74 | 36 [label="X[8] <= 0.088\ngini = 0.023\nsamples = 173\nvalue = [171, 2]"] ;
75 | 32 -> 36 ;
76 | 37 [label="gini = 0.0\nsamples = 1\nvalue = [0, 1]"] ;
77 | 36 -> 37 ;
78 | 38 [label="X[9] <= 0.18\ngini = 0.012\nsamples = 172\nvalue = [171, 1]"] ;
79 | 36 -> 38 ;
80 | 39 [label="X[11] <= 0.242\ngini = 0.375\nsamples = 4\nvalue = [3, 1]"] ;
81 | 38 -> 39 ;
82 | 40 [label="gini = 0.0\nsamples = 1\nvalue = [0, 1]"] ;
83 | 39 -> 40 ;
84 | 41 [label="gini = 0.0\nsamples = 3\nvalue = [3, 0]"] ;
85 | 39 -> 41 ;
86 | 42 [label="gini = 0.0\nsamples = 168\nvalue = [168, 0]"] ;
87 | 38 -> 42 ;
88 | }
89 |
--------------------------------------------------------------------------------
/ABY_example/dectree/UCI_dectrees/breast:
--------------------------------------------------------------------------------
1 | digraph Tree {
2 | node [shape=box] ;
3 | 0 [label="X[5] <= 16.795\ngini = 0.468\nsamples = 569\nvalue = [212, 357]"] ;
4 | 1 [label="X[10] <= 0.136\ngini = 0.159\nsamples = 379\nvalue = [33, 346]"] ;
5 | 0 -> 1 [labeldistance=2.5, labelangle=45, headlabel="True"] ;
6 | 2 [label="X[4] <= 0.009\ngini = 0.03\nsamples = 333\nvalue = [5, 328]"] ;
7 | 1 -> 2 ;
8 | 3 [label="gini = 0.0\nsamples = 1\nvalue = [1, 0]"] ;
9 | 2 -> 3 ;
10 | 4 [label="X[2] <= 38.605\ngini = 0.024\nsamples = 332\nvalue = [4, 328]"] ;
11 | 2 -> 4 ;
12 | 5 [label="X[3] <= 0.003\ngini = 0.012\nsamples = 319\nvalue = [2, 317]"] ;
13 | 4 -> 5 ;
14 | 6 [label="X[9] <= 0.195\ngini = 0.245\nsamples = 7\nvalue = [1, 6]"] ;
15 | 5 -> 6 ;
16 | 7 [label="gini = 0.0\nsamples = 6\nvalue = [0, 6]"] ;
17 | 6 -> 7 ;
18 | 8 [label="gini = 0.0\nsamples = 1\nvalue = [1, 0]"] ;
19 | 6 -> 8 ;
20 | 9 [label="X[6] <= 33.27\ngini = 0.006\nsamples = 312\nvalue = [1, 311]"] ;
21 | 5 -> 9 ;
22 | 10 [label="gini = 0.0\nsamples = 292\nvalue = [0, 292]"] ;
23 | 9 -> 10 ;
24 | 11 [label="X[6] <= 33.56\ngini = 0.095\nsamples = 20\nvalue = [1, 19]"] ;
25 | 9 -> 11 ;
26 | 12 [label="gini = 0.0\nsamples = 1\nvalue = [1, 0]"] ;
27 | 11 -> 12 ;
28 | 13 [label="gini = 0.0\nsamples = 19\nvalue = [0, 19]"] ;
29 | 11 -> 13 ;
30 | 14 [label="X[4] <= 0.016\ngini = 0.26\nsamples = 13\nvalue = [2, 11]"] ;
31 | 4 -> 14 ;
32 | 15 [label="gini = 0.0\nsamples = 1\nvalue = [1, 0]"] ;
33 | 14 -> 15 ;
34 | 16 [label="X[10] <= 0.117\ngini = 0.153\nsamples = 12\nvalue = [1, 11]"] ;
35 | 14 -> 16 ;
36 | 17 [label="gini = 0.0\nsamples = 11\nvalue = [0, 11]"] ;
37 | 16 -> 17 ;
38 | 18 [label="gini = 0.0\nsamples = 1\nvalue = [1, 0]"] ;
39 | 16 -> 18 ;
40 | 19 [label="X[6] <= 25.67\ngini = 0.476\nsamples = 46\nvalue = [28, 18]"] ;
41 | 1 -> 19 ;
42 | 20 [label="X[7] <= 810.3\ngini = 0.332\nsamples = 19\nvalue = [4, 15]"] ;
43 | 19 -> 20 ;
44 | 21 [label="X[8] <= 0.179\ngini = 0.124\nsamples = 15\nvalue = [1, 14]"] ;
45 | 20 -> 21 ;
46 | 22 [label="gini = 0.0\nsamples = 14\nvalue = [0, 14]"] ;
47 | 21 -> 22 ;
48 | 23 [label="gini = 0.0\nsamples = 1\nvalue = [1, 0]"] ;
49 | 21 -> 23 ;
50 | 24 [label="X[3] <= 0.005\ngini = 0.375\nsamples = 4\nvalue = [3, 1]"] ;
51 | 20 -> 24 ;
52 | 25 [label="gini = 0.0\nsamples = 1\nvalue = [0, 1]"] ;
53 | 24 -> 25 ;
54 | 26 [label="gini = 0.0\nsamples = 3\nvalue = [3, 0]"] ;
55 | 24 -> 26 ;
56 | 27 [label="X[1] <= 0.054\ngini = 0.198\nsamples = 27\nvalue = [24, 3]"] ;
57 | 19 -> 27 ;
58 | 28 [label="X[0] <= 20.455\ngini = 0.5\nsamples = 6\nvalue = [3, 3]"] ;
59 | 27 -> 28 ;
60 | 29 [label="gini = 0.0\nsamples = 3\nvalue = [0, 3]"] ;
61 | 28 -> 29 ;
62 | 30 [label="gini = 0.0\nsamples = 3\nvalue = [3, 0]"] ;
63 | 28 -> 30 ;
64 | 31 [label="gini = 0.0\nsamples = 21\nvalue = [21, 0]"] ;
65 | 27 -> 31 ;
66 | 32 [label="X[0] <= 16.11\ngini = 0.109\nsamples = 190\nvalue = [179, 11]"] ;
67 | 0 -> 32 [labeldistance=2.5, labelangle=-45, headlabel="False"] ;
68 | 33 [label="X[1] <= 0.066\ngini = 0.498\nsamples = 17\nvalue = [8, 9]"] ;
69 | 32 -> 33 ;
70 | 34 [label="gini = 0.0\nsamples = 9\nvalue = [0, 9]"] ;
71 | 33 -> 34 ;
72 | 35 [label="gini = 0.0\nsamples = 8\nvalue = [8, 0]"] ;
73 | 33 -> 35 ;
74 | 36 [label="X[8] <= 0.088\ngini = 0.023\nsamples = 173\nvalue = [171, 2]"] ;
75 | 32 -> 36 ;
76 | 37 [label="gini = 0.0\nsamples = 1\nvalue = [0, 1]"] ;
77 | 36 -> 37 ;
78 | 38 [label="X[9] <= 0.18\ngini = 0.012\nsamples = 172\nvalue = [171, 1]"] ;
79 | 36 -> 38 ;
80 | 39 [label="X[11] <= 0.242\ngini = 0.375\nsamples = 4\nvalue = [3, 1]"] ;
81 | 38 -> 39 ;
82 | 40 [label="gini = 0.0\nsamples = 1\nvalue = [0, 1]"] ;
83 | 39 -> 40 ;
84 | 41 [label="gini = 0.0\nsamples = 3\nvalue = [3, 0]"] ;
85 | 39 -> 41 ;
86 | 42 [label="gini = 0.0\nsamples = 168\nvalue = [168, 0]"] ;
87 | 38 -> 42 ;
88 | }
89 |
--------------------------------------------------------------------------------
/ABY_example/dectree/common/dectree.h:
--------------------------------------------------------------------------------
1 | /**
2 | \file dectree.cpp
3 | \author kiss@encrypto.cs.tu-darmstadt.de
4 | \copyright ABY - A Framework for Efficient Mixed-protocol Secure Two-party Computation
5 | Copyright (C) 2019 Engineering Cryptographic Protocols Group, TU Darmstadt
6 | This program is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU Lesser General Public License as published
8 | by the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 | ABY is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | GNU Lesser General Public License for more details.
14 | You should have received a copy of the GNU Lesser General Public License
15 | along with this program. If not, see .
16 | \brief Decision tree implementation
17 | */
18 |
19 | #ifndef DECTREE_H_INCLUDED
20 | #define DECTREE_H_INCLUDED
21 |
22 | #include
23 | #include
24 | #include
25 | #include
26 | #include
27 | #include
28 | #include
29 | #include
30 | #include
31 | #include
32 | #include
33 | #include /* pow */
34 |
35 | using namespace std;
36 |
37 | class DecTree {
38 | public:
39 | struct Node {
40 | // Pointer to the first child node
41 | Node* left;
42 | // Pointer to the second child node
43 | Node* right;
44 | // Pointer to the first parent node
45 | Node* parent;
46 | // True if the edges coming into the node are already colored
47 | uint32_t level;
48 | // True if the node is a leaf
49 | bool leaf;
50 | // Threshold in decision node to compare with
51 | uint64_t threshold;
52 | // Threshold in decision node to compare with
53 | uint64_t classification;
54 | // Attribute index to compare with, -1 if undefined
55 | uint32_t attribute_index;
56 |
57 | Node();
58 | Node(const Node&);
59 | };
60 | // Vector of nodes that belong to the Gamma1 graph
61 | vector node_vec;
62 | // Vector of decision nodes that belong to the Gamma1 graph
63 | vector decnode_vec;
64 | //Node** node_array;
65 | // Vector of all attributes used for comparison with their occurrence
66 | vector attributes;
67 | // Vector of all thresholds used for comparison with their occurrence
68 | vector thresholds;
69 |
70 | //STATISTICS FOR DECISION TREES
71 | //number of attributes
72 | uint32_t num_attributes;
73 | //number of decision nodes
74 | uint32_t num_dec_nodes;
75 | //depth = largest level of leaves
76 | uint32_t depth;
77 | //number of leaves
78 | uint32_t num_of_leaves;
79 | //dummy in our case
80 | uint32_t dummy_non_full;
81 |
82 | DecTree();
83 | DecTree(const DecTree&);
84 |
85 | void add_node(Node*);
86 | void add_decnode(Node*);
87 | void add_edge(Node*, Node*);
88 | void read_from_file(string);
89 | void evaluate(vector inputs);
90 | void depthPad();
91 | void fullTree(uint32_t num_att, uint32_t depth);
92 |
93 | ~DecTree();
94 | };
95 |
96 | void tokenize(const std::string&, std::vector&);
97 | void eraseSubStr(std::string &, const std::string &);
98 |
99 | #endif // DECTREE_H_INCLUDED
100 |
--------------------------------------------------------------------------------
/ABY_example/dectree/common/selection_blocks/e_SelectionBlock.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | \file e_SelectionBlock.cpp
3 | \author masoud.naderpour@helsinki.fi
4 | \author michael.zohner@ec-spride.de
5 | \copyright ABY - A Framework for Efficient Mixed-protocol Secure Two-party Computation
6 | Copyright (C) 2019 Engineering Cryptographic Protocols Group, TU Darmstadt
7 | This program is free software: you can redistribute it and/or modify
8 | it under the terms of the GNU Lesser General Public License as published
9 | by the Free Software Foundation, either version 3 of the License, or
10 | (at your option) any later version.
11 | ABY is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU Lesser General Public License for more details.
15 | You should have received a copy of the GNU Lesser General Public License
16 | along with this program. If not, see .
17 | \brief Implementation of extended SelectionBlock
18 | */
19 | #include "e_SelectionBlock.h"
20 | #include "permutation_network.h"
21 |
22 | void e_SelectionBlock::SelectionBlockProgram(uint32_t *p){
23 | uint32_t *prog1, *programm;
24 |
25 | if(m_nNumInputs==1) return;
26 |
27 | // count number of occurrences
28 | vector c;
29 | c.resize(m_nNumInputs);
30 |
31 | for(uint32_t i=0; i=0 && p[i] upos, dummy;
40 | upos.resize(m_nNumInputs);
41 | dummy.resize(m_nNumOutputs); // list of dummy outputs
42 |
43 | for(uint32_t i=0; i0) {
45 | prog1[i]=sum;
46 | upos[i]=sum;
47 | if(sum>0) {
48 | setYProgram(sum-1, true);
49 | //m_vYgatesProgram[sum-1] = true;
50 | }
51 | for(uint32_t j = sum+1; j < sum+c[i]; j++) {
52 | setYProgram(j-1, false);
53 | //m_vYgatesProgram[j-1] = false;
54 | dummy[ndummys++]=j;
55 | }
56 | sum+=c[i];
57 | }
58 | }
59 |
60 | // program dummys
61 | uint32_t nextdummy=0;
62 | for(uint32_t i=0; iProgramPermutationNetwork(prog1);
68 |
69 | // program b2
70 |
71 | vector prog2;
72 | prog2.resize(m_nNumOutputs);
73 | for(uint32_t i=0; iProgramPermutationNetwork(programm);
83 | }
84 |
85 | vector > e_SelectionBlock::buildSelectionBlockCircuit(vector >& inputs){
86 | uint32_t rep = inputs[0].size();
87 | vector > out_p1,out_g, outputs;
88 |
89 | if(m_nNumInputs==1) {
90 | for(uint32_t i=0; ibuildPermutationCircuit(inputs);
99 |
100 | out_g.resize(m_nNumOutputs);
101 | out_g[0]=out_p1[0];
102 | for(uint32_t i=1; ibuildPermutationCircuit(out_g);
108 | }
109 | }
110 |
--------------------------------------------------------------------------------
/ABY_example/dectree/decision_tree_test.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | \file decision_tree_test.cpp
3 | \author masoud.naderpour@helsinki.fi
4 | \copyright ABY - A Framework for Efficient Mixed-protocol Secure Two-party Computation
5 | Copyright (C) 2019 Engineering Cryptographic Protocols Group, TU Darmstadt
6 | This program is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU Lesser General Public License as published
8 | by the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 | ABY is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | GNU Lesser General Public License for more details.
14 | You should have received a copy of the GNU Lesser General Public License
15 | along with this program. If not, see .
16 | \brief Private decision tree evaluation
17 | */
18 |
19 | //Utility libs
20 | #include
21 | #include
22 | //ABY Party class
23 | #include "../../abycore/aby/abyparty.h"
24 | #include "common/decision-tree-circuit.h"
25 | #include "common/dectree.h"
26 | #include
27 |
28 | int32_t read_test_options(int32_t* argcp, char*** argvp, e_role* role, uint32_t* bitlen, string* filename, uint32_t* depth, uint32_t* dim, uint64_t* numNodes, uint32_t* secparam, string* address, uint16_t* port, int32_t* test_op) {
29 |
30 | uint32_t int_role = 0, int_port = 0;
31 | bool useffc = false;
32 |
33 | parsing_ctx options[] = { { (void*) &int_role, T_NUM, "r", "Role: 0/1", true, false },
34 | { (void*) filename, T_STR, "f", "Input file, e.g. wine, boston, ... (provide either an input file or depth & dimension)", false, false },
35 | { (void*) depth, T_NUM, "d", "Depth of tree, default: 4", false, false },
36 | { (void*) dim, T_NUM, "n", "Dimension of feature vector, default: 8", false, false },
37 | { (void*) numNodes, T_NUM, "m", "Number of Decision Nodes, default: 15", false, false },
38 | { (void*) bitlen, T_NUM, "b", "Bit-length, default 32", false, false },
39 | { (void*) secparam, T_NUM, "s", "Symmetric Security Bits, default: 128", false, false },
40 | { (void*) address, T_STR, "a", "IP-address, default: localhost", false, false },
41 | { (void*) &int_port, T_NUM, "p", "Port, default: 7766", false, false },
42 | { (void*) test_op, T_NUM, "t", "Single test (leave out for all operations), default: off", false, false } };
43 |
44 | if (!parse_options(argcp, argvp, options, sizeof(options) / sizeof(parsing_ctx))) {
45 | print_usage(*argvp[0], options, sizeof(options) / sizeof(parsing_ctx));
46 | cout << "Exiting" << endl;
47 | exit(0);
48 | }
49 |
50 | assert(int_role < 2);
51 | *role = (e_role) int_role;
52 |
53 | if (int_port != 0) {
54 | assert(int_port < 1 << (sizeof(uint16_t) * 8));
55 | *port = (uint16_t) int_port;
56 | }
57 |
58 | cout << endl;
59 |
60 | //delete options;
61 |
62 | return 1;
63 | }
64 |
65 | int main(int argc, char** argv) {
66 |
67 | e_role role;
68 | uint32_t bitlen, secparam = 128, nthreads = 1;
69 | seclvl seclvl = get_sec_lvl(secparam);
70 | uint16_t nodeSize, port = 7760;
71 | string address = "127.0.0.1";
72 | int32_t test_op = -1;
73 | e_mt_gen_alg mt_alg = MT_OT;
74 | e_sel_alg sel_alg = SEL_GC;
75 | timeval tbegin, tend;
76 |
77 | //----Tree Params------
78 | uint32_t featureVecDimension = 8, depth = 4; //defaults
79 | uint64_t numNodes = (1 << depth) - 1; // number of decision nodes
80 | string dectree_rootdir = "../../src/examples/dectree/UCI_dectrees/";
81 | string dectree_filename = "wine";
82 |
83 | read_test_options(&argc, &argv, &role, &bitlen, &dectree_filename, &depth, &featureVecDimension, &numNodes, &secparam, &address, &port, &test_op);
84 |
85 | DecTree tree;
86 | tree.read_from_file(dectree_rootdir + dectree_filename);
87 | tree.depthPad();
88 | //tree.fullTree(featureVecDimension, depth);
89 | featureVecDimension = tree.num_attributes; numNodes = tree.num_dec_nodes; //Setting new values if reading from file
90 |
91 | cout << "Testing GGG & HGG protocols..." << endl;
92 | cout << "Number of decision nodes: " << numNodes << "\tFeature vector dimension: " << featureVecDimension << endl;
93 | cout << "\n----------------GGG Protocol----------------" << endl;
94 |
95 | /* ===GGG=== */
96 | pri_eval_decision_tree(role, (char*) address.c_str(), port, seclvl, nthreads, mt_alg, S_YAO,sel_alg, numNodes, featureVecDimension, tree);
97 |
98 | cout << "\n----------------HGG Protocol----------------" << endl;
99 |
100 | /* ===HGG=== */
101 | sel_alg = SEL_HE;
102 | pri_eval_decision_tree(role, (char*) address.c_str(), port, seclvl, nthreads, mt_alg, S_YAO, sel_alg, numNodes, featureVecDimension, tree);
103 |
104 | return 0;
105 | }
106 |
--------------------------------------------------------------------------------
/ABY_example/dectree/common/selection_blocks/permutation_network.h:
--------------------------------------------------------------------------------
1 | /**
2 | \file permutation_network.cpp
3 | \author masoud.naderpour@helsinki.fi
4 | \author michael.zohner@ec-spride.de
5 | \copyright ABY - A Framework for Efficient Mixed-protocol Secure Two-party Computation
6 | Copyright (C) 2019 Engineering Cryptographic Protocols Group, TU Darmstadt
7 | This program is free software: you can redistribute it and/or modify
8 | it under the terms of the GNU Lesser General Public License as published
9 | by the Free Software Foundation, either version 3 of the License, or
10 | (at your option) any later version.
11 | ABY is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU Lesser General Public License for more details.
15 | You should have received a copy of the GNU Lesser General Public License
16 | along with this program. If not, see .
17 | \brief Implementation of WaksmanPermutation
18 | */
19 |
20 |
21 | #ifndef __ABY_PN_H_
22 | #define __ABY_PN_H_
23 |
24 | #include "../../../../abycore/circuit/booleancircuits.h"
25 |
26 | //Some default output that is used if no output is written to
27 | static std::vector > NON_INIT_DEF_OUTPUT;
28 |
29 | uint32_t estimateGates(uint32_t u, uint32_t v);
30 |
31 | class PermutationNetwork {
32 | //double linked list; node n is head
33 | class TodoList {
34 | uint32_t* nextu;
35 | uint32_t* prevu;
36 | uint32_t n;
37 |
38 | public:
39 | void remove(uint32_t x) {
40 | nextu[prevu[x]] = nextu[x];
41 | prevu[nextu[x]] = prevu[x];
42 | }
43 |
44 | uint32_t next() {
45 | uint32_t ret = nextu[n];
46 | if (ret == n)
47 | return -1;
48 | else
49 | return ret;
50 | }
51 |
52 | TodoList(uint32_t num) {
53 | n = num;
54 | nextu = (uint32_t*) malloc(sizeof(uint32_t) * (n + 1)); //new uint32_t[n+1];
55 | prevu = (uint32_t*) malloc(sizeof(uint32_t) * (n + 1)); //new uint32_t[n+1];
56 | for (uint32_t i = 0; i < n + 1; i++) {
57 | nextu[i] = (i + 1) % (n + 1);
58 | prevu[i] = (i + n) % (n + 1);
59 | }
60 | }
61 | };
62 |
63 | class WaksmanPermutation {
64 | public:
65 | WaksmanPermutation* b1;
66 | WaksmanPermutation* b2;
67 |
68 | uint32_t m_nNumInputs;
69 | uint32_t m_nNumOutputs;
70 | uint32_t m_nSizeB2;
71 |
72 | WaksmanPermutation(uint32_t numgates, uint32_t numoutputs, PermutationNetwork* pm);
73 | virtual ~WaksmanPermutation();
74 | //Program the permutation
75 | void program(uint32_t* perm);
76 | void program_rec(uint32_t in, uint32_t block, uint32_t* p1, uint32_t* p2, uint32_t* rows, uint32_t* cols);
77 | std::vector > generateCircuit(std::vector > inputs, std::vector > outputs);
78 |
79 | std::vector s1, s2;
80 | TodoList* Todo;
81 | PermutationNetwork* m_PM;
82 | };
83 |
84 | public:
85 | PermutationNetwork(uint32_t numInputs, uint32_t numOutputs, BooleanCircuit* circ) {
86 | m_nNumIn = numInputs;
87 | m_nNumOut = numOutputs;
88 | gatebuildcounter = 0;
89 | m_cBoolCirc = circ;
90 | m_vSwitchGateProgram.resize(estimateGates(numInputs, numOutputs));
91 | wm = new WaksmanPermutation(numInputs, numOutputs, this);
92 | }
93 |
94 | uint32_t nextGate() {
95 | return gatebuildcounter++;
96 | }
97 | uint32_t getSwapGateAt(uint32_t idx) {
98 | return m_vSwapGates[idx];
99 | }
100 | void setSwitchProgram(uint32_t idx, bool val) {
101 | m_vSwitchGateProgram[idx] = val;
102 | }
103 |
104 | /*void setPermutationGates(std::vector& gates) {
105 | m_vSwapGates = gates;
106 | }*/
107 | void setPermutationGates() {
108 | uint32_t val;
109 | m_vSwapGates.resize(m_vSwitchGateProgram.size());
110 | for (uint32_t i = 0; i < m_vSwitchGateProgram.size(); i++) {
111 | val = (uint32_t) m_vSwitchGateProgram[i];
112 | m_vSwapGates[i] = (m_cBoolCirc->PutSIMDINGate(1,val,1,SERVER))->get_wire_id(0);
113 | }
114 | }
115 | std::vector > buildPermutationCircuit(std::vector >& input) {
116 | return wm->generateCircuit(input, NON_INIT_DEF_OUTPUT);
117 | }
118 | std::vector > PutCondSwapGate(std::vector& a, std::vector& b, uint32_t s) {
119 | return m_cBoolCirc->PutCondSwapGate(a, b, s, true);
120 | }
121 | std::vector ProgramPermutationNetwork(uint32_t* permutation) {
122 | wm->program(permutation);
123 | return m_vSwitchGateProgram;
124 | }
125 | private:
126 | uint32_t gatebuildcounter;
127 | uint32_t m_nNumIn;
128 | uint32_t m_nNumOut;
129 | std::vector m_vSwitchGateProgram; //contains the actual program for the swapgates to achieve the output permutation
130 | std::vector m_vSwapGates; //contains the gate addresses of the swapgates
131 | WaksmanPermutation* wm;
132 | BooleanCircuit* m_cBoolCirc;
133 |
134 | };
135 |
136 | #endif /* __ABY_PN_H_ */
137 |
--------------------------------------------------------------------------------
/ABY_example/dectree/common/selection_blocks/t_SelectionBlock.h:
--------------------------------------------------------------------------------
1 | /**
2 | \file t_SelectionBlock.h
3 | \author masoud.naderpour@helsinki.fi
4 | \copyright ABY - A Framework for Efficient Mixed-protocol Secure Two-party Computation
5 | Copyright (C) 2019 Engineering Cryptographic Protocols Group, TU Darmstadt
6 | This program is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU Lesser General Public License as published
8 | by the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 | ABY is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | GNU Lesser General Public License for more details.
14 | You should have received a copy of the GNU Lesser General Public License
15 | along with this program. If not, see .
16 | \brief Implementation of truncated SelectionBlock
17 | */
18 | #ifndef __ABY_T_SELECTIONBLOCK_H_
19 | #define __ABY_T_SELECTIONBLOCK_H_
20 |
21 | #include
22 | #include
23 | #include "stdio.h"
24 | #include
25 | #include "../../../../abycore/circuit/booleancircuits.h"
26 | #include "selection_block.h"
27 | #include "permutation_network.h"
28 |
29 | using namespace std;
30 |
31 | //TODO: Generate destructor methods
32 |
33 | class Truncated_PN{
34 | //double linked list; node n is head
35 | class TodoList {
36 | uint32_t* nextu;
37 | uint32_t* prevu;
38 | uint32_t n;
39 |
40 | public:
41 | void remove(uint32_t x) {
42 | nextu[prevu[x]] = nextu[x];
43 | prevu[nextu[x]] = prevu[x];
44 | }
45 |
46 | uint32_t next() {
47 | uint32_t ret = nextu[n];
48 | if (ret == n)
49 | return -1;
50 | else
51 | return ret;
52 | }
53 |
54 | TodoList(uint32_t num) {
55 | n = num;
56 | nextu = (uint32_t*) malloc(sizeof(uint32_t) * (n + 1)); //new uint32_t[n+1];
57 | prevu = (uint32_t*) malloc(sizeof(uint32_t) * (n + 1)); //new uint32_t[n+1];
58 | for (uint32_t i = 0; i < n + 1; i++) {
59 | nextu[i] = (i + 1) % (n + 1);
60 | prevu[i] = (i + n) % (n + 1);
61 | }
62 | }
63 | };
64 |
65 | class WaksmanPermutation {
66 | public:
67 | WaksmanPermutation* b1;
68 | WaksmanPermutation* b2;
69 |
70 | uint32_t m_nNumInputs;
71 | uint32_t m_nNumOutputs;
72 | uint32_t m_nSizeB2;
73 |
74 | WaksmanPermutation(uint32_t numgates, uint32_t numoutputs, Truncated_PN* pm);
75 | virtual ~WaksmanPermutation();
76 | //Program the permutation
77 | void program(uint32_t* perm);
78 | void program_rec(uint32_t out, uint32_t block, uint32_t* p1, uint32_t* p2, uint32_t* rows, uint32_t* cols);
79 | vector > generateCircuit(vector > inputs, vector > outputs);
80 |
81 | vector s1, s2;
82 | vector m_vYGates;
83 | vector m_vYgatesProgram;
84 | TodoList* Todo;
85 | Truncated_PN* m_PM;
86 | };
87 |
88 | public:
89 | Truncated_PN(uint32_t numInputs, uint32_t numOutputs, BooleanCircuit* circ) {
90 | m_nNumIn = numInputs;
91 | m_nNumOut = numOutputs;
92 | gatebuildcounter = 0;
93 | m_cBoolCirc = circ;
94 | m_vSwitchGateProgram.resize(numInputs-1);
95 | m_vSwitchGateProgram.resize(estimateGates(numInputs, numOutputs));
96 | wm = new WaksmanPermutation(numInputs, numOutputs, this);
97 | }
98 |
99 | uint32_t nextGate() {
100 | return gatebuildcounter++;
101 | }
102 | uint32_t getSwapGateAt(uint32_t idx) {
103 | return m_vSwapGates[idx];
104 | }
105 | void setSwitchProgram(uint32_t idx, bool val) {
106 | m_vSwitchGateProgram[idx] = val;
107 | }
108 |
109 | /*void setPermutationGates(vector& gates) {
110 | m_vSwapGates = gates;
111 | }*/
112 | void setPermutationGates() {
113 | uint32_t val;
114 | m_vSwapGates.resize(m_vSwitchGateProgram.size());
115 | for (uint32_t i = 0; i < m_vSwitchGateProgram.size(); i++) {
116 | val = (uint32_t) m_vSwitchGateProgram[i];
117 | m_vSwapGates[i] = (m_cBoolCirc->PutSIMDINGate(1,val,1,SERVER))->get_wire_id(0);
118 | }
119 | }
120 | vector > buildPermutationCircuit(vector >& input) {
121 | return wm->generateCircuit(input, NON_INIT_DEF_OUTPUT);
122 | }
123 | vector > PutCondSwapGate(vector& a, vector& b, uint32_t s) {
124 | return m_cBoolCirc->PutCondSwapGate(a, b, s, true);
125 | }
126 | vector PutCondYGate(vector& a, vector& b, uint32_t s) {
127 | //return m_cBoolCirc->PutCondYGate(a, b, s, true);
128 | return m_cBoolCirc->PutMUXGate(b, a, s);
129 | }
130 | vector ProgramPermutationNetwork(uint32_t* permutation) {
131 | wm->program(permutation);
132 | return m_vSwitchGateProgram;
133 | }
134 | private:
135 | uint32_t gatebuildcounter;
136 | uint32_t m_nNumIn;
137 | uint32_t m_nNumOut;
138 | vector m_vSwitchGateProgram;
139 | vector m_vSwapGates; //gate addresses of the swapgates
140 | WaksmanPermutation* wm;
141 | BooleanCircuit* m_cBoolCirc;
142 |
143 | };
144 |
145 | class t_SelectionBlock : public SelectionBlock {
146 | //private:
147 | public:
148 | Truncated_PN *m_Pblock1;
149 | PermutationNetwork *m_Pblock2;
150 | uint32_t m_nNumInputs, m_nNumOutputs;
151 | vector m_vYgatesProgram;
152 | vector m_vYGates;
153 | BooleanCircuit* m_cBoolCirc;
154 | //public:
155 | t_SelectionBlock (uint32_t numInputs, uint32_t numOutputs, BooleanCircuit* circ){
156 | m_nNumInputs = numInputs;
157 | m_nNumOutputs = numOutputs;
158 | m_vYgatesProgram.resize(m_nNumOutputs-1);
159 | m_vYGates.resize(m_nNumOutputs-1);
160 | m_Pblock1 = new Truncated_PN(numInputs, numOutputs, circ); // Truncated PermutationNetwork(u,v) [v>u]
161 | m_Pblock2 = new PermutationNetwork(numOutputs, numOutputs, circ);// PermutationNetwork(v,v)
162 | m_cBoolCirc = circ;
163 | }
164 |
165 | void SelectionBlockProgram(uint32_t *p);
166 | uint32_t getYGateAt(uint32_t idx) {
167 | return m_vYGates[idx];
168 | }
169 | void setYProgram(uint32_t idx, bool val) {
170 | m_vYgatesProgram[idx] = val;
171 | }
172 | void setYGates() {
173 | uint32_t val;
174 | for (uint32_t i = 0; i < m_nNumOutputs-1 ; i++){
175 | val = (uint32_t) m_vYgatesProgram[i];
176 | m_vYGates[i] = (m_cBoolCirc->PutSIMDINGate(1,val,1,SERVER))->get_wire_id(0);
177 | }
178 | }
179 | void SetControlBits(){
180 | m_Pblock1->setPermutationGates();
181 | setYGates();
182 | m_Pblock2->setPermutationGates();
183 | }
184 | vector > buildSelectionBlockCircuit(vector >& input);
185 | vector PutCondYGate(vector& a, vector& b, uint32_t s) {
186 | //return m_cBoolCirc->PutCondYGate(a, b, s, true);
187 | return {m_cBoolCirc->PutCombinerGate(m_cBoolCirc->PutMUXGate(m_cBoolCirc->PutSplitterGate(b[0]), m_cBoolCirc->PutSplitterGate(a[0]), s, true))};
188 | }
189 |
190 | };
191 | #endif /* __ABY_T_SELECTIONBLOCK_H_ */
192 |
--------------------------------------------------------------------------------
/ABY_example/dectree/common/selection_blocks/permutation_network.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | \file permutation_network.cpp
3 | \author masoud.naderpour@helsinki.fi
4 | \author michael.zohner@ec-spride.de
5 | \copyright ABY - A Framework for Efficient Mixed-protocol Secure Two-party Computation
6 | Copyright (C) 2019 Engineering Cryptographic Protocols Group, TU Darmstadt
7 | This program is free software: you can redistribute it and/or modify
8 | it under the terms of the GNU Lesser General Public License as published
9 | by the Free Software Foundation, either version 3 of the License, or
10 | (at your option) any later version.
11 | ABY is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU Lesser General Public License for more details.
15 | You should have received a copy of the GNU Lesser General Public License
16 | along with this program. If not, see .
17 | \brief Implementation of WaksmanPermutation
18 | */
19 |
20 | #include "permutation_network.h"
21 |
22 | uint32_t estimateGates(uint32_t u, uint32_t v) {
23 | if (u == 1)
24 | return 0;
25 | else {
26 | uint32_t s1count = u/2;
27 | uint32_t s2count = (u % 2 == 0 && v % 2 == 0) ? v/2-1 : v/2;
28 | return (s1count + s2count) + estimateGates(u/2, v/2) + estimateGates(u-(u/2), v-(v/2));
29 | }
30 | }
31 |
32 | PermutationNetwork::WaksmanPermutation::~WaksmanPermutation() {
33 | // TODO Auto-generated destructor stub
34 | }
35 |
36 | void PermutationNetwork::WaksmanPermutation::program_rec(uint32_t in, uint32_t block, uint32_t* p1, uint32_t* p2, uint32_t* rows, uint32_t* cols) {
37 | uint32_t out = rows[in];
38 |
39 | if ((in ^ 1) < m_nNumInputs && rows[in ^ 1] != -1) {
40 | m_PM->setSwitchProgram(s1[in / 2], (block == 0) != (in % 2 == 0));
41 | Todo->remove(in / 2);
42 | }
43 |
44 | if (block == 1) {
45 | p2[in / 2] = out / 2;
46 | if (out / 2 < m_nSizeB2) {
47 | m_PM->setSwitchProgram(s2[out / 2], out % 2 == 0);
48 | }
49 | } else { // block==0
50 | p1[in / 2] = out / 2;
51 | if (out / 2 < m_nSizeB2) {
52 | m_PM->setSwitchProgram(s2[out / 2], out % 2 == 1);
53 | }
54 | }
55 | rows[in] = -1;
56 | cols[out] = -1;
57 |
58 | uint32_t newout = out ^ 1;
59 | if (newout < m_nNumOutputs && cols[newout] != -1) {
60 | uint32_t newin = cols[newout];
61 | cols[newout] = -1;
62 | program_rec(newin, block ^ 1, p1, p2, rows, cols);
63 | }
64 |
65 | if ((in ^ 1) < m_nNumInputs && rows[in ^ 1] != -1) {
66 | program_rec(in ^ 1, block ^ 1, p1, p2, rows, cols);
67 | }
68 | }
69 |
70 | void PermutationNetwork::WaksmanPermutation::program(uint32_t* perm) {
71 | if (m_nNumInputs == 1)
72 | return;
73 |
74 | uint32_t* rows = perm;
75 |
76 | uint32_t* cols = (uint32_t*) malloc(sizeof(uint32_t) * m_nNumOutputs); //new uint32_t[v];
77 | for (uint32_t i = 0; i < m_nNumOutputs; i++) cols[i] = -1;
78 | for (uint32_t i = 0; i < m_nNumInputs; i++) {
79 | uint32_t x = perm[i];
80 | assert(x>=0 && xnext(); n != -1; n = Todo->next()) {
101 | program_rec(2 * n, 0, p1, p2, rows, cols);
102 | }
103 |
104 | // program sub-blocks
105 | b1->program(p1);
106 | b2->program(p2);
107 | }
108 |
109 | PermutationNetwork::WaksmanPermutation::WaksmanPermutation(uint32_t numinputs, uint32_t numoutputs, PermutationNetwork* pm) {
110 | assert(numoutputs >= numinputs);
111 | m_nNumInputs = numinputs;
112 | m_nNumOutputs = numoutputs;
113 | m_PM = pm;
114 |
115 | if (numinputs != 1) {
116 | // first row X
117 | s1.resize(m_nNumInputs / 2);
118 |
119 | for (uint32_t i = 0; i < m_nNumInputs / 2; i++)
120 | s1[i] = pm->nextGate();
121 |
122 | //assign wires to X gates and permute them
123 |
124 | // B1
125 | b1 = new WaksmanPermutation(numinputs / 2, numoutputs / 2, pm);
126 |
127 | // B2
128 | b2 = new WaksmanPermutation(numinputs - (numinputs / 2), numoutputs - (numoutputs / 2), pm);
129 |
130 | // last row X
131 | m_nSizeB2 = (numinputs % 2 == 0 && numoutputs % 2 ==0) ? numoutputs / 2 - 1 : numoutputs / 2;
132 | s2.resize(m_nSizeB2);
133 | for (uint32_t i = 0; i < m_nSizeB2; i++)
134 | s2[i] = pm->nextGate();
135 |
136 | }
137 |
138 | }
139 |
140 | std::vector > PermutationNetwork::WaksmanPermutation::generateCircuit(std::vector > inputs, std::vector > outputs) {
141 | uint32_t rep = inputs[0].size();
142 | if (outputs == NON_INIT_DEF_OUTPUT) {
143 | outputs.resize(m_nNumOutputs);
144 | for (uint32_t i = 0; i < m_nNumOutputs; i++) {
145 | outputs[i].resize(rep);
146 | }
147 | }
148 | // wire input to all outputs
149 | if (m_nNumInputs == 1) {
150 | for (uint32_t i = 0; i < m_nNumOutputs; i++){
151 | for (uint32_t j = 0; j < rep; j++){
152 | outputs[i][j] = inputs[0][j];
153 | }
154 | }
155 | return outputs;
156 | }
157 |
158 | uint32_t sizeB2 = m_nNumInputs - (m_nNumInputs / 2);
159 | std::vector > in_p1(m_nNumInputs / 2);
160 | std::vector > in_p2(sizeB2);
161 |
162 | //uint64_t s = 1;
163 | //share *shr_s = m_PM->m_cBoolCirc->PutINGate(1, s, 1, SERVER);
164 |
165 |
166 |
167 | // first row X
168 | std::vector > outtmp(2);
169 |
170 |
171 |
172 | for (uint32_t i = 0; i < s1.size(); i++) {
173 | in_p1[i].resize(rep);
174 | in_p2[i].resize(rep);
175 | //in_p1[i] = inputs[2 * i + m_PM->m_vSwitchGateProgram[s1[i]]];
176 | //in_p2[i] = inputs[2 * i + !(m_PM->m_vSwitchGateProgram[s1[i]])];
177 | outtmp = m_PM->PutCondSwapGate(inputs[2 * i], inputs[2 * i + 1], m_PM->m_vSwapGates[s1[i]]);
178 | for (uint32_t j = 0; j < rep; j++) {
179 | in_p1[i][j] = outtmp[0][j];
180 | in_p2[i][j] = outtmp[1][j];
181 | }
182 |
183 | }
184 |
185 | if (m_nNumInputs % 2 == 1) {
186 | in_p2[sizeB2 - 1].resize(rep);
187 | for (uint32_t i = 0; i < rep; i++)
188 | in_p2[sizeB2 - 1][i] = inputs[m_nNumInputs - 1][i];
189 | }
190 |
191 | std::vector > out_p1 = b1->generateCircuit(in_p1, NON_INIT_DEF_OUTPUT);
192 | std::vector > out_p2 = b2->generateCircuit(in_p2, NON_INIT_DEF_OUTPUT);
193 |
194 | // last row X
195 | for (uint32_t i = 0; i < s2.size(); i++) {
196 |
197 | outtmp = m_PM->PutCondSwapGate(out_p1[i], out_p2[i], m_PM->m_vSwapGates[s2[i]]);
198 | for (uint32_t j = 0; j < rep; j++) {
199 | outputs[2 * i][j] = outtmp[0][j];
200 | outputs[2 * i + 1][j] = outtmp[1][j];
201 | }
202 |
203 |
204 | }
205 |
206 | if(m_nNumOutputs % 2 == 1) {
207 | for (uint32_t i = 0; i < rep; i++){
208 | outputs[m_nNumOutputs - 1][i] = out_p2[out_p2.size()-1][i];
209 | }
210 | } else if (m_nNumInputs % 2 == 0){
211 | for (uint32_t i = 0; i < rep; i++){
212 |
213 | outputs[m_nNumOutputs - 1][i] = out_p2[out_p2.size()-1][i];
214 | outputs[m_nNumOutputs - 2][i] = out_p1[out_p1.size()-1][i];
215 | }
216 | }
217 |
218 | return outputs;
219 | }
220 |
--------------------------------------------------------------------------------
/ABY_example/dectree/common/selection-functions.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | \file selection-functions.cpp
3 | \author masoud.naderpour@helsinki.fi
4 | \copyright ABY - A Framework for Efficient Mixed-protocol Secure Two-party Computation
5 | Copyright (C) 2019 Engineering Cryptographic Protocols Group, TU Darmstadt
6 | This program is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU Lesser General Public License as published
8 | by the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 | ABY is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | GNU Lesser General Public License for more details.
14 | You should have received a copy of the GNU Lesser General Public License
15 | along with this program. If not, see .
16 | \brief Selection with HE or GC
17 | */
18 |
19 | #include "decision-tree-circuit.h"
20 | #include "selection_blocks/e_SelectionBlock.h"
21 | #include "selection_blocks/t_SelectionBlock.h"
22 |
23 | #define HE_SCHEME 1 //enum e_HE_crypto_party { e_DGK = 0, e_PAILLIER = 1};
24 |
25 | /**
26 | * Selection function (homomorphic encryption)
27 | */
28 | void selction_HE(e_role role, channel* channel, vector &featureVec, seclvl seclvl, uint64_t numDecisionNodes, uint16_t* permutation, BooleanCircuit* &Circ, share** &CircOut){
29 |
30 | struct timespec start, end, clientOnline;
31 | uint32_t dimension = featureVec.size();
32 | uint32_t m_nStatisticalParamBits = 40; // statistical param
33 | uint32_t m_nFeatureSize = 64; // param t
34 | uint32_t m_nPlaintextSize = m_nFeatureSize + m_nStatisticalParamBits;
35 |
36 | /* Initilization */
37 | cryptoParty* cryptoPraty;
38 |
39 | switch(HE_SCHEME) {
40 | case e_DGK: {
41 | cryptoPraty = new DGK(seclvl.ifcbits, (uint32_t) m_nPlaintextSize, 1); // ifcbits = 3072 bits for LT security
42 | }
43 | break;
44 |
45 | case e_PAILLIER:
46 | default: {
47 | cryptoPraty = new PaillierParty(2048, 1); // ifcbits = 3072 bits for LT security
48 | }
49 | break;
50 | }
51 | cryptoPraty->keyExchange(channel);
52 |
53 | gmp_randstate_t m_randstate;
54 | gmp_randinit_default(m_randstate);
55 | gmp_randseed_ui(m_randstate, rand());
56 |
57 | mpz_t *m_pRandomdMasks = (mpz_t*) calloc(numDecisionNodes, sizeof(mpz_t)); // random masks vector
58 | vector m_nRandomMasksVec;
59 | vector m_vSelection; // feature selection function (mapping)
60 |
61 | uint64_t lo, hi;
62 | mpz_t tmp;
63 | mpz_init( tmp );
64 |
65 | for(int i=0; i < numDecisionNodes; i++){
66 | mpz_init(m_pRandomdMasks[i]);
67 | mpz_urandomb (m_pRandomdMasks[i], m_randstate, MaskBitLen); // MaskBitLen 104
68 | m_vSelection.push_back(rand() % dimension); // dummy selection function
69 |
70 | //truncating random masks to sizeof uint64_t
71 | mpz_mod_2exp( tmp, m_pRandomdMasks[i], 64 ); /* tmp = (lower 64 bits of m_pRandomdMasks[i]) */
72 | lo = mpz_get_ui( tmp ); /* lo = tmp & 0xffffffff */
73 | mpz_div_2exp( tmp, tmp, 32 ); /* tmp >>= 32 */
74 | hi = mpz_get_ui( tmp ); /* hi = tmp & 0xffffffff */
75 | m_nRandomMasksVec.push_back((hi << 32) + lo);
76 | }
77 |
78 | mpz_t *m_pEncFeatureVec, *m_pBlindedFeatureVec;
79 |
80 | //--------client encrypts the feature vec and sends it to server----------
81 | clock_gettime(CLOCK_MONOTONIC, &start);
82 | cryptoPraty->encSndRcvVec(role, featureVec, m_pEncFeatureVec, channel);
83 |
84 | //--------server selects & sends the inputs to subtraction circuit----------
85 | cryptoPraty->mskSndRcvVec(role, m_pEncFeatureVec, m_pRandomdMasks, m_vSelection, m_pBlindedFeatureVec, channel); // decrypts the inputs internally
86 | clock_gettime(CLOCK_MONOTONIC, &end);
87 | printf("client online runtime: %.0lf ms \n", getMillies(start, end));
88 |
89 | vector m_vTruncBlindedFeatureVec(numDecisionNodes, 0);
90 | // Truncating client inputs to garbled circuit
91 | if(role == CLIENT){
92 | for(int i= 0; i < numDecisionNodes; i++){
93 | mpz_mod_2exp( tmp, m_pBlindedFeatureVec[i], 64 ); /* tmp = (lower 64 bits of m_pBlindedFeatureVec[i]) */
94 | lo = mpz_get_ui( tmp );
95 | mpz_div_2exp( tmp, tmp, 32 );
96 | hi = mpz_get_ui( tmp );
97 | m_vTruncBlindedFeatureVec[i] = (hi << 32) + lo;
98 | }
99 | cout << "CLIENT: Input truncation done." << endl;
100 | } else {
101 | //SleepMiliSec(10);
102 | }
103 | mpz_clear( tmp );
104 |
105 |
106 | uint64_t maxbitlen = 64;
107 | vector tresholdVec;
108 | share **tresholdShr, **featureVecShr, **rndMasksVecShr;
109 |
110 | //----------------Settign server input ----------------
111 | tresholdShr = (share**) malloc(sizeof(share*) * numDecisionNodes);
112 | for(int i = 0; i < numDecisionNodes; i++) {
113 | tresholdVec.push_back(rand());
114 | tresholdShr[permutation[i]] = Circ->PutSIMDINGate(1, tresholdVec[i], maxbitlen, SERVER);
115 | }
116 | rndMasksVecShr = (share**) malloc(sizeof(share*) * numDecisionNodes);
117 | for(int i = 0; i < numDecisionNodes; i++) {
118 | rndMasksVecShr[i] = Circ->PutSIMDINGate(1, m_nRandomMasksVec[i], maxbitlen, SERVER);
119 | }
120 | //----------------Setting client input-------------
121 | featureVecShr = (share**) malloc(sizeof(share*) * numDecisionNodes);
122 | for(int i = 0; i < numDecisionNodes; i++) {
123 | featureVecShr[i] = Circ->PutSIMDINGate(1, m_vTruncBlindedFeatureVec[i], maxbitlen, CLIENT);
124 | }
125 | //----------------Subtraction & comparison ciruit--------------
126 | CircOut = (share**) malloc(sizeof(share*) * numDecisionNodes);
127 | assert(Circ->GetCircuitType() == C_BOOLEAN);
128 |
129 | for(int i = 0; i < numDecisionNodes; i++) {
130 | CircOut[i] = Circ->PutSUBGate(featureVecShr[i], rndMasksVecShr[i]);
131 | CircOut[i] = Circ->PutGTGate(CircOut[i], tresholdShr[i]);
132 | }
133 | }
134 |
135 | /**
136 | * Selection function (garbled circuit)
137 | */
138 | void selction_GC(vector &featureVec, uint64_t numDecisionNodes, uint16_t* permutation, BooleanCircuit* &Circ, share** &CircOut) {
139 |
140 | uint16_t dim = featureVec.size();
141 | uint16_t m_numNodes = numDecisionNodes;
142 | uint64_t maxbitlen = 64;
143 |
144 | //---- init selectionBlcok ---------------
145 | SelectionBlock *selBlock;
146 | if (m_numNodes >= dim){
147 | selBlock = new e_SelectionBlock(dim, m_numNodes, Circ); // extended SelectionBlock
148 | } else {
149 | selBlock = new t_SelectionBlock(dim, m_numNodes, Circ); // truncated SelectionBlock
150 | }
151 |
152 | //-----------Output Program (Mapping) of Selection Block --------------
153 | uint32_t *m_nMapping = (uint32_t*) malloc(sizeof(uint32_t) * m_numNodes);
154 | for(int i = 0; i < m_numNodes; i++){
155 | m_nMapping[permutation[i]] = rand() % dim;
156 | }
157 | selBlock->SelectionBlockProgram(m_nMapping);
158 | selBlock->SetControlBits();
159 |
160 | vector tresholdVec;
161 | share **tresholdShr, **featureVecShr;
162 |
163 | //----------------Settign server input ----------------
164 | tresholdShr = (share**) malloc(sizeof(share*) * m_numNodes);
165 | for(int i = 0; i < m_numNodes; i++) {
166 | tresholdVec.push_back(rand());
167 | tresholdShr[permutation[i]] = Circ->PutSIMDINGate(1, tresholdVec[i], maxbitlen, SERVER);
168 | }
169 |
170 | //----------------Setting client input-------------
171 | featureVecShr = (share**) malloc(sizeof(share*) * dim);
172 | for(int j = 0; j < dim; j++) {
173 | featureVecShr[j] = Circ->PutSIMDINGate(1, featureVec[j], maxbitlen, CLIENT);
174 | }
175 |
176 | //---------------Building selection circuit--------------
177 | share **out, *cmp, *tmp;
178 |
179 | CircOut = (share**) malloc(sizeof(share*) * m_numNodes);
180 | assert(Circ->GetCircuitType() == C_BOOLEAN);
181 |
182 | vector > Inputs(dim);
183 | for(int i = 0; i < dim; i++){
184 | Inputs[i].resize(1);
185 | Inputs[i][0] = Circ->PutCombinerGate(featureVecShr[i]->get_wires());
186 | }
187 |
188 | vector > tempvec(m_numNodes);
189 | tempvec = selBlock->buildSelectionBlockCircuit(Inputs);
190 |
191 | share **SelectionBlockOutput = (share**) malloc(sizeof(share*) * m_numNodes);
192 | for (int i = 0; i < tempvec.size(); i++){
193 | SelectionBlockOutput[i] = new boolshare(Circ->PutSplitterGate(tempvec[i][0]), Circ);
194 | }
195 |
196 | for (int i=0; i < m_numNodes; i++) {
197 | CircOut[i] = Circ->PutGTGate(SelectionBlockOutput[i], tresholdShr[i]);
198 | }
199 | }
200 |
--------------------------------------------------------------------------------
/UCI_dectrees/linnerud:
--------------------------------------------------------------------------------
1 | digraph Tree {
2 | node [shape=box] ;
3 | 0 [label="X[1] <= 103.0\ngini = 0.895\nsamples = 20\nvalue = [[1, 2, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 2, 1, 1, 1]\n[1, 1, 4, 3, 2, 3, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0]\n[2, 3, 3, 2, 3, 1, 1, 2, 1, 1, 1, 0, 0, 0, 0, 0]]"] ;
4 | 1 [label="X[1] <= 65.0\ngini = 0.759\nsamples = 6\nvalue = [[0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 2, 0, 1, 1]\n[0, 0, 0, 0, 0, 2, 1, 2, 1, 0, 0, 0, 0, 0, 0, 0]\n[1, 1, 0, 1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]"] ;
5 | 0 -> 1 [labeldistance=2.5, labelangle=45, headlabel="True"] ;
6 | 2 [label="X[0] <= 2.5\ngini = 0.5\nsamples = 2\nvalue = [[0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1]\n[0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0]\n[0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]"] ;
7 | 1 -> 2 ;
8 | 3 [label="gini = 0.0\nsamples = 1\nvalue = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]\n[0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]\n[0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]"] ;
9 | 2 -> 3 ;
10 | 4 [label="gini = 0.0\nsamples = 1\nvalue = [[0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]\n[0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]"] ;
11 | 2 -> 4 ;
12 | 5 [label="X[0] <= 7.0\ngini = 0.583\nsamples = 4\nvalue = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 1, 0]\n[0, 0, 0, 0, 0, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0]\n[1, 0, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]"] ;
13 | 1 -> 5 ;
14 | 6 [label="X[0] <= 5.0\ngini = 0.333\nsamples = 2\nvalue = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0]\n[0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]"] ;
15 | 5 -> 6 ;
16 | 7 [label="gini = 0.0\nsamples = 1\nvalue = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0]\n[0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]"] ;
17 | 6 -> 7 ;
18 | 8 [label="gini = 0.0\nsamples = 1\nvalue = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]\n[0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]"] ;
19 | 6 -> 8 ;
20 | 9 [label="X[2] <= 69.5\ngini = 0.333\nsamples = 2\nvalue = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0]\n[0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]"] ;
21 | 5 -> 9 ;
22 | 10 [label="gini = 0.0\nsamples = 1\nvalue = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0]\n[0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]"] ;
23 | 9 -> 10 ;
24 | 11 [label="gini = 0.0\nsamples = 1\nvalue = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]\n[0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]"] ;
25 | 9 -> 11 ;
26 | 12 [label="X[0] <= 13.5\ngini = 0.867\nsamples = 14\nvalue = [[1, 2, 1, 1, 1, 1, 1, 1, 1, 0, 2, 1, 0, 1, 0, 0]\n[1, 1, 4, 3, 2, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[1, 2, 3, 1, 1, 0, 1, 2, 1, 1, 1, 0, 0, 0, 0, 0]]"] ;
27 | 0 -> 12 [labeldistance=2.5, labelangle=-45, headlabel="False"] ;
28 | 13 [label="X[2] <= 59.0\ngini = 0.823\nsamples = 9\nvalue = [[1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 2, 1, 0, 1, 0, 0]\n[0, 1, 2, 1, 2, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[1, 1, 3, 0, 0, 0, 1, 2, 0, 1, 0, 0, 0, 0, 0, 0]]"] ;
29 | 12 -> 13 ;
30 | 14 [label="X[0] <= 9.0\ngini = 0.708\nsamples = 4\nvalue = [[1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0]\n[0, 0, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0]]"] ;
31 | 13 -> 14 ;
32 | 15 [label="X[1] <= 117.5\ngini = 0.5\nsamples = 2\nvalue = [[1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0]]"] ;
33 | 14 -> 15 ;
34 | 16 [label="gini = 0.0\nsamples = 1\nvalue = [[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0]]"] ;
35 | 15 -> 16 ;
36 | 17 [label="gini = 0.0\nsamples = 1\nvalue = [[0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0]]"] ;
37 | 15 -> 17 ;
38 | 18 [label="X[0] <= 12.5\ngini = 0.333\nsamples = 2\nvalue = [[0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0]\n[0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0]]"] ;
39 | 14 -> 18 ;
40 | 19 [label="gini = 0.0\nsamples = 1\nvalue = [[0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0]]"] ;
41 | 18 -> 19 ;
42 | 20 [label="gini = 0.0\nsamples = 1\nvalue = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0]\n[0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]"] ;
43 | 18 -> 20 ;
44 | 21 [label="X[2] <= 117.5\ngini = 0.693\nsamples = 5\nvalue = [[0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0]\n[0, 1, 1, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 1, 3, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0]]"] ;
45 | 13 -> 21 ;
46 | 22 [label="X[2] <= 70.0\ngini = 0.625\nsamples = 4\nvalue = [[0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0]\n[0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]"] ;
47 | 21 -> 22 ;
48 | 23 [label="X[1] <= 136.0\ngini = 0.5\nsamples = 2\nvalue = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0]\n[0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]"] ;
49 | 22 -> 23 ;
50 | 24 [label="gini = 0.0\nsamples = 1\nvalue = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0]\n[0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]"] ;
51 | 23 -> 24 ;
52 | 25 [label="gini = 0.0\nsamples = 1\nvalue = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]\n[0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]"] ;
53 | 23 -> 25 ;
54 | 26 [label="X[1] <= 220.0\ngini = 0.333\nsamples = 2\nvalue = [[0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]"] ;
55 | 22 -> 26 ;
56 | 27 [label="gini = 0.0\nsamples = 1\nvalue = [[0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]"] ;
57 | 26 -> 27 ;
58 | 28 [label="gini = 0.0\nsamples = 1\nvalue = [[0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]"] ;
59 | 26 -> 28 ;
60 | 29 [label="gini = 0.0\nsamples = 1\nvalue = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0]\n[0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0]]"] ;
61 | 21 -> 29 ;
62 | 30 [label="X[1] <= 220.0\ngini = 0.72\nsamples = 5\nvalue = [[0, 2, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0]\n[1, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0]]"] ;
63 | 12 -> 30 ;
64 | 31 [label="X[0] <= 14.5\ngini = 0.593\nsamples = 3\nvalue = [[0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0]\n[1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0]]"] ;
65 | 30 -> 31 ;
66 | 32 [label="gini = 0.0\nsamples = 1\nvalue = [[0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]]"] ;
67 | 31 -> 32 ;
68 | 33 [label="X[2] <= 39.0\ngini = 0.5\nsamples = 2\nvalue = [[0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0]\n[1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0]]"] ;
69 | 31 -> 33 ;
70 | 34 [label="gini = 0.0\nsamples = 1\nvalue = [[0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]"] ;
71 | 33 -> 34 ;
72 | 35 [label="gini = 0.0\nsamples = 1\nvalue = [[0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]\n[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0]]"] ;
73 | 33 -> 35 ;
74 | 36 [label="X[2] <= 161.5\ngini = 0.333\nsamples = 2\nvalue = [[0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]"] ;
75 | 30 -> 36 ;
76 | 37 [label="gini = 0.0\nsamples = 1\nvalue = [[0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]"] ;
77 | 36 -> 37 ;
78 | 38 [label="gini = 0.0\nsamples = 1\nvalue = [[0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]"] ;
79 | 36 -> 38 ;
80 | }
81 |
--------------------------------------------------------------------------------
/ABY_example/dectree/UCI_dectrees/linnerud:
--------------------------------------------------------------------------------
1 | digraph Tree {
2 | node [shape=box] ;
3 | 0 [label="X[1] <= 103.0\ngini = 0.895\nsamples = 20\nvalue = [[1, 2, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 2, 1, 1, 1]\n[1, 1, 4, 3, 2, 3, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0]\n[2, 3, 3, 2, 3, 1, 1, 2, 1, 1, 1, 0, 0, 0, 0, 0]]"] ;
4 | 1 [label="X[1] <= 65.0\ngini = 0.759\nsamples = 6\nvalue = [[0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 2, 0, 1, 1]\n[0, 0, 0, 0, 0, 2, 1, 2, 1, 0, 0, 0, 0, 0, 0, 0]\n[1, 1, 0, 1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]"] ;
5 | 0 -> 1 [labeldistance=2.5, labelangle=45, headlabel="True"] ;
6 | 2 [label="X[0] <= 2.5\ngini = 0.5\nsamples = 2\nvalue = [[0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1]\n[0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0]\n[0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]"] ;
7 | 1 -> 2 ;
8 | 3 [label="gini = 0.0\nsamples = 1\nvalue = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]\n[0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]\n[0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]"] ;
9 | 2 -> 3 ;
10 | 4 [label="gini = 0.0\nsamples = 1\nvalue = [[0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]\n[0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]"] ;
11 | 2 -> 4 ;
12 | 5 [label="X[0] <= 7.0\ngini = 0.583\nsamples = 4\nvalue = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 1, 0]\n[0, 0, 0, 0, 0, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0]\n[1, 0, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]"] ;
13 | 1 -> 5 ;
14 | 6 [label="X[0] <= 5.0\ngini = 0.333\nsamples = 2\nvalue = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0]\n[0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]"] ;
15 | 5 -> 6 ;
16 | 7 [label="gini = 0.0\nsamples = 1\nvalue = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0]\n[0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]"] ;
17 | 6 -> 7 ;
18 | 8 [label="gini = 0.0\nsamples = 1\nvalue = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]\n[0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]"] ;
19 | 6 -> 8 ;
20 | 9 [label="X[2] <= 69.5\ngini = 0.333\nsamples = 2\nvalue = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0]\n[0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]"] ;
21 | 5 -> 9 ;
22 | 10 [label="gini = 0.0\nsamples = 1\nvalue = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0]\n[0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]"] ;
23 | 9 -> 10 ;
24 | 11 [label="gini = 0.0\nsamples = 1\nvalue = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]\n[0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]"] ;
25 | 9 -> 11 ;
26 | 12 [label="X[0] <= 13.5\ngini = 0.867\nsamples = 14\nvalue = [[1, 2, 1, 1, 1, 1, 1, 1, 1, 0, 2, 1, 0, 1, 0, 0]\n[1, 1, 4, 3, 2, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[1, 2, 3, 1, 1, 0, 1, 2, 1, 1, 1, 0, 0, 0, 0, 0]]"] ;
27 | 0 -> 12 [labeldistance=2.5, labelangle=-45, headlabel="False"] ;
28 | 13 [label="X[2] <= 59.0\ngini = 0.823\nsamples = 9\nvalue = [[1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 2, 1, 0, 1, 0, 0]\n[0, 1, 2, 1, 2, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[1, 1, 3, 0, 0, 0, 1, 2, 0, 1, 0, 0, 0, 0, 0, 0]]"] ;
29 | 12 -> 13 ;
30 | 14 [label="X[0] <= 9.0\ngini = 0.708\nsamples = 4\nvalue = [[1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0]\n[0, 0, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0]]"] ;
31 | 13 -> 14 ;
32 | 15 [label="X[1] <= 117.5\ngini = 0.5\nsamples = 2\nvalue = [[1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0]]"] ;
33 | 14 -> 15 ;
34 | 16 [label="gini = 0.0\nsamples = 1\nvalue = [[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0]]"] ;
35 | 15 -> 16 ;
36 | 17 [label="gini = 0.0\nsamples = 1\nvalue = [[0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0]]"] ;
37 | 15 -> 17 ;
38 | 18 [label="X[0] <= 12.5\ngini = 0.333\nsamples = 2\nvalue = [[0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0]\n[0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0]]"] ;
39 | 14 -> 18 ;
40 | 19 [label="gini = 0.0\nsamples = 1\nvalue = [[0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0]]"] ;
41 | 18 -> 19 ;
42 | 20 [label="gini = 0.0\nsamples = 1\nvalue = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0]\n[0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]"] ;
43 | 18 -> 20 ;
44 | 21 [label="X[2] <= 117.5\ngini = 0.693\nsamples = 5\nvalue = [[0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0]\n[0, 1, 1, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 1, 3, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0]]"] ;
45 | 13 -> 21 ;
46 | 22 [label="X[2] <= 70.0\ngini = 0.625\nsamples = 4\nvalue = [[0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0]\n[0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]"] ;
47 | 21 -> 22 ;
48 | 23 [label="X[1] <= 136.0\ngini = 0.5\nsamples = 2\nvalue = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0]\n[0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]"] ;
49 | 22 -> 23 ;
50 | 24 [label="gini = 0.0\nsamples = 1\nvalue = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0]\n[0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]"] ;
51 | 23 -> 24 ;
52 | 25 [label="gini = 0.0\nsamples = 1\nvalue = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]\n[0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]"] ;
53 | 23 -> 25 ;
54 | 26 [label="X[1] <= 220.0\ngini = 0.333\nsamples = 2\nvalue = [[0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]"] ;
55 | 22 -> 26 ;
56 | 27 [label="gini = 0.0\nsamples = 1\nvalue = [[0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]"] ;
57 | 26 -> 27 ;
58 | 28 [label="gini = 0.0\nsamples = 1\nvalue = [[0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]"] ;
59 | 26 -> 28 ;
60 | 29 [label="gini = 0.0\nsamples = 1\nvalue = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0]\n[0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0]]"] ;
61 | 21 -> 29 ;
62 | 30 [label="X[1] <= 220.0\ngini = 0.72\nsamples = 5\nvalue = [[0, 2, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0]\n[1, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0]]"] ;
63 | 12 -> 30 ;
64 | 31 [label="X[0] <= 14.5\ngini = 0.593\nsamples = 3\nvalue = [[0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0]\n[1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0]]"] ;
65 | 30 -> 31 ;
66 | 32 [label="gini = 0.0\nsamples = 1\nvalue = [[0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]]"] ;
67 | 31 -> 32 ;
68 | 33 [label="X[2] <= 39.0\ngini = 0.5\nsamples = 2\nvalue = [[0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0]\n[1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0]]"] ;
69 | 31 -> 33 ;
70 | 34 [label="gini = 0.0\nsamples = 1\nvalue = [[0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]"] ;
71 | 33 -> 34 ;
72 | 35 [label="gini = 0.0\nsamples = 1\nvalue = [[0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]\n[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0]]"] ;
73 | 33 -> 35 ;
74 | 36 [label="X[2] <= 161.5\ngini = 0.333\nsamples = 2\nvalue = [[0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]"] ;
75 | 30 -> 36 ;
76 | 37 [label="gini = 0.0\nsamples = 1\nvalue = [[0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]"] ;
77 | 36 -> 37 ;
78 | 38 [label="gini = 0.0\nsamples = 1\nvalue = [[0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n[0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]"] ;
79 | 36 -> 38 ;
80 | }
81 |
--------------------------------------------------------------------------------
/ABY_example/dectree/common/selection_blocks/t_SelectionBlock.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | \file t_SelectionBlock.cpp
3 | \author masoud.naderpour@helsinki.fi
4 | \copyright ABY - A Framework for Efficient Mixed-protocol Secure Two-party Computation
5 | Copyright (C) 2019 Engineering Cryptographic Protocols Group, TU Darmstadt
6 | This program is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU Lesser General Public License as published
8 | by the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 | ABY is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | GNU Lesser General Public License for more details.
14 | You should have received a copy of the GNU Lesser General Public License
15 | along with this program. If not, see .
16 | \brief Implementation of truncated SelectionBlock
17 | */
18 | #include "t_SelectionBlock.h"
19 | #include "permutation_network.h"
20 |
21 | Truncated_PN::WaksmanPermutation::~WaksmanPermutation() {
22 | // TODO Auto-generated destructor stub
23 | }
24 |
25 | void Truncated_PN::WaksmanPermutation::program_rec(uint32_t out, uint32_t block, uint32_t* p1, uint32_t* p2, uint32_t* rows, uint32_t* cols) {
26 | uint32_t in = cols[out];
27 |
28 | if ((out^1) < m_nNumOutputs && cols[out^1] != -1 && out/2 < s2.size()) {
29 | m_PM->setSwitchProgram(s2[out/2],(block==0)!=(out%2==0));
30 | Todo->remove(out/2);
31 | }
32 |
33 | if (block == 1) {
34 | p2[out/2] = in / 2;
35 | if(in / 2 < s1.size()) {
36 | m_PM->setSwitchProgram(s1[in/2], in % 2 == 0);
37 | }
38 | } else { // block==0
39 | p1[out / 2] = in / 2;
40 | if (in / 2 < s1.size()) {
41 | m_PM->setSwitchProgram(s1[in/2], in % 2 == 1);
42 | }
43 | }
44 | cols[out] = -1;
45 | rows[in] = -1;
46 |
47 | uint32_t newin = in^1;
48 | if (newin < m_nNumInputs && rows[newin]!=-1) {
49 | uint32_t newout = rows[newin];
50 | rows[newin] = -1;
51 | program_rec(newout,block^1,p1,p2,rows,cols);
52 | }
53 |
54 | if ((out^1) < m_nNumOutputs && cols[out^1] != -1 && out/2 < s2.size()) {
55 | program_rec(out^1,block^1,p1,p2,rows,cols);
56 | }
57 | }
58 |
59 | void Truncated_PN::WaksmanPermutation::program(uint32_t* perm) {
60 | if (m_nNumOutputs == 1){
61 | if(m_nNumInputs == 1) {return;}
62 | m_vYgatesProgram.resize(m_nNumInputs - 1);
63 | for(int i=0; i < m_nNumInputs-1; i++) {
64 | if(i + 1 == perm[0]) m_vYgatesProgram[i] = true;
65 | else m_vYgatesProgram[i] = false;
66 | }
67 | return;
68 | }
69 |
70 | uint32_t* cols = perm;
71 |
72 | uint32_t* rows = (uint32_t*) malloc(sizeof(uint32_t) * m_nNumInputs); //new uint32_t[u];
73 | for (uint32_t i = 0; i < m_nNumInputs; i++) rows[i] = -1;
74 | for (uint32_t i = 0; i < m_nNumOutputs; i++) {
75 | uint32_t x = perm[i];
76 | assert(x>=0 && xnext(); n != -1; n = Todo->next()) {
97 | program_rec(2 * n, 0, p1, p2, rows, cols);
98 | }
99 |
100 | // program sub-blocks
101 | b1->program(p1);
102 | b2->program(p2);
103 | }
104 |
105 | Truncated_PN::WaksmanPermutation::WaksmanPermutation(uint32_t numinputs, uint32_t numoutputs, Truncated_PN* pm) {
106 | assert(numoutputs <= numinputs);
107 | m_nNumInputs = numinputs;
108 | m_nNumOutputs = numoutputs;
109 | m_PM = pm;
110 |
111 | if (numoutputs != 1) {
112 | // first row X
113 | s1.resize(m_nNumInputs / 2);
114 |
115 | for (uint32_t i = 0; i < m_nNumInputs / 2; i++)
116 | s1[i] = pm->nextGate();
117 |
118 | //assign wires to X gates and permute them
119 |
120 | // B1PermutationNetwork
121 | b1 = new WaksmanPermutation(numinputs / 2, numoutputs / 2, pm);
122 |
123 | // B2
124 | b2 = new WaksmanPermutation(numinputs - (numinputs / 2), numoutputs - (numoutputs / 2), pm);
125 |
126 | // last row X
127 | m_nSizeB2 = (numinputs % 2 == 0 && numoutputs % 2 ==0) ? numoutputs / 2 - 1 : numoutputs / 2;
128 | s2.resize(m_nSizeB2);
129 | for (uint32_t i = 0; i < m_nSizeB2; i++)
130 | s2[i] = pm->nextGate();
131 |
132 | }
133 |
134 | }
135 |
136 | vector > Truncated_PN::WaksmanPermutation::generateCircuit(vector > inputs, vector > outputs) {
137 | uint32_t rep = inputs[0].size();
138 | if (outputs == NON_INIT_DEF_OUTPUT) {
139 | outputs.resize(m_nNumOutputs);
140 | for (uint32_t i = 0; i < m_nNumOutputs; i++) {
141 | outputs[i].resize(rep);
142 | }
143 | }
144 | if (m_nNumOutputs == 1) {
145 | if(m_nNumInputs == 1) {
146 | for (uint32_t j = 0; j < rep; j++){
147 | outputs[0][j] = inputs[0][j];
148 | return outputs;
149 | }
150 | }
151 | vector > outtmp(1);
152 | outtmp[0] = m_PM->PutCondYGate(inputs[0], inputs[1],(m_PM->m_cBoolCirc->PutSIMDINGate(1,(uint32_t) m_vYgatesProgram[0],1,SERVER))->get_wire_id(0));
153 | for(uint32_t i = 1;i < m_nNumInputs - 1; i++) {
154 | outtmp[0] = m_PM->PutCondYGate(outtmp[0], inputs[i+1], (m_PM->m_cBoolCirc->PutSIMDINGate(1,(uint32_t) m_vYgatesProgram[i],1,SERVER))->get_wire_id(0));
155 | }
156 | outputs[0] = outtmp [0];
157 | return outputs;
158 | }
159 |
160 | uint32_t sizeB2 = m_nNumInputs - (m_nNumInputs / 2);
161 | vector > in_p1(m_nNumInputs / 2);
162 | vector > in_p2(sizeB2);
163 |
164 | // first row X
165 | vector > outtmp(2);
166 | for (uint32_t i = 0; i < s1.size(); i++) {
167 | in_p1[i].resize(rep);
168 | in_p2[i].resize(rep);
169 | //in_p1[i] = inputs[2 * i + m_PM->m_vSwitchGateProgram[s1[i]]];
170 | //in_p2[i] = inputs[2 * i + !(m_PM->m_vSwitchGateProgram[s1[i]])];
171 | outtmp = m_PM->PutCondSwapGate(inputs[2 * i], inputs[2 * i + 1], m_PM->m_vSwapGates[s1[i]]);
172 | for (uint32_t j = 0; j < rep; j++) {
173 | in_p1[i][j] = outtmp[0][j];
174 | in_p2[i][j] = outtmp[1][j];
175 | }
176 |
177 | }
178 |
179 | if (m_nNumInputs % 2 == 1) {
180 | in_p2[sizeB2 - 1].resize(rep);
181 | for (uint32_t i = 0; i < rep; i++)
182 | in_p2[sizeB2 - 1][i] = inputs[m_nNumInputs - 1][i];
183 | }
184 |
185 | vector > out_p1 = b1->generateCircuit(in_p1, NON_INIT_DEF_OUTPUT);
186 | vector > out_p2 = b2->generateCircuit(in_p2, NON_INIT_DEF_OUTPUT);
187 |
188 | // last row X
189 | for (uint32_t i = 0; i < s2.size(); i++) {
190 |
191 | outtmp = m_PM->PutCondSwapGate(out_p1[i], out_p2[i], m_PM->m_vSwapGates[s2[i]]);
192 | for (uint32_t j = 0; j < rep; j++) {
193 | outputs[2 * i][j] = outtmp[0][j];
194 | outputs[2 * i + 1][j] = outtmp[1][j];
195 | }
196 |
197 |
198 | }
199 |
200 | if(m_nNumOutputs % 2 == 1) {
201 | for (uint32_t i = 0; i < rep; i++){
202 | outputs[m_nNumOutputs - 1][i] = out_p2[out_p2.size()-1][i];
203 | }
204 | } else if (m_nNumInputs % 2 == 0){
205 | for (uint32_t i = 0; i < rep; i++){
206 |
207 | outputs[m_nNumOutputs - 1][i] = out_p2[out_p2.size()-1][i];
208 | outputs[m_nNumOutputs - 2][i] = out_p1[out_p1.size()-1][i];
209 | }
210 | }
211 |
212 | return outputs;
213 | }
214 |
215 | void t_SelectionBlock::SelectionBlockProgram(uint32_t *p){
216 | uint32_t *prog1, *programm;
217 |
218 | if(m_nNumInputs==1) return;
219 |
220 | // count number of occurrences
221 | vector c;
222 | c.resize(m_nNumInputs);
223 | for(uint32_t i=0; i=0 && p[i] upos, dummy;
232 | upos.resize(m_nNumInputs);
233 | dummy.resize(m_nNumInputs); // list of dummy outputs
234 |
235 | for(uint32_t i=0; i0) {
237 | prog1[sum] = i;
238 | upos[i] = sum;
239 | if(sum>0) {
240 | setYProgram(sum-1, true);
241 | //m_vYgatesProgram[sum-1] = true;
242 | }
243 | for(uint32_t j = sum + 1; j < sum+c[i]; j++) {
244 | setYProgram(j-1, false);
245 | //m_vYgatesProgram[j-1] = false;
246 | prog1[j] = -1;
247 | }
248 | sum+=c[i];
249 | }
250 | else{
251 | dummy[ndummys++] = i;
252 | }
253 | }
254 |
255 | // program dummys
256 | uint32_t nextdummy=0;
257 | for(uint32_t i=0; i < m_nNumOutputs; i++) {
258 | if(prog1[i]==-1) {
259 | prog1[i]=dummy[nextdummy++];
260 | }
261 | }
262 | m_Pblock1->ProgramPermutationNetwork(prog1);
263 |
264 | // program b2
265 | uint32_t* prog2 = (uint32_t*) malloc(sizeof(uint32_t) * m_nNumOutputs);
266 | for(uint32_t i=0; i < m_nNumOutputs; i++) {
267 | prog2[i]=upos[p[i]]++;
268 | }
269 | m_Pblock2->ProgramPermutationNetwork(prog2);
270 | }
271 |
272 | vector > t_SelectionBlock::buildSelectionBlockCircuit(vector >& inputs){
273 | uint32_t rep = inputs[0].size();
274 | vector > out_p1,out_g, outputs;
275 |
276 | out_p1 = m_Pblock1->buildPermutationCircuit(inputs);
277 | out_g.resize(m_nNumOutputs);
278 | out_g[0]=out_p1[0];
279 | for(uint32_t i=1; ibuildPermutationCircuit(out_g);
283 | }
284 |
--------------------------------------------------------------------------------
/ABY_example/dectree/common/crypto_party/paillier.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | libpaillier - A library implementing the Paillier cryptosystem.
3 |
4 | Copyright (C) 2006 SRI International.
5 |
6 | This program is free software; you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation; either version 2 of the License, or
9 | (at your option) any later version.
10 |
11 | This program is distributed in the hope that it will be useful, but
12 | WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | General Public License for more details.
15 | */
16 |
17 | #include
18 | #include
19 | #include
20 | #include
21 | #include "paillier.h"
22 |
23 | void
24 | init_rand( gmp_randstate_t rand, paillier_get_rand_t get_rand, int bytes )
25 | {
26 | void* buf;
27 | mpz_t s;
28 |
29 | buf = malloc(bytes);
30 | get_rand(buf, bytes);
31 |
32 | gmp_randinit_default(rand);
33 | mpz_init(s);
34 | mpz_import(s, bytes, 1, 1, 0, 0, buf);
35 | gmp_randseed(rand, s);
36 | mpz_clear(s);
37 |
38 | free(buf);
39 | }
40 |
41 | void
42 | complete_pubkey( paillier_pubkey_t* pub )
43 | {
44 | mpz_mul(pub->n_squared, pub->n, pub->n);
45 | mpz_add_ui(pub->n_plusone, pub->n, 1);
46 | }
47 |
48 | void
49 | complete_prvkey( paillier_prvkey_t* prv, paillier_pubkey_t* pub )
50 | {
51 | mpz_powm(prv->x, pub->n_plusone, prv->lambda, pub->n_squared);
52 | mpz_sub_ui(prv->x, prv->x, 1);
53 | mpz_div(prv->x, prv->x, pub->n);
54 | mpz_invert(prv->x, prv->x, pub->n);
55 | }
56 |
57 | void
58 | paillier_keygen( int modulusbits,
59 | paillier_pubkey_t** pub,
60 | paillier_prvkey_t** prv,
61 | paillier_get_rand_t get_rand )
62 | {
63 | mpz_t p;
64 | mpz_t q;
65 | gmp_randstate_t rand;
66 |
67 | /* allocate the new key structures */
68 |
69 | *pub = (paillier_pubkey_t*) malloc(sizeof(paillier_pubkey_t));
70 | *prv = (paillier_prvkey_t*) malloc(sizeof(paillier_prvkey_t));
71 |
72 | /* initialize our integers */
73 |
74 | mpz_init((*pub)->n);
75 | mpz_init((*pub)->n_squared);
76 | mpz_init((*pub)->n_plusone);
77 | mpz_init((*prv)->lambda);
78 | mpz_init((*prv)->x);
79 | mpz_init(p);
80 | mpz_init(q);
81 |
82 | /* pick random (modulusbits/2)-bit primes p and q */
83 |
84 | init_rand(rand, get_rand, modulusbits / 8 + 1);
85 | do
86 | {
87 | do
88 | mpz_urandomb(p, rand, modulusbits / 2);
89 | while( !mpz_probab_prime_p(p, 10) );
90 |
91 | do
92 | mpz_urandomb(q, rand, modulusbits / 2);
93 | while( !mpz_probab_prime_p(q, 10) );
94 |
95 | /* compute the public modulus n = p q */
96 |
97 | mpz_mul((*pub)->n, p, q);
98 | } while( !mpz_tstbit((*pub)->n, modulusbits - 1) );
99 | complete_pubkey(*pub);
100 | (*pub)->bits = modulusbits;
101 |
102 | /* compute the private key lambda = lcm(p-1,q-1) */
103 |
104 | mpz_sub_ui(p, p, 1);
105 | mpz_sub_ui(q, q, 1);
106 | mpz_lcm((*prv)->lambda, p, q);
107 | complete_prvkey(*prv, *pub);
108 |
109 | /* clear temporary integers and randstate */
110 |
111 | mpz_clear(p);
112 | mpz_clear(q);
113 | gmp_randclear(rand);
114 | }
115 |
116 | paillier_ciphertext_t*
117 | paillier_enc( paillier_ciphertext_t* res,
118 | paillier_pubkey_t* pub,
119 | paillier_plaintext_t* pt,
120 | paillier_get_rand_t get_rand )
121 | {
122 | mpz_t r;
123 | gmp_randstate_t rand;
124 | mpz_t x;
125 |
126 | /* pick random blinding factor */
127 |
128 | mpz_init(r);
129 | gmp_randinit_mt(rand);
130 | do
131 | mpz_urandomb(r, rand, pub->bits);
132 | while( mpz_cmp(r, pub->n) >= 0 );
133 |
134 | /* compute ciphertext */
135 |
136 | if( !res )
137 | {
138 | res = (paillier_ciphertext_t*) malloc(sizeof(paillier_ciphertext_t));
139 | mpz_init(res->c);
140 | }
141 |
142 | mpz_init(x);
143 | mpz_powm(res->c, pub->n_plusone, pt->m, pub->n_squared);
144 | mpz_powm(x, r, pub->n, pub->n_squared);
145 |
146 | mpz_mul(res->c, res->c, x);
147 | mpz_mod(res->c, res->c, pub->n_squared);
148 |
149 | mpz_clear(x);
150 | mpz_clear(r);
151 | gmp_randclear(rand);
152 |
153 | return res;
154 | }
155 |
156 | paillier_plaintext_t*
157 | paillier_dec( paillier_plaintext_t* res,
158 | paillier_pubkey_t* pub,
159 | paillier_prvkey_t* prv,
160 | paillier_ciphertext_t* ct )
161 | {
162 | if( !res )
163 | {
164 | res = (paillier_plaintext_t*) malloc(sizeof(paillier_plaintext_t));
165 | mpz_init(res->m);
166 | }
167 |
168 | mpz_powm(res->m, ct->c, prv->lambda, pub->n_squared);
169 | mpz_sub_ui(res->m, res->m, 1);
170 | mpz_div(res->m, res->m, pub->n);
171 | mpz_mul(res->m, res->m, prv->x);
172 | mpz_mod(res->m, res->m, pub->n);
173 |
174 | return res;
175 | }
176 |
177 | void
178 | paillier_mul( paillier_pubkey_t* pub,
179 | paillier_ciphertext_t* res,
180 | paillier_ciphertext_t* ct0,
181 | paillier_ciphertext_t* ct1 )
182 | {
183 | mpz_mul(res->c, ct0->c, ct1->c);
184 | mpz_mod(res->c, res->c, pub->n_squared);
185 | }
186 |
187 | void
188 | paillier_exp( paillier_pubkey_t* pub,
189 | paillier_ciphertext_t* res,
190 | paillier_ciphertext_t* ct,
191 | paillier_plaintext_t* pt )
192 | {
193 | mpz_powm(res->c, ct->c, pt->m, pub->n_squared);
194 | }
195 |
196 | paillier_plaintext_t*
197 | paillier_plaintext_from_ui( unsigned long int x )
198 | {
199 | paillier_plaintext_t* pt;
200 |
201 | pt = (paillier_plaintext_t*) malloc(sizeof(paillier_plaintext_t));
202 | mpz_init_set_ui(pt->m, x);
203 |
204 | return pt;
205 | }
206 |
207 | paillier_plaintext_t*
208 | paillier_plaintext_from_bytes( void* m, int len )
209 | {
210 | paillier_plaintext_t* pt;
211 |
212 | pt = (paillier_plaintext_t*) malloc(sizeof(paillier_plaintext_t));
213 | mpz_init(pt->m);
214 | mpz_import(pt->m, len, 1, 1, 0, 0, m);
215 |
216 | return pt;
217 | }
218 |
219 | void*
220 | paillier_plaintext_to_bytes( int len, paillier_plaintext_t* pt )
221 | {
222 | void* buf0;
223 | void* buf1;
224 | size_t written;
225 |
226 | buf0 = mpz_export(0, &written, 1, 1, 0, 0, pt->m);
227 |
228 | if( written == len )
229 | return buf0;
230 |
231 | buf1 = malloc(len);
232 | memset(buf1, 0, len);
233 |
234 | if( written == 0 )
235 | /* no need to copy anything, pt->m = 0 and buf0 was not allocated */
236 | return buf1;
237 | else if( written < len )
238 | /* pad with leading zeros */
239 | memcpy(buf1 + (len - written), buf0, written);
240 | else
241 | /* truncate leading garbage */
242 | memcpy(buf1, buf0 + (written - len), len);
243 |
244 | free(buf0);
245 |
246 | return buf1;
247 | }
248 |
249 | paillier_plaintext_t*
250 | paillier_plaintext_from_str( char* str )
251 | {
252 | return paillier_plaintext_from_bytes(str, strlen(str));
253 | }
254 |
255 | char*
256 | paillier_plaintext_to_str( paillier_plaintext_t* pt )
257 | {
258 | char* buf;
259 | size_t len;
260 |
261 | buf = (char*) mpz_export(0, &len, 1, 1, 0, 0, pt->m);
262 | buf = (char*) realloc(buf, len + 1);
263 | buf[len] = 0;
264 |
265 | return buf;
266 | }
267 |
268 | paillier_ciphertext_t*
269 | paillier_ciphertext_from_bytes( void* c, int len )
270 | {
271 | paillier_ciphertext_t* ct;
272 |
273 | ct = (paillier_ciphertext_t*) malloc(sizeof(paillier_ciphertext_t));
274 | mpz_init(ct->c);
275 | mpz_import(ct->c, len, 1, 1, 0, 0, c);
276 |
277 | return ct;
278 | }
279 |
280 | void*
281 | paillier_ciphertext_to_bytes( int len, paillier_ciphertext_t* ct )
282 | {
283 | void* buf;
284 | int cur_len;
285 |
286 | cur_len = mpz_sizeinbase(ct->c, 2);
287 | cur_len = PAILLIER_BITS_TO_BYTES(cur_len);
288 | buf = malloc(len);
289 | memset(buf, 0, len);
290 | mpz_export(buf + (len - cur_len), 0, 1, 1, 0, 0, ct->c);
291 |
292 | return buf;
293 | }
294 |
295 | char*
296 | paillier_pubkey_to_hex( paillier_pubkey_t* pub )
297 | {
298 | return mpz_get_str(0, 16, pub->n);
299 | }
300 |
301 | char*
302 | paillier_prvkey_to_hex( paillier_prvkey_t* prv )
303 | {
304 | return mpz_get_str(0, 16, prv->lambda);
305 | }
306 |
307 | paillier_pubkey_t*
308 | paillier_pubkey_from_hex( char* str )
309 | {
310 | paillier_pubkey_t* pub;
311 |
312 | pub = (paillier_pubkey_t*) malloc(sizeof(paillier_pubkey_t));
313 | mpz_init_set_str(pub->n, str, 16);
314 | pub->bits = mpz_sizeinbase(pub->n, 2);
315 | mpz_init(pub->n_squared);
316 | mpz_init(pub->n_plusone);
317 | complete_pubkey(pub);
318 |
319 | return pub;
320 | }
321 |
322 | paillier_prvkey_t*
323 | paillier_prvkey_from_hex( char* str, paillier_pubkey_t* pub )
324 | {
325 | paillier_prvkey_t* prv;
326 |
327 | prv = (paillier_prvkey_t*) malloc(sizeof(paillier_prvkey_t));
328 | mpz_init_set_str(prv->lambda, str, 16);
329 | mpz_init(prv->x);
330 | complete_prvkey(prv, pub);
331 |
332 | return prv;
333 | }
334 |
335 | void
336 | paillier_freepubkey( paillier_pubkey_t* pub )
337 | {
338 | mpz_clear(pub->n);
339 | mpz_clear(pub->n_squared);
340 | mpz_clear(pub->n_plusone);
341 | free(pub);
342 | }
343 |
344 | void
345 | paillier_freeprvkey( paillier_prvkey_t* prv )
346 | {
347 | mpz_clear(prv->lambda);
348 | mpz_clear(prv->x);
349 | free(prv);
350 | }
351 |
352 | void
353 | paillier_freeplaintext( paillier_plaintext_t* pt )
354 | {
355 | mpz_clear(pt->m);
356 | // free(pt);
357 | }
358 |
359 | void
360 | paillier_freeciphertext( paillier_ciphertext_t* ct )
361 | {
362 | mpz_clear(ct->c);
363 | // free(ct);
364 | }
365 |
366 | void
367 | paillier_get_rand_file( void* buf, int len, char* file )
368 | {
369 | FILE* fp;
370 | void* p;
371 |
372 | fp = fopen(file, "r");
373 |
374 | p = buf;
375 | while( len )
376 | {
377 | size_t s;
378 | s = fread(p, 1, len, fp);
379 | p += s;
380 | len -= s;
381 | }
382 |
383 | fclose(fp);
384 | }
385 |
386 | void
387 | paillier_get_rand_devrandom( void* buf, int len )
388 | {
389 | paillier_get_rand_file(buf, len, "/dev/random");
390 | }
391 |
392 | void
393 | paillier_get_rand_devurandom( void* buf, int len )
394 | {
395 | paillier_get_rand_file(buf, len, "/dev/urandom");
396 | }
397 |
398 | paillier_ciphertext_t*
399 | paillier_create_enc_zero()
400 | {
401 | paillier_ciphertext_t* ct;
402 |
403 | /* make a NON-RERANDOMIZED encryption of zero for the purposes of
404 | homomorphic computation */
405 |
406 | /* note that this is just the number 1 */
407 |
408 | ct = (paillier_ciphertext_t*) malloc(sizeof(paillier_ciphertext_t));
409 | mpz_init_set_ui(ct->c, 1);
410 |
411 | return ct;
412 | }
413 |
--------------------------------------------------------------------------------
/ABY_example/dectree/common/crypto_party/paillier.h:
--------------------------------------------------------------------------------
1 | /*
2 | libpaillier - A library implementing the Paillier cryptosystem.
3 |
4 | Copyright (C) 2006 SRI International.
5 |
6 | This program is free software; you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation; either version 2 of the License, or
9 | (at your option) any later version.
10 |
11 | This program is distributed in the hope that it will be useful, but
12 | WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | General Public License for more details.
15 | */
16 |
17 | /*
18 | Include gmp.h before including this file.
19 | */
20 |
21 | /*
22 | IMPORTANT SECURITY NOTES:
23 |
24 | On paillier_keygen and strong primes:
25 |
26 | When selecting a modulus n = p q, we do not bother ensuring that p
27 | and q are strong primes. While this was at one point considered
28 | important (e.g., it is required by ANSI X9.31), modern factoring
29 | algorithms make any advantage of strong primes doubtful [1]. RSA
30 | Laboratories no longer recommends the practice [2].
31 |
32 | On memory handling:
33 |
34 | At no point is any special effort made to securely "shred" sensitive
35 | memory or prevent it from being paged out to disk. This means that
36 | it is important that functions dealing with private keys and
37 | plaintexts (e.g., paillier_keygen and paillier_enc) only be run on
38 | trusted machines. The resulting ciphertexts and public keys,
39 | however, may of course be handled in an untrusted manner.
40 |
41 | [1] Are "strong" primes needed for RSA? Ron Rivest and Robert
42 | Silverman. Cryptology ePrint Archive, Report 2001/007, 2001.
43 |
44 | [2] RSA Laboratories' Frequently Asked Questions About Today's
45 | Cryptography, Version 4.1, Section 3.1.4.
46 | */
47 |
48 | /******
49 | TYPES
50 | *******/
51 |
52 | /*
53 | This represents a Paillier public key, which is basically just the
54 | modulus n. The other values should be considered private.
55 | */
56 | typedef struct
57 | {
58 | int bits; /* e.g., 1024 */
59 | mpz_t n; /* public modulus n = p q */
60 | mpz_t n_squared; /* cached to avoid recomputing */
61 | mpz_t n_plusone; /* cached to avoid recomputing */
62 | } paillier_pubkey_t;
63 |
64 | /*
65 | This represents a Paillier private key; it needs to be used with a
66 | paillier_pubkey_t to be meaningful. It only includes the Carmichael
67 | function (lambda) of the modulus. The other value is kept for
68 | efficiency and should be considered private.
69 | */
70 | typedef struct
71 | {
72 | mpz_t lambda; /* lambda(n), i.e., lcm(p-1,q-1) */
73 | mpz_t x; /* cached to avoid recomputing */
74 | } paillier_prvkey_t;
75 |
76 | /*
77 | This is a (semantic rather than structural) type for plaintexts.
78 | These can be converted to and from ASCII strings and byte arrays.
79 | */
80 | typedef struct
81 | {
82 | mpz_t m;
83 | } paillier_plaintext_t;
84 |
85 | /*
86 | This is a (semantic rather than structural) type for ciphertexts.
87 | These can also be converted to or from byte arrays (for example in
88 | order to store them in a file).
89 | */
90 | typedef struct
91 | {
92 | mpz_t c;
93 | } paillier_ciphertext_t;
94 |
95 | /*
96 | This is the type of the callback functions used to obtain the
97 | randomness needed by the probabilistic algorithms. The functions
98 | paillier_get_rand_devrandom and paillier_get_rand_devurandom
99 | (documented later) may be passed to any library function requiring a
100 | paillier_get_rand_t, or you may implement your own. If you implement
101 | your own such function, it should fill in "len" random bytes in the
102 | array "buf".
103 | */
104 | typedef void (*paillier_get_rand_t) ( void* buf, int len );
105 |
106 | /*****************
107 | BASIC OPERATIONS
108 | *****************/
109 |
110 | /*
111 | Generate a keypair of length modulusbits using randomness from the
112 | provided get_rand function. Space will be allocated for each of the
113 | keys, and the given pointers will be set to point to the new
114 | paillier_pubkey_t and paillier_prvkey_t structures. The functions
115 | paillier_get_rand_devrandom and paillier_get_rand_devurandom may be
116 | passed as the final argument.
117 | */
118 | void paillier_keygen( int modulusbits,
119 | paillier_pubkey_t** pub,
120 | paillier_prvkey_t** prv,
121 | paillier_get_rand_t get_rand );
122 |
123 | /*
124 | Encrypt the given plaintext with the given public key using
125 | randomness from get_rand for blinding. If res is not null, its
126 | contents will be overwritten with the result. Otherwise, a new
127 | paillier_ciphertext_t will be allocated and returned.
128 | */
129 | paillier_ciphertext_t* paillier_enc( paillier_ciphertext_t* res,
130 | paillier_pubkey_t* pub,
131 | paillier_plaintext_t* pt,
132 | paillier_get_rand_t get_rand );
133 |
134 | /*
135 | Decrypt the given ciphertext with the given key pair. If res is not
136 | null, its contents will be overwritten with the result. Otherwise, a
137 | new paillier_plaintext_t will be allocated and returned.
138 | */
139 | paillier_plaintext_t* paillier_dec( paillier_plaintext_t* res,
140 | paillier_pubkey_t* pub,
141 | paillier_prvkey_t* prv,
142 | paillier_ciphertext_t* ct );
143 |
144 | /*****************************
145 | USE OF ADDITIVE HOMOMORPHISM
146 | *****************************/
147 |
148 | /*
149 | Multiply the two ciphertexts assuming the modulus in the given
150 | public key and store the result in the contents of res, which is
151 | assumed to have already been allocated.
152 | */
153 | void paillier_mul( paillier_pubkey_t* pub,
154 | paillier_ciphertext_t* res,
155 | paillier_ciphertext_t* ct0,
156 | paillier_ciphertext_t* ct1 );
157 |
158 | /*
159 | Raise the given ciphertext to power pt and store the result in res,
160 | which is assumed to be already allocated. If ct is an encryption of
161 | x, then res will become an encryption of x * pt mod n, where n is
162 | the modulus in pub.
163 | */
164 | void paillier_exp( paillier_pubkey_t* pub,
165 | paillier_ciphertext_t* res,
166 | paillier_ciphertext_t* ct,
167 | paillier_plaintext_t* pt );
168 |
169 | /****************************
170 | PLAINTEXT IMPORT AND EXPORT
171 | ****************************/
172 |
173 | /*
174 | Allocate and initialize a paillier_plaintext_t from an unsigned long
175 | integer, an array of bytes, or a null terminated string.
176 | */
177 | paillier_plaintext_t* paillier_plaintext_from_ui( unsigned long int x );
178 | paillier_plaintext_t* paillier_plaintext_from_bytes( void* m, int len );
179 | paillier_plaintext_t* paillier_plaintext_from_str( char* str );
180 |
181 | /*
182 | Export a paillier_plaintext_t as a null terminated string or an
183 | array of bytes. In either case the result is allocated for the
184 | caller and the original paillier_plaintext_t is unchanged.
185 | */
186 | char* paillier_plaintext_to_str( paillier_plaintext_t* pt );
187 | void* paillier_plaintext_to_bytes( int len, paillier_plaintext_t* pt );
188 |
189 | /*****************************
190 | CIPHERTEXT IMPORT AND EXPORT
191 | *****************************/
192 |
193 | /*
194 | Import or export a paillier_ciphertext_t from or to an array of
195 | bytes. These behave like the corresponding functions for
196 | paillier_plaintext_t's.
197 | */
198 | paillier_ciphertext_t* paillier_ciphertext_from_bytes( void* c, int len );
199 | void* paillier_ciphertext_to_bytes( int len, paillier_ciphertext_t* ct );
200 |
201 | /**********************
202 | KEY IMPORT AND EXPORT
203 | **********************/
204 |
205 | /*
206 | Import or export public and private keys from or to hexadecimal,
207 | ASCII strings, which are suitable for I/O. Note that the
208 | corresponding public key is necessary to initialize a private key
209 | from a hex string. In all cases, the returned value is allocated for
210 | the caller and the values passed are unchanged.
211 | */
212 | char* paillier_pubkey_to_hex( paillier_pubkey_t* pub );
213 | char* paillier_prvkey_to_hex( paillier_prvkey_t* prv );
214 | paillier_pubkey_t* paillier_pubkey_from_hex( char* str );
215 | paillier_prvkey_t* paillier_prvkey_from_hex( char* str,
216 | paillier_pubkey_t* pub );
217 |
218 | /********
219 | CLEANUP
220 | ********/
221 |
222 | /*
223 | These free the structures allocated and returned by various
224 | functions within library and should be used when the structures are
225 | no longer needed.
226 | */
227 | void paillier_freepubkey( paillier_pubkey_t* pub );
228 | void paillier_freeprvkey( paillier_prvkey_t* prv );
229 | void paillier_freeplaintext( paillier_plaintext_t* pt );
230 | void paillier_freeciphertext( paillier_ciphertext_t* ct );
231 |
232 | /***********
233 | MISC STUFF
234 | ***********/
235 |
236 | /*
237 | These functions may be passed to the paillier_keygen and
238 | paillier_enc functions to provide a source of random numbers. The
239 | first reads bytes from /dev/random. On Linux, this device
240 | exclusively returns entropy gathered from environmental noise and
241 | therefore frequently blocks when not enough is available. The second
242 | returns bytes from /dev/urandom. On Linux, this device also returns
243 | environmental noise, but augments it with a pseudo-random number
244 | generator when not enough is available. The latter is probably the
245 | better choice unless you have a specific reason to believe it is
246 | insufficient.
247 | */
248 | void paillier_get_rand_devrandom( void* buf, int len );
249 | void paillier_get_rand_devurandom( void* buf, int len );
250 |
251 | /*
252 | This function just allocates and returns a paillier_ciphertext_t
253 | which is a valid, _unblinded_ encryption of zero (which may actually
254 | be done without knowledge of a public key). Note that this
255 | encryption is UNBLINDED, so don't use it unless you want anyone who
256 | sees it to know it is an encryption of zero. This function is
257 | sometimes handy to get some homomorphic computations started or
258 | quickly allocate a paillier_ciphertext_t in which to place some
259 | later result.
260 | */
261 | paillier_ciphertext_t* paillier_create_enc_zero();
262 |
263 | /*
264 | Just a utility used internally when we need round a number of bits
265 | up the number of bytes necessary to hold them.
266 | */
267 |
268 | void complete_pubkey( paillier_pubkey_t* pub );
269 |
270 |
271 | #define PAILLIER_BITS_TO_BYTES(n) ((n) % 8 ? (n) / 8 + 1 : (n) / 8)
272 |
--------------------------------------------------------------------------------
/ABY_example/dectree/common/dectree.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | \file dectree.cpp
3 | \author kiss@encrypto.cs.tu-darmstadt.de
4 | \copyright ABY - A Framework for Efficient Mixed-protocol Secure Two-party Computation
5 | Copyright (C) 2019 Engineering Cryptographic Protocols Group, TU Darmstadt
6 | This program is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU Lesser General Public License as published
8 | by the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 | ABY is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | GNU Lesser General Public License for more details.
14 | You should have received a copy of the GNU Lesser General Public License
15 | along with this program. If not, see .
16 | \brief Decision tree implementation
17 | */
18 |
19 | #include "dectree.h"
20 | /**
21 | * Node constructor that takes its number num, by default it has no children
22 | * and parents, is not colored.
23 | * @param num the number that identifies the node
24 | */
25 | DecTree::Node::Node()
26 | : left(0)
27 | , right(0)
28 | , parent(0)
29 | , level(0)
30 | , leaf(false)
31 | , threshold(0)
32 | , attribute_index(0)
33 | , classification(0)
34 | {}
35 |
36 | DecTree::Node::Node(const Node& other){
37 | left = new Node(*(other.left));
38 | right = new Node(*(other.right));
39 | parent = new Node(*(other.parent));
40 | level = other.level;
41 | leaf = other.leaf;
42 | threshold = other.threshold;
43 | attribute_index = other.attribute_index;
44 | classification = other.classification;
45 | }
46 |
47 | /**
48 | * Gamma2 constructor that creates a Gamma2 graph with specified number of Nodes
49 | * @param num the number specifying the number of Nodes
50 | */
51 | DecTree::DecTree()
52 | {
53 | num_attributes = 0;
54 | num_dec_nodes = 0;
55 | depth = 0;
56 | num_of_leaves = 0;
57 | dummy_non_full = 0;
58 | }
59 |
60 | DecTree::DecTree(const DecTree& other){
61 | node_vec = other.node_vec;
62 | decnode_vec = other.decnode_vec;
63 | attributes = other.attributes;
64 | thresholds = other.thresholds;
65 | num_attributes = other.num_attributes;
66 | num_dec_nodes = other.num_dec_nodes;
67 | depth = other.depth;
68 | num_of_leaves = other.num_of_leaves;
69 | dummy_non_full = other.dummy_non_full;
70 | }
71 |
72 | /**
73 | * Add a node
74 | * @param node the Node to be added to the tree
75 | */
76 | void DecTree::add_node(DecTree::Node* node){
77 | node_vec.push_back(node);
78 | }
79 |
80 | /**
81 | * Add a decision node
82 | * @param node the Node to be added to the tree
83 | */
84 | void DecTree::add_decnode(DecTree::Node* node){
85 | decnode_vec.push_back(node);
86 | }
87 |
88 | /**
89 | * Add an edge between two nodes
90 | * @param n1 the starting Node of the edge
91 | * @param n2 the ending Node of the edge
92 | */
93 | void DecTree::add_edge(DecTree::Node* n1, DecTree::Node* n2){
94 | n2->parent = n1;
95 | n2->level = n1->level + 1;
96 | if(n1->left == NULL){
97 | n1->left = n2;
98 | }
99 | else{
100 | n1->right = n2;
101 | }
102 | }
103 |
104 | /**
105 | * Takes a string in the Format "i i i ..." separated by ' '
106 | * @param str the string to tokenize
107 | * @param tokens the result vector of wire id
108 | */
109 | void tokenize(const std::string& str, std::vector& tokens) {
110 | tokens.clear();
111 | std::size_t prev = 0, pos;
112 | while ((pos = str.find_first_of(" []", prev)) != std::string::npos)
113 | {
114 | if (pos > prev)
115 | tokens.push_back(str.substr(prev, pos-prev));
116 | prev = pos+1;
117 | }
118 | if (prev < str.length())
119 | tokens.push_back(str.substr(prev, std::string::npos));
120 | }
121 |
122 | /**
123 | * Erase First Occurrence of given substring from main string.
124 | */
125 | void eraseSubStr(std::string & mainStr, const std::string & toErase)
126 | {
127 | // Search for the substring in string
128 | size_t pos = mainStr.find(toErase);
129 |
130 | if (pos != std::string::npos)
131 | {
132 | // If found then erase it from string
133 | mainStr.erase(pos, toErase.length());
134 | }
135 | }
136 |
137 | class SearchFunction {
138 | public:
139 | SearchFunction(uint32_t item): item_(item) {}
140 | bool operator()(uint64_t const & ref) {
141 | return ref == item_;
142 | }
143 | private:
144 | uint32_t item_;
145 | };
146 |
147 | //root node will be in decnode_vec[0] and node_vec[0]
148 | void DecTree::read_from_file(string string_file){
149 | const char* filename = string_file.c_str();
150 | ifstream file;
151 | file.open(filename);
152 | cout << "Reading from " << filename << endl;
153 |
154 | //ofstream file2;
155 | //file2.open("dectree.txt", std::ios_base::app);
156 |
157 | uint32_t node1;
158 | uint32_t node2;
159 |
160 | DecTree::Node* node;
161 | uint32_t index;
162 | string line;
163 | vector tokens;
164 | vector::iterator it;
165 | float thres;
166 | while (getline(file, line)){
167 | tokenize(line, tokens);
168 | if(tokens[1] == "label=\"gini"){
169 | node1 = atoi(tokens[0].c_str());
170 | this->add_node(new DecTree::Node());
171 | this->node_vec[node1]->leaf = true;
172 | this->num_of_leaves++;
173 | this->node_vec[node1]->classification = rand() % 100;
174 | }
175 | else if(tokens[1] == "label=\"X"){
176 | node1 = atoi(tokens[0].c_str());
177 | //cout << node1 << endl;
178 | node = new DecTree::Node();
179 | index = atoi(tokens[2].c_str());
180 | node->attribute_index = index;
181 | //cout << index << endl;
182 | string str_cleaned = tokens[4];
183 | eraseSubStr(str_cleaned, "\\ngini");
184 | thres = atof(str_cleaned.c_str());
185 | node->threshold = thres*1000;
186 | //cout << node->threshold << endl; //Thresholds are converted so that we only compare integers
187 | this->num_dec_nodes++;
188 | this->add_node(node);
189 | this->add_decnode(node);
190 |
191 | it = find_if(this->attributes.begin(), this->attributes.end(), SearchFunction(index));
192 | if(it == this->attributes.end()){
193 | this->num_attributes++;
194 | }
195 | this->attributes.push_back(index);
196 | this->thresholds.push_back(node->threshold);
197 | }
198 | else if(tokens[1] == "->"){
199 | node1 = atoi(tokens[0].c_str());
200 | node2 = atoi(tokens[2].c_str());
201 | this->add_edge(this->node_vec[node1], this->node_vec[node2]);
202 | }
203 | }
204 | for(uint32_t i = 0; i < this->node_vec.size(); ++i){
205 | node = this->node_vec[i];
206 | if(node->leaf){ //Right is also 0 in this case
207 | if(node->level > this->depth){
208 | this->depth = node->level;
209 | }
210 | }
211 | }
212 | //cout << "Total number of attributes " << this->num_attributes << endl;
213 | //cout << "Depth of the tree " << this->depth << endl;
214 | //cout << "Total number of decision nodes " << this->num_dec_nodes << endl;
215 | //cout << "Total number of leaves " << this->num_of_leaves << endl;
216 |
217 | for(uint32_t i = 0; i < this->node_vec.size(); ++i){
218 | node = this->node_vec[i];
219 | if(node->leaf){
220 | this->dummy_non_full += this->depth - node->level;
221 | }
222 | }
223 | //cout << "Total number of dummy nodes in non-full tree " << this->dummy_non_full << endl;
224 |
225 | uint32_t total_number_of_edges = 0;
226 | for(uint32_t i = 0; i < this->node_vec.size(); ++i){
227 | node = this->node_vec[i];
228 | if(node->leaf){
229 | total_number_of_edges += node->level;
230 | }
231 | }
232 | //cout << "Total number of edges " << total_number_of_edges << endl;
233 | file.close();
234 | //file2.close();
235 | }
236 |
237 |
238 | void DecTree::fullTree(uint32_t num_att, uint32_t tree_depth){
239 | this->num_attributes = num_att;
240 | this->num_dec_nodes = pow(2.0, num_att);
241 | this->depth = tree_depth;
242 | this->num_of_leaves = pow(2.0, num_att + 1);
243 | vector attr(num_att, 0);
244 | vector thres(this->num_dec_nodes, 0);
245 | this->attributes = attr;
246 | this->thresholds = thres;
247 |
248 | for(uint32_t i = 0; i < this->num_dec_nodes + this->num_of_leaves; ++i){
249 | DecTree::Node* newNode = new DecTree::Node();
250 | if(i == 0){
251 | newNode->parent = NULL;
252 | newNode->level = 0;
253 | }
254 | else if(i%2 == 0){
255 | this->node_vec[i/2 - 1]->right = newNode;
256 | newNode->parent = this->node_vec[i/2 - 1];
257 | newNode->level = newNode->parent->level + 1;
258 | }
259 | else if(i%2 == 1){ //odd case
260 | this->node_vec[i/2]->left = newNode;
261 | newNode->parent = this->node_vec[i/2];
262 | newNode->level = newNode->parent->level + 1;
263 | }
264 |
265 | if(i < this->num_dec_nodes){
266 | this->decnode_vec.push_back(newNode);
267 | }
268 | else{
269 | newNode->leaf = true;
270 | }
271 | this->node_vec.push_back(newNode);
272 | }
273 | }
274 |
275 | void DecTree::depthPad(){
276 | DecTree::Node* tmp;
277 | for(uint32_t i = 0; i < this->node_vec.size(); ++i){
278 | if(this->node_vec[i]->leaf){
279 | if(this->node_vec[i]->level != this->depth){
280 | tmp = this->node_vec[i];
281 | this->node_vec[i] = new DecTree::Node();
282 | this->node_vec[i]->parent = tmp->parent;
283 | this->node_vec[i]->level = tmp->level; //leaf is false, threshold is 0, attribute_index is 0
284 | this->decnode_vec.push_back(this->node_vec[i]);
285 | this->attributes.push_back(this->node_vec[i]->attribute_index);
286 | this->thresholds.push_back(this->node_vec[i]->threshold);
287 | this->num_dec_nodes++;
288 |
289 | tmp->level++;
290 | tmp->parent = this->node_vec[i];
291 | this->node_vec[i]->left = tmp;
292 | this->node_vec[i]->right = tmp;
293 | this->node_vec.push_back(tmp);
294 | }
295 | }
296 | }
297 | //cout << "Number of decision nodes " << this->num_dec_nodes << endl;
298 | }
299 |
300 | void DecTree::evaluate(vector inputs){
301 | DecTree::Node* this_node = this->node_vec[0];
302 | while(!(this_node->leaf)){
303 | //cout << inputs[this_node->attribute_index] << endl;
304 | //cout << this_node->threshold << endl;
305 | if(inputs[this_node->attribute_index] <= this_node->threshold){
306 | this_node = this_node->left;
307 | }
308 | else{
309 | this_node = this_node->right;
310 | }
311 | }
312 | }
313 |
314 | /**
315 | * Destructor DecTree
316 | */
317 | DecTree::~DecTree(){
318 | node_vec.clear();
319 | }
320 |
--------------------------------------------------------------------------------
/ABY_example/dectree/common/crypto_party/dgk_party.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | \file dgk_party.cpp
3 | \author masoud.naderpour@helsinki.fi
4 | \copyright ABY - A Framework for Efficient Mixed-protocol Secure Two-party Computation
5 | Copyright (C) 2019 Engineering Cryptographic Protocols Group, TU Darmstadt
6 | This program is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU Lesser General Public License as published
8 | by the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 | ABY is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | GNU Lesser General Public License for more details.
14 | You should have received a copy of the GNU Lesser General Public License
15 | along with this program. If not, see .
16 | \brief DGK crypto
17 | */
18 |
19 |
20 |
21 | #include "dgk_party.h"
22 |
23 | #define CHECKCOMM 0
24 | #define DEBUG 0
25 | #define NETDEBUG 0
26 | #define WINDOWSIZE 50000 //maximum size of a network packet in Byte
27 |
28 | /**
29 | * initializes a DGK_Party with the asymmetric security parameter and the sharelength and exchanges public keys.
30 | * @param mode - 0 = generate new key; 1 = read key
31 | */
32 | DGK::DGK(uint32_t DGKbits, uint32_t sharelen, channel* chan, uint32_t readkey) {
33 |
34 | m_nShareLength = sharelen;
35 | m_nDGKbits = DGKbits;
36 | m_nBuflen = DGKbits / 8 + 1; //size of one ciphertext to send via network. DGK uses n bits == n/8 bytes
37 |
38 | #if DEBUG
39 | std::cout << "Created party with " << DGKbits << " key bits and" << sharelen << " bit shares" << std::endl;
40 | #endif
41 |
42 | gmp_randinit_default(m_randstate);
43 | srand(time(0));
44 | gmp_randseed_ui(m_randstate, rand());
45 |
46 | if (readkey) {
47 | readKey();
48 | } else {
49 | generateKey();
50 | }
51 |
52 | keyExchange(chan);
53 | }
54 |
55 | /**
56 | * initializes a DGK_Party with the asymmetric security parameter and the sharelength.
57 | * @param mode - 0 = generate new key; 1 = read key
58 | * Public keys must be exchanged manually when using this constructor!
59 | */
60 | DGK::DGK(uint32_t DGKbits, uint32_t sharelen, uint32_t readkey) {
61 |
62 | m_nShareLength = sharelen;
63 | m_nDGKbits = DGKbits;
64 | m_nBuflen = DGKbits / 8; //size of one ciphertext to send via network. DGK uses n bits == n/8 bytes
65 |
66 | #if DEBUG
67 | std::cout << "Created party with " << DGKbits << " key bits and" << sharelen << " bit shares" << std::endl;
68 | #endif
69 |
70 | gmp_randinit_default(m_randstate);
71 | gmp_randseed_ui(m_randstate, rand());
72 |
73 | if (readkey) {
74 | if (!readKey()){
75 | std::cout << "No DGK key file found! Generating a new DGK key." << std::endl;
76 | generateKey();
77 | storeKey();
78 | }
79 | } else {
80 | generateKey();
81 | }
82 | }
83 |
84 | bool DGK::readKey() {
85 | #if DEBUG
86 | std::cout << "KeyGen" << std::endl;
87 | #endif
88 | dgk_readkey(m_nDGKbits, m_nShareLength, &m_localpub, &m_prv);
89 | #if DEBUG
90 | std::cout << "key read." << std::endl;
91 | #endif
92 | return true;
93 | }
94 |
95 | void DGK::storeKey(){
96 |
97 | dgk_storekey(m_nDGKbits, m_nShareLength, m_localpub, m_prv);
98 | }
99 |
100 | void DGK::generateKey() {
101 | #if DEBUG
102 | std::cout << "KeyGen" << std::endl;
103 | #endif
104 | dgk_keygen(m_nDGKbits, m_nShareLength, &m_localpub, &m_prv);
105 |
106 | #if DEBUG
107 | std::cout << "key generated." << std::endl;
108 | #endif
109 | }
110 |
111 | /**
112 | * deletes party and frees keys and randstate
113 | */
114 | DGK::~DGK() {
115 | #if DEBUG
116 | std::cout << "Deleting DGK..." << std::endl;
117 | #endif
118 | gmp_randclear(m_randstate);
119 | dgk_freeprvkey(m_prv);
120 | dgk_freepubkey(m_localpub);
121 | dgk_freepubkey(m_remotepub);
122 |
123 | }
124 |
125 | /**
126 | * encrypts PTs in the given Vec
127 | */
128 | bool DGK::encrypt(vector &plaintexts, BYTE* &ciphertexts){
129 |
130 | mpz_t tmp, tmp2, res;
131 | mpz_inits(tmp, tmp2, res, NULL);
132 |
133 | for(int i = 0;i < plaintexts.size();i++){
134 |
135 | //mpz_set_ui(tmp, plaintexts[i]);
136 | mpz_set_ui(tmp, 123456); //Testing with a fixed val for debugging
137 |
138 | dgk_encrypt_crt(res, m_localpub, m_prv, tmp);
139 | //dgk_encrypt_plain(res, m_localpub, tmp);
140 | //mpz_mod(res,res, m_localpub->n); //res % modulus n (TODO: remove this)
141 |
142 | mpz_set_ui(res, plaintexts[i]);
143 | mpz_export(ciphertexts + i * m_nBuflen, NULL, -1, 1, 1, 0, res);
144 |
145 | dgk_decrypt(tmp2, m_localpub, m_prv, res);
146 | gmp_printf ("feature%d (%Zd) decryption is (%Zd)\n", i, tmp, tmp2); //TODO: solve the problem with decryption :(
147 |
148 | if (mpz_cmp(tmp, tmp2)) {
149 | printf("ERROR!\n");
150 | break; //exit(0);
151 | }
152 | }
153 |
154 | return 1;
155 | }
156 |
157 | /**
158 | * encrypts & sends a Vec of plaintexts
159 | */
160 | void DGK::encSndRcvVec(e_role role, vector &plaintexts, mpz_t* &ciphertexts, channel* &chan){
161 |
162 |
163 | struct timespec start, end;
164 | uint32_t shareBytes = m_nShareLength / 8;
165 | uint32_t offset = 0;
166 |
167 | clock_gettime(CLOCK_MONOTONIC, &start);
168 |
169 | BYTE *m_encSndBuf, *m_encRcvBuf;
170 | m_encSndBuf = (BYTE*) calloc(plaintexts.size() * m_nBuflen, 1);
171 | m_encRcvBuf = (BYTE*) calloc(plaintexts.size() * m_nBuflen, 1);
172 |
173 | encrypt(plaintexts, m_encSndBuf);
174 |
175 | clock_gettime(CLOCK_MONOTONIC, &end);
176 |
177 | // send & receive encrypted values
178 | int window = WINDOWSIZE;
179 | int tosend = m_nBuflen * plaintexts.size();
180 | offset = 0;
181 |
182 | while (tosend > 0) {
183 |
184 | window = min(window, tosend);
185 |
186 | chan->send(m_encSndBuf + offset, window);
187 | chan->blocking_receive(m_encRcvBuf + offset, window);
188 |
189 | tosend -= window;
190 | offset += window;
191 | }
192 |
193 | #if CHECKCOMM
194 | for(int i = 0;i < m_nBuflen * plaintexts.size();i++) {
195 | if(m_encRcvBuf[i] != m_encSndBuf[i]){
196 | std::cout << "Error: buff is not received correctly!" << std::endl;
197 | break;
198 | } else if(i+1 == m_nBuflen * plaintexts.size()) {
199 | std::cout << "checking successful." << std::endl;
200 | }
201 | }
202 |
203 | #endif
204 |
205 | //reconstructs the CTs from the received raw data buffer
206 |
207 | ciphertexts = (mpz_t*) calloc(plaintexts.size(), sizeof(mpz_t));
208 |
209 | for(int i = 0; i < plaintexts.size();i++){
210 |
211 | mpz_init(ciphertexts[i]);
212 | mpz_import(ciphertexts[i], m_nBuflen, -1, 1, 1, 0, m_encRcvBuf + i * m_nBuflen);
213 | //gmp_printf ("feature %d is %Zx\n", i, ciphertexts[i]);
214 | }
215 |
216 | //TODO: free unnecessary bufs
217 | }
218 |
219 | void DGK::mskSndRcvVec(e_role role, mpz_t* &CTs, mpz_t* &rndMsks, vector &mapping, mpz_t* &inputsVec, channel* &chan){
220 |
221 | mpz_t tmp, rnd, res;
222 | mpz_inits(tmp, rnd, res, NULL);
223 |
224 | uint32_t statisParam = 40;
225 |
226 | BYTE *m_encSndBuf, *m_encRcvBuf;
227 | int bufSize = mapping.size() * m_nBuflen;
228 | m_encSndBuf = (BYTE*) calloc(bufSize, 1);
229 | m_encRcvBuf = (BYTE*) calloc(bufSize, 1);
230 |
231 | for(int i=0;i < mapping.size();i++){
232 |
233 | //mpz_set_ui(rnd, rndMsks[i]); // mask > 100 bits
234 | mpz_set (rnd, rndMsks[i]);
235 | //mpz_urandomb(rnd, m_randstate, m_nShareLength - 1);
236 |
237 | dgk_encrypt_plain(res, m_remotepub, rnd); // server encrypts the mask
238 |
239 | mpz_mul(res, res, CTs[mapping[i]]); // masks the feature homomorphically
240 | mpz_mod(res,res, m_remotepub->n); //res % modulus n
241 |
242 | mpz_export(m_encSndBuf + i * m_nBuflen, NULL, -1, 1, 1, 0, res); // embeds the masked inputs in Snd buffer
243 |
244 | }
245 |
246 | // send & receive encrypted values
247 | int window = WINDOWSIZE;
248 | int tosend = m_nBuflen * mapping.size();
249 | int offset = 0;
250 |
251 | while (tosend > 0) {
252 |
253 | window = min(window, tosend);
254 |
255 | chan->send(m_encSndBuf + offset, window);
256 | chan->blocking_receive(m_encRcvBuf + offset, window);
257 |
258 | tosend -= window;
259 | offset += window;
260 | }
261 |
262 | #if CHECKCOMM
263 |
264 | for(int i = 0;i < bufSize;i++) {
265 | if(m_encRcvBuf[i] != m_encSndBuf[i]){
266 | std::cout << "Error: buff is not received correctly!" << std::endl;
267 | break;
268 | } else if(i+1 == bufSize) {
269 | std::cout << "checking successful." << std::endl;
270 | }
271 | }
272 |
273 | #endif
274 |
275 | //reconstructs the CTs from the received raw data buffer
276 |
277 | mpz_t* m_pCTVec = (mpz_t*) calloc(mapping.size(), sizeof(mpz_t)); //TODO: get rid of this
278 | inputsVec = (mpz_t*) calloc(mapping.size(), sizeof(mpz_t)); //inputs to the substraction circuit in plaintext
279 |
280 | for(int i = 0; i < mapping.size();i++){
281 |
282 | mpz_inits(m_pCTVec[i], inputsVec[i], NULL);
283 | //mpz_import(m_pCTVec[i], m_nBuflen, -1, 1, 1, 0, m_encRcvBuf + i * m_nBuflen);
284 | //dgk_decrypt(inputsVec[i],m_localpub, m_prv, m_pCTVec[i]); // decryps the inputs here before returning the vec
285 | }
286 |
287 | //TODO: free unnecessary bufs;
288 | }
289 |
290 | /**
291 | * exchanges private keys with other party via sock, pre-calculates fixed-base representation of remote pub-key
292 | */
293 | void DGK::keyExchange(channel* &chan) {
294 |
295 | //send public key
296 | sendmpz_t(m_localpub->n, chan);
297 | sendmpz_t(m_localpub->g, chan);
298 | sendmpz_t(m_localpub->h, chan);
299 |
300 | //receive and complete public key
301 | mpz_t n, g, h;
302 | mpz_inits(n, g, h, NULL);
303 | receivempz_t(n, chan); //n
304 | receivempz_t(g, chan); //g
305 | receivempz_t(h, chan); //h
306 |
307 | dgk_complete_pubkey(m_nDGKbits, m_nShareLength, &m_remotepub, n, g, h);
308 |
309 | // pre calculate table for fixed-base exponentiation for client
310 | fbpowmod_init_g(m_remotepub->g, m_remotepub->n, 2 * m_nShareLength + 2);
311 | fbpowmod_init_h(m_remotepub->h, m_remotepub->n, 400); // 2.5 * t = 2.5 * 160 = 400 bit
312 |
313 | //free a and b
314 | mpz_clears(n, g, h, NULL);
315 |
316 | #if DEBUG
317 | std::cout << "KX done. This pubkey: " << m_localpub->n << " remotekey: " << m_remotepub->n << std::endl;
318 | #endif
319 | }
320 |
321 | /**
322 | * send one mpz_t to sock
323 | */
324 | void DGK::sendmpz_t(mpz_t t, channel* chan, BYTE * buf) {
325 |
326 | //clear upper bytes of the buffer, so tailing bytes are zero
327 | for (int i = mpz_sizeinbase(t, 256); i < m_nBuflen; i++) {
328 | *(buf + i) = 0;
329 | }
330 |
331 | #if NETDEBUG
332 | std::cout << mpz_sizeinbase(t, 256) << " vs. " << m_nBuflen << std::endl;
333 | #endif
334 |
335 | mpz_export(buf, NULL, -1, 1, 1, 0, t);
336 |
337 | //send bytes of t
338 | chan->send(buf, (uint64_t) m_nBuflen);
339 |
340 | #if NETDEBUG
341 | std::cout << std::endl << "SEND" << std::endl;
342 | for (int i = 0; i < m_nBuflen; i++) {
343 | printf("%02x.", *(buf + i));
344 | }
345 |
346 | std::cout << std::endl << "sent: " << t << " with len: " << m_nBuflen << " should have been " << mpz_sizeinbase(t, 256) << std::endl;
347 | #endif
348 | }
349 |
350 | /**
351 | * receive one mpz_t from sock. t must be initialized.
352 | */
353 | void DGK::receivempz_t(mpz_t t, channel* chan, BYTE * buf) {
354 | chan->blocking_receive(buf, (uint64_t) m_nBuflen);
355 | mpz_import(t, m_nBuflen, -1, 1, 1, 0, buf);
356 |
357 | #if NETDEBUG
358 | std::cout << std::endl << "RECEIVE" << std::endl;
359 | for (int i = 0; i < m_nBuflen; i++) {
360 | printf("%02x.", *(buf + i));
361 | }
362 |
363 | std::cout << "received: " << t << " with len: " << m_nBuflen << std::endl;
364 | #endif
365 | }
366 |
367 | /**
368 | * send one mpz_t to sock, allocates buffer
369 | */
370 | void DGK::sendmpz_t(mpz_t t, channel* chan) {
371 | unsigned int bytelen = mpz_sizeinbase(t, 256);
372 | BYTE* arr = (BYTE*) malloc(bytelen);
373 | mpz_export(arr, NULL, 1, 1, 1, 0, t);
374 |
375 | //send byte length
376 | chan->send((BYTE*) &bytelen, sizeof(bytelen));
377 |
378 | //send bytes of t
379 | chan->send(arr, (uint64_t) bytelen);
380 |
381 | free(arr);
382 | #if NETDEBUG
383 | std::cout << "sent: " << t << " with len: " << bytelen << std::endl;
384 | #endif
385 | }
386 |
387 | /**
388 | * receive one mpz_t from sock. t must be initialized.
389 | */
390 | void DGK::receivempz_t(mpz_t t, channel* chan) {
391 | unsigned int bytelen;
392 |
393 | //reiceive byte length
394 | chan->blocking_receive((BYTE*) &bytelen, sizeof(bytelen));
395 | BYTE* arr = (BYTE*) malloc(bytelen);
396 |
397 | //receive bytes of t
398 | chan->blocking_receive(arr, (uint64_t) bytelen);
399 | mpz_import(t, bytelen, 1, 1, 1, 0, arr);
400 |
401 | free(arr);
402 | #if NETDEBUG
403 | std::cout << "received: " << t << " with len: " << bytelen << std::endl;
404 | #endif
405 | }
406 |
407 | void DGK::printBuf(BYTE* b, uint32_t len) {
408 | for (uint32_t i = 0; i < len; i++) {
409 | printf("%02x.", *(b + i));
410 | }
411 | std::cout << std::endl;
412 | }
413 |
414 |
--------------------------------------------------------------------------------
/XCMP_files/benchmark_gt/dectree.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | \file dectree.hpp
3 | \author kiss@encrypto.cs.tu-darmstadt.de
4 | \copyright Decision Tree
5 | Copyright (C) 2019 Cryptography and Privacy Engineering Group, TU Darmstadt
6 | This program is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU Affero General Public License as published
8 | by the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 | This program is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | GNU Affero General Public License for more details.
14 | You should have received a copy of the GNU Affero General Public License
15 | along with this program. If not, see .
16 | \brief DecTree class for reading in decision trees generated from scikit-learn.
17 | */
18 |
19 | #ifndef DECTREE_H_INCLUDED
20 | #define DECTREE_H_INCLUDED
21 |
22 | #include
23 | #include
24 | #include
25 | #include
26 | #include
27 | #include
28 | #include
29 | #include
30 | #include
31 | #include
32 | #include
33 | #include /* pow */
34 |
35 | #include
36 | #include
37 | #include
38 | #include
39 | #include
40 | #include
41 | #include
42 | #include
43 | #include
44 |
45 | typedef mcl::FpT<> Fp;
46 | typedef mcl::FpT Zn; // use ZnTag because Zn is different class with Fp
47 | typedef mcl::EcT Ec;
48 | typedef mcl::ElgamalT Elgamal;
49 |
50 | using namespace std;
51 |
52 | class DecTree {
53 | public:
54 | struct Node {
55 | // Pointer to the first child node
56 | Node* left;
57 | // Pointer to the second child node
58 | Node* right;
59 | // Pointer to the first parent node
60 | Node* parent;
61 | // True if the edges coming into the node are already colored
62 | uint32_t level;
63 | // True if the node is a leaf
64 | bool leaf;
65 | // Threshold in decision node to compare with
66 | uint64_t threshold;
67 | // Threshold in decision node to compare with
68 | uint64_t classification;
69 | // Attribute index to compare with, -1 if undefined
70 | uint32_t attribute_index;
71 | //pathcost until this node
72 | Elgamal::CipherText path_cost;
73 |
74 | Node();
75 | Node(const Node&);
76 | };
77 | // Vector of nodes that belong to the Gamma1 graph
78 | vector node_vec;
79 | // Vector of decision nodes that belong to the Gamma1 graph
80 | vector decnode_vec;
81 | //Node** node_array;
82 | // Vector of all attributes used for comparison with their occurrence
83 | vector attributes;
84 | // Vector of all thresholds used for comparison with their occurrence
85 | vector thresholds;
86 |
87 | //STATISTICS FOR DECISION TREES
88 | //number of attributes
89 | uint32_t num_attributes;
90 | //number of decision nodes
91 | uint32_t num_dec_nodes;
92 | //depth = largest level of leaves
93 | uint32_t depth;
94 | //number of leaves
95 | uint32_t num_of_leaves;
96 | //dummy in our case
97 | uint32_t dummy_non_full;
98 |
99 | DecTree();
100 | DecTree(const DecTree&);
101 |
102 | void add_node(Node*);
103 | void add_decnode(Node*);
104 | void add_edge(Node*, Node*);
105 | void read_from_file(string);
106 | void evaluate(vector inputs);
107 | void depthPad();
108 | void fullTree(uint32_t num_att, uint32_t depth);
109 |
110 | ~DecTree();
111 | };
112 |
113 | void tokenize(const std::string&, std::vector&);
114 | void eraseSubStr(std::string &, const std::string &);
115 |
116 | /**
117 | * Node constructor that takes its number num, by default it has no children
118 | * and parents, is not colored.
119 | * @param num the number that identifies the node
120 | */
121 | DecTree::Node::Node()
122 | : left(0)
123 | , right(0)
124 | , parent(0)
125 | , level(0)
126 | , leaf(false)
127 | , threshold(0)
128 | , attribute_index(0)
129 | , classification(0)
130 | {}
131 |
132 | DecTree::Node::Node(const Node& other){
133 | left = new Node(*(other.left));
134 | right = new Node(*(other.right));
135 | parent = new Node(*(other.parent));
136 | level = other.level;
137 | leaf = other.leaf;
138 | threshold = other.threshold;
139 | attribute_index = other.attribute_index;
140 | classification = other.classification;
141 | }
142 |
143 | /**
144 | * Gamma2 constructor that creates a Gamma2 graph with specified number of Nodes
145 | * @param num the number specifying the number of Nodes
146 | */
147 | DecTree::DecTree()
148 | {
149 | num_attributes = 0;
150 | num_dec_nodes = 0;
151 | depth = 0;
152 | num_of_leaves = 0;
153 | dummy_non_full = 0;
154 | }
155 |
156 | DecTree::DecTree(const DecTree& other){
157 | node_vec = other.node_vec;
158 | decnode_vec = other.decnode_vec;
159 | attributes = other.attributes;
160 | thresholds = other.thresholds;
161 | num_attributes = other.num_attributes;
162 | num_dec_nodes = other.num_dec_nodes;
163 | depth = other.depth;
164 | num_of_leaves = other.num_of_leaves;
165 | dummy_non_full = other.dummy_non_full;
166 | }
167 |
168 | /**
169 | * Add a node
170 | * @param node the Node to be added to the tree
171 | */
172 | void DecTree::add_node(DecTree::Node* node){
173 | node_vec.push_back(node);
174 | }
175 |
176 | /**
177 | * Add a decision node
178 | * @param node the Node to be added to the tree
179 | */
180 | void DecTree::add_decnode(DecTree::Node* node){
181 | decnode_vec.push_back(node);
182 | }
183 |
184 | /**
185 | * Add an edge between two nodes
186 | * @param n1 the starting Node of the edge
187 | * @param n2 the ending Node of the edge
188 | */
189 | void DecTree::add_edge(DecTree::Node* n1, DecTree::Node* n2){
190 | n2->parent = n1;
191 | n2->level = n1->level + 1;
192 | if(n1->left == NULL){
193 | n1->left = n2;
194 | }
195 | else{
196 | n1->right = n2;
197 | }
198 | }
199 |
200 | /**
201 | * Takes a string in the Format "i i i ..." separated by ' '
202 | * @param str the string to tokenize
203 | * @param tokens the result vector of wire id
204 | */
205 | void tokenize(const std::string& str, std::vector& tokens) {
206 | tokens.clear();
207 | std::size_t prev = 0, pos;
208 | while ((pos = str.find_first_of(" [] \\ ", prev)) != std::string::npos)
209 | {
210 | if (pos > prev)
211 | tokens.push_back(str.substr(prev, pos-prev));
212 | prev = pos+1;
213 | }
214 | if (prev < str.length())
215 | tokens.push_back(str.substr(prev, std::string::npos));
216 | }
217 |
218 | /**
219 | * Erase First Occurrence of given substring from main string.
220 | */
221 | void eraseSubStr(std::string & mainStr, const std::string & toErase)
222 | {
223 | // Search for the substring in string
224 | size_t pos = mainStr.find(toErase);
225 |
226 | if (pos != std::string::npos)
227 | {
228 | // If found then erase it from string
229 | mainStr.erase(pos, toErase.length());
230 | }
231 | }
232 |
233 | class SearchFunction {
234 | public:
235 | SearchFunction(uint32_t item): item_(item) {}
236 | bool operator()(std::uint64_t const & ref) {
237 | return ref == item_;
238 | }
239 | private:
240 | uint32_t item_;
241 | };
242 |
243 | //root node will be in decnode_vec[0] and node_vec[0]
244 | void DecTree::read_from_file(string string_file){
245 | const char* filename = string_file.c_str();
246 | ifstream file;
247 | file.open(filename);
248 | cout << filename << endl;
249 |
250 | //ofstream file2;
251 | //file2.open("dectree.txt", std::ios_base::app);
252 |
253 | uint32_t node1;
254 | uint32_t node2;
255 |
256 | DecTree::Node* node;
257 | uint32_t index;
258 | string line;
259 | vector tokens;
260 | vector::iterator it;
261 | float thres;
262 | while (getline(file, line)){
263 | tokenize(line, tokens);
264 | if(tokens[1] == "label=\"gini"){
265 | node1 = atoi(tokens[0].c_str());
266 | this->add_node(new DecTree::Node());
267 | this->node_vec[node1]->leaf = true;
268 | this->num_of_leaves++;
269 | this->node_vec[node1]->classification = atoi(tokens[6].c_str());
270 | }
271 | else if(tokens[1] == "label=\"X"){
272 | node1 = atoi(tokens[0].c_str());
273 | //cout << node1 << endl;
274 | node = new DecTree::Node();
275 | index = atoi(tokens[2].c_str());
276 | node->attribute_index = index;
277 | //cout << index << endl;
278 | thres = atof(tokens[4].c_str());
279 | node->threshold = thres*1000;
280 | //cout << node->threshold << endl; //Thresholds are converted so that we only compare integers
281 | this->num_dec_nodes++;
282 | this->add_node(node);
283 | this->add_decnode(node);
284 |
285 | it = find_if(this->attributes.begin(), this->attributes.end(), SearchFunction(index));
286 | if(it == this->attributes.end()){
287 | this->num_attributes++;
288 | }
289 | this->attributes.push_back(index);
290 | this->thresholds.push_back(node->threshold);
291 | }
292 | else if(tokens[1] == "->"){
293 | node1 = atoi(tokens[0].c_str());
294 | node2 = atoi(tokens[2].c_str());
295 | this->add_edge(this->node_vec[node1], this->node_vec[node2]);
296 | }
297 | }
298 | for(uint32_t i = 0; i < this->node_vec.size(); ++i){
299 | node = this->node_vec[i];
300 | if(node->leaf){ //Right is also 0 in this case
301 | if(node->level > this->depth){
302 | this->depth = node->level;
303 | }
304 | }
305 | }
306 | //cout << "Total number of attributes " << this->num_attributes << endl;
307 | //cout << "Depth of the tree " << this->depth << endl;
308 | //cout << "Total number of decision nodes " << this->num_dec_nodes << endl;
309 | //cout << "Total number of leaves " << this->num_of_leaves << endl;
310 |
311 | for(uint32_t i = 0; i < this->node_vec.size(); ++i){
312 | node = this->node_vec[i];
313 | if(node->leaf){
314 | this->dummy_non_full += this->depth - node->level;
315 | }
316 | }
317 | //cout << "Total number of dummy nodes in non-full tree " << this->dummy_non_full << endl;
318 |
319 | uint32_t total_number_of_edges = 0;
320 | for(uint32_t i = 0; i < this->node_vec.size(); ++i){
321 | node = this->node_vec[i];
322 | if(node->leaf){
323 | total_number_of_edges += node->level;
324 | }
325 | }
326 | //cout << "Total number of edges " << total_number_of_edges << endl;
327 | file.close();
328 | //file2.close();
329 | }
330 |
331 |
332 | void DecTree::fullTree(uint32_t num_att, uint32_t tree_depth){
333 | this->num_attributes = num_att;
334 | this->num_dec_nodes = pow(2.0, num_att);
335 | this->depth = tree_depth;
336 | this->num_of_leaves = pow(2.0, num_att + 1);
337 | vector attr(num_att, 0);
338 | vector thres(this->num_dec_nodes, 0);
339 | this->attributes = attr;
340 | this->thresholds = thres;
341 |
342 | for(uint32_t i = 0; i < this->num_dec_nodes + this->num_of_leaves; ++i){
343 | DecTree::Node* newNode = new DecTree::Node();
344 | if(i == 0){
345 | newNode->parent = NULL;
346 | newNode->level = 0;
347 | }
348 | else if(i%2 == 0){
349 | this->node_vec[i/2 - 1]->right = newNode;
350 | newNode->parent = this->node_vec[i/2 - 1];
351 | newNode->level = newNode->parent->level + 1;
352 | }
353 | else if(i%2 == 1){ //odd case
354 | this->node_vec[i/2]->left = newNode;
355 | newNode->parent = this->node_vec[i/2];
356 | newNode->level = newNode->parent->level + 1;
357 | }
358 |
359 | if(i < this->num_dec_nodes){
360 | this->decnode_vec.push_back(newNode);
361 | }
362 | else{
363 | newNode->leaf = true;
364 | }
365 | this->node_vec.push_back(newNode);
366 | }
367 | }
368 |
369 | void DecTree::depthPad(){
370 | DecTree::Node* tmp;
371 | for(uint32_t i = 0; i < this->node_vec.size(); ++i){
372 | if(this->node_vec[i]->leaf){
373 | if(this->node_vec[i]->level != this->depth){
374 | tmp = this->node_vec[i];
375 | this->node_vec[i] = new DecTree::Node();
376 | this->node_vec[i]->parent = tmp->parent;
377 | this->node_vec[i]->level = tmp->level; //leaf is false, threshold is 0, attribute_index is 0
378 | this->decnode_vec.push_back(this->node_vec[i]);
379 | this->attributes.push_back(this->node_vec[i]->attribute_index);
380 | this->thresholds.push_back(this->node_vec[i]->threshold);
381 | this->num_dec_nodes++;
382 |
383 | tmp->level++;
384 | tmp->parent = this->node_vec[i];
385 | this->node_vec[i]->left = tmp;
386 | this->node_vec[i]->right = tmp;
387 | this->node_vec.push_back(tmp);
388 | }
389 | }
390 | }
391 | //cout << "Number of decision nodes " << this->num_dec_nodes << endl;
392 | }
393 |
394 | void DecTree::evaluate(vector inputs){
395 | DecTree::Node* this_node = this->node_vec[0];
396 | while(!(this_node->leaf)){
397 | //cout << inputs[this_node->attribute_index] << endl;
398 | //cout << this_node->threshold << endl;
399 | if(inputs[this_node->attribute_index] <= this_node->threshold){
400 | this_node = this_node->left;
401 | }
402 | else{
403 | this_node = this_node->right;
404 | }
405 | }
406 | }
407 |
408 | /**
409 | * Destructor DecTree
410 | */
411 | DecTree::~DecTree(){
412 | node_vec.clear();
413 | }
414 |
415 | #endif // DECTREE_H_INCLUDED
416 |
--------------------------------------------------------------------------------
/ABY_example/dectree/common/decision-tree-circuit.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | \file decision-tree-circuit.cpp
3 | \author masoud.naderpour@helsinki.fi
4 | \copyright ABY - A Framework for Efficient Mixed-protocol Secure Two-party Computation
5 | Copyright (C) 2019 Engineering Cryptographic Protocols Group, TU Darmstadt
6 | This program is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU Lesser General Public License as published
8 | by the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 | ABY is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | GNU Lesser General Public License for more details.
14 | You should have received a copy of the GNU Lesser General Public License
15 | along with this program. If not, see .
16 | \brief Private decision tree evaluation
17 | */
18 |
19 | #include "decision-tree-circuit.h"
20 | #include "garbledBP.h"
21 | #include "sndrcv.h"
22 | #include
23 | #include
24 | #include "auxiliary-functions.h"
25 | #include "../../../abycore/sharing/sharing.h"
26 |
27 | //#define AES_NOT_HASH
28 |
29 | int pri_eval_decision_tree(e_role role, char* address, uint16_t port, seclvl seclvl, uint32_t nthreads, e_mt_gen_alg mt_alg, e_sharing comparesharing, e_sel_alg sel_alg, uint64_t numNodes, uint64_t dimension, DecTree &tree) {
30 |
31 | //=============== Initialization ================
32 |
33 | uint32_t bitlen = 8, i, j, maxbitlen=64, keybitlen = seclvl.symbits, keysize = keybitlen/8;
34 | uint16_t m_numNodes = numNodes;
35 | uint16_t dim = dimension;
36 | uint32_t nodeSize = keysize + sizeof(uint16_t) + sizeof(uint8_t);
37 | uint8_t *m_cGarbledTree;
38 |
39 | timeval tbegin, tend;
40 | srand(time(NULL));
41 |
42 | // ----- generate a random permutation of [0 1...d-1] ----------
43 | uint16_t *permutation;
44 | permutation = new uint16_t[m_numNodes];
45 | for (uint16_t i = 0;i < m_numNodes;i++) permutation[i] = i;
46 | random_shuffle(permutation + 1, permutation + m_numNodes ); //permutation[0] = 0 */
47 |
48 | //----------- generate a random feature vector ----------------
49 | vector m_vFeatureVec;
50 |
51 | for(int i=0; i < dim; i++){
52 | m_vFeatureVec.push_back(rand());
53 | //cout << "Feature " << i << ":" << m_vFeatureVec[i] << endl;
54 | }
55 |
56 | // ---- ABY init --------
57 | ABYParty* party = new ABYParty(role, address, port, seclvl, keybitlen, nthreads, mt_alg);
58 |
59 | vector& sharings = party->GetSharings();
60 | BooleanCircuit *permuteCirc, *cmpCirc;
61 | //permuteCirc = (BooleanCircuit*) sharings[S_BOOL]->GetCircuitBuildRoutine(); // for B+Y testing
62 | cmpCirc = (BooleanCircuit*) sharings[S_YAO]->GetCircuitBuildRoutine();
63 | permuteCirc = cmpCirc;
64 |
65 | share **m_shrCircOutput, **output;
66 |
67 | //----- Communication channel establishment ----------
68 | NetConnection* netConnection = new NetConnection(address, port+1);
69 | if (!netConnection->EstConnection(role)) {
70 | std::exit(EXIT_FAILURE);
71 | }
72 |
73 | //===============Feature selection ===================
74 | switch(sel_alg) {
75 | case SEL_HE:
76 | {
77 | cout << "**Runing oblivious selection subprotocol (homomorphic encryption)..." << endl;
78 | selction_HE(role, netConnection->commChannel, m_vFeatureVec, seclvl, numNodes, permutation, cmpCirc, m_shrCircOutput);
79 | }
80 | break;
81 | case SEL_GC:
82 | {
83 | cout << "**Runing oblivious selection subprotocol (garbled circuit)..." << endl;
84 | selction_GC(m_vFeatureVec, m_numNodes, permutation, cmpCirc, m_shrCircOutput);
85 | }
86 | break;
87 | }
88 | cout << "\n**Running oblivious comparison subprotocol (Yao's garbled circuit protocol)..." << endl;
89 | party->ExecCircuit();
90 |
91 | //------garbled key/colour bit per node--------
92 | uint8_t **circuitOutputKeys = (uint8_t**) malloc(sizeof(uint8_t*) * m_numNodes);
93 |
94 | for (i = 0;i < m_numNodes;i++) {
95 | circuitOutputKeys[i] = (uint8_t*) malloc(sizeof(uint8_t) * keysize);
96 | memcpy(circuitOutputKeys[i], cmpCirc->GetEvaluatedKey(m_shrCircOutput[i]->get_wire_id(0)), keysize);
97 | //cout << "circuitOutputKeys" << i << ": "; print(circuitOutputKeys[i], keysize);
98 | }
99 |
100 | ofstream serverOutputFile ("server_colour_bits.txt");
101 | ofstream clientOutputFile ("client_colour_bits.txt");
102 | BYTE *pi, colorBit;
103 | CSocket socket;
104 | uint16_t port = 7750;
105 |
106 | if (role == SERVER) {
107 | if (serverOutputFile.is_open()) {
108 | cout << "Writing server colour bits to file..." << endl;
109 | for (i = 0; i < numNodes; i++) {
110 | pi = permuteCirc->GetPi(m_shrCircOutput[i]->get_wire_id(0));
111 | serverOutputFile << int(*pi) << endl;
112 | }
113 | serverOutputFile.close();
114 | }
115 |
116 | BYTE *tmp, *R, *pi, colorBit;
117 | tmp = new uint8_t[keysize];
118 | R = new uint8_t[keysize];
119 | uint8_t **pointerKey, *binPermute;
120 | pointerKey = new uint8_t*[2*m_numNodes];
121 | binPermute = new uint8_t[m_numNodes];
122 |
123 | memcpy(R, ((YaoServerSharing*)sharings[S_YAO])->get_R().GetArr(), keysize); //R: global difference of garbled pairs
124 |
125 | for (i = 0; i < m_numNodes; i++){
126 | pointerKey[2*i] = new uint8_t[keysize];
127 | pointerKey[2*i+1] = new uint8_t[keysize];
128 | memcpy(tmp, permuteCirc->GetServerRandomKey(m_shrCircOutput[i]->get_wire_id(0)), keysize);
129 | pi = permuteCirc->GetPi(m_shrCircOutput[i]->get_wire_id(0));
130 | memcpy(binPermute + i, pi, sizeof(uint8_t));
131 | memcpy(pointerKey[2 * i], tmp, keysize);
132 | Xor(tmp, R, keysize);
133 | memcpy(pointerKey[2 * i + 1], tmp, keysize);
134 | }
135 |
136 | cout << "\n**Running oblivious path evaluation subprotocol (garbled decision tree)..." << endl;
137 | gettimeofday(&tbegin, NULL);
138 | m_cGarbledTree = create_garbled_tree(tree, seclvl, pointerKey, binPermute, permutation);
139 | gettimeofday(&tend, NULL);
140 |
141 | sendGarbledDT( netConnection->commChannel , m_numNodes, nodeSize, m_cGarbledTree );
142 | cout << "SERVER: Created garbled decision tree in: " << time_diff_microsec(tbegin, tend) << "us" << endl;
143 | } else { // role = client
144 | if (clientOutputFile.is_open()) {
145 | cout << "Writing client colour bits to file..." << endl;
146 | for (i = 0; i < numNodes; i++) {
147 | colorBit = circuitOutputKeys[i][keysize-1] & 0x01;
148 | clientOutputFile << int(colorBit) << endl;
149 | }
150 | clientOutputFile.close();
151 | }
152 | cout << "\n**Running oblivious path evaluation subprotocol (garbled decision tree)..." << endl;
153 | m_cGarbledTree = (uint8_t*) malloc(sizeof(uint8_t) *m_numNodes * nodeSize * 2);
154 | bool success = false;
155 | success = receiveGarbledDT(netConnection->commChannel, m_numNodes, nodeSize, m_cGarbledTree);
156 | if (success) {
157 | Eval_garbled_tree( m_cGarbledTree, circuitOutputKeys, m_numNodes, seclvl.symbits/8, nodeSize, seclvl);
158 | }
159 | }
160 |
161 | //TODO: free
162 | delete party;
163 | return 0;
164 | }
165 |
166 | uint8_t* create_garbled_tree(DecTree &dectree, seclvl seclvl, uint8_t** pointerKey, uint8_t* binPermute, uint16_t* permutation){
167 |
168 | crypto *crypt = new crypto(seclvl.symbits, (uint8_t*) const_seed);
169 | //cout << "seclvl.symbits: " << seclvl.symbits << endl;
170 | const int type = sizeof(uint8_t), nodeIdxSize = sizeof(uint16_t), keySize = seclvl.symbits/8; // Size * Byte
171 | const int size = type + nodeIdxSize + keySize; //1+2+16
172 | //cout << "data size: " << size << endl;
173 |
174 | // n: number of nodes, d: number of decision nodes
175 | uint16_t n = dectree.node_vec.size(), d = dectree.num_dec_nodes;
176 |
177 | //generate random numbers as keys to hash fuction
178 | uint8_t **nodeKey;
179 | nodeKey = new uint8_t*[d];
180 |
181 | for(int i = 0; i < d; i++){
182 | nodeKey[i] = new uint8_t[keySize];
183 | crypt->gen_rnd(nodeKey[i],keySize);
184 | //print(nodeKey[i],keySize);
185 | }
186 | //nodekey[0] = 0
187 | memset(nodeKey[0],0,keySize);
188 | //print(nodeKey[0],keySize);
189 |
190 | //create garbled decision tree
191 | garbldNode *garbledTree = new garbldNode[d];
192 | uint8_t *gTree = (uint8_t*) malloc(sizeof(uint8_t) * d * size * 2);
193 |
194 |
195 | //copy node data from tree
196 | uint64_t global_index = 0;
197 | uint16_t i,j, rindex , lindex;
198 | uint32_t length = 0;
199 | DecTree::Node* current_node;
200 |
201 | for(i = 0; i < dectree.num_dec_nodes; i++){
202 |
203 | current_node = dectree.decnode_vec[i];
204 | j = permutation[i];
205 | garbledTree[j].rnode = new uint8_t[size];
206 | garbledTree[j].lnode = new uint8_t[size];
207 | uint8_t *r = garbledTree[j].rnode, *l = garbledTree[j].lnode;
208 |
209 | if (current_node->right != current_node->left) { // non-dummy node
210 |
211 | //left node's data of node i in garbled Tree : [TYPE, PERMUTED INDEX, DELTA]
212 | lindex = ++global_index;
213 | if (!(current_node->left->leaf)){
214 | *l = 0x00; // type : decision
215 | memcpy(l+type, &(permutation[lindex]), nodeIdxSize); //nodeId
216 | memcpy(l+type+nodeIdxSize, nodeKey[permutation[lindex]], keySize); //nodeKey
217 | }
218 | else{
219 | *l = 0x01; // type : classification
220 | memcpy(l+type, &(current_node->left->classification), sizeof(uint64_t)); // Classification label
221 | memset(l+type+length, 0, size-(type+length));//Padding
222 |
223 | }
224 | //print(l,size);
225 |
226 | //right node:
227 | rindex = ++global_index;
228 | if (!(current_node->right->leaf)){
229 | *r = 0x00; // type : decision
230 | memcpy(r+type, &(permutation[rindex]), nodeIdxSize); //nodeId
231 | memcpy(r+type+nodeIdxSize, nodeKey[permutation[rindex]], keySize); // nodeKey
232 | }
233 | else{
234 | *r = 0x01; // type : classification
235 | memcpy(l+type, &(current_node->right->classification), sizeof(uint64_t)); // Classification label
236 | memset(l+type+length, 0, size-(type+length));//Padding
237 | }
238 | //print(r,size);
239 | } else {
240 |
241 | lindex = ++global_index;
242 | if (!(current_node->left->leaf)){
243 | *l = 0x00; // type : decision
244 | memcpy(l+type, &(permutation[lindex]), nodeIdxSize); //nodeId
245 | memcpy(l+type+nodeIdxSize, nodeKey[permutation[lindex]], keySize); //nodeKey
246 | }
247 | else{
248 | *l = 0x01; // type : classification
249 | memcpy(l+type, &(current_node->left->classification), sizeof(uint64_t)); // Classification label
250 | memset(l+type+length, 0, size-(type+length));//Padding
251 |
252 | }
253 | //print(l,size);
254 |
255 | //right node:
256 | rindex = lindex; //dummy node
257 | memcpy(r, l, size);
258 | //print(r,size);
259 | }
260 | }
261 |
262 | uint8_t *key, *ExpKey, colorBit;
263 | key = new uint8_t[keySize];
264 | ExpKey = new uint8_t[size];
265 |
266 | //cout << "Encrypted nodes:" << endl;
267 |
268 | for( i = 0;i < d;i++ ){
269 | colorBit = (pointerKey[2 * i][keySize-1]) & 0x01;
270 |
271 | //Encrypt left node
272 | memcpy(key, nodeKey[i], keySize);
273 | timeval tbegin, tend;
274 | gettimeofday(&tbegin, NULL);
275 |
276 | #ifdef AES_NOT_HASH
277 | uint8_t* one = {};
278 | crypt->encrypt(ExpKey, one, keySize);
279 | //crypt->encrypt(Xor(key, pointerKey[2 * i + (colorBit ^ binPermute[i])], keySize), ExpKey, one, keySize);
280 | //crypt->encrypt(Xor(key, pointerKey[2 * i + (colorBit ^ binPermute[i])], keySize), ExpKey, zero, keySize);
281 | #else
282 | crypt->hash(ExpKey, size, Xor(key, pointerKey[2 * i + (colorBit ^ binPermute[i])], keySize), keySize);
283 | #endif
284 |
285 | gettimeofday(&tend, NULL);
286 | //cout << "Hash/AES Time: " << ((tend.tv_sec-tbegin.tv_sec)*1000000 + tend.tv_usec - tbegin.tv_usec) << "us" << endl;
287 | //cout << "hash keys: ";print(ExpKey,size);
288 | Xor(garbledTree[i].lnode, ExpKey, size);
289 | //cout << "l node: ";print(garbledTree[i].lnode,size);
290 |
291 | //Encrypt right node
292 | memcpy(key, nodeKey[i], keySize);
293 |
294 | #ifdef AES_NOT_HASH
295 | crypt->encrypt(ExpKey, one, keySize);
296 | //crypt->encrypt(Xor(key, pointerKey[2 * i + !(colorBit ^ binPermute[i])], keySize), ExpKey, one, keySize);
297 | #else
298 | crypt->hash(ExpKey, size, Xor(key, pointerKey[2 * i + !(colorBit ^ binPermute[i])], keySize), keySize);
299 | #endif
300 |
301 | //cout << "hash keys: "; print(ExpKey,size);
302 | Xor(garbledTree[i].rnode, ExpKey, size);
303 | //cout << "r node: ";print(garbledTree[i].rnode,size);
304 |
305 |
306 | //swap nodes randomly
307 | if (binPermute[i]){
308 | swap(garbledTree[i].rnode, garbledTree[i].lnode);
309 | }
310 | memcpy(gTree+(2*i) * size, garbledTree[i].lnode, size);
311 | memcpy(gTree+(2*i + 1) * size, garbledTree[i].rnode, size);
312 | }
313 |
314 | //delete[] permutation;
315 | //delete[] garbledTree;
316 | return gTree;
317 |
318 | }
319 |
320 | int Eval_garbled_tree(uint8_t *garbledTree, uint8_t **keys, uint16_t d, uint32_t keysize, uint32_t msgsize, seclvl seclvl){
321 |
322 | crypto *crypt = new crypto(seclvl.symbits, (uint8_t*) const_seed);
323 | timeval tbegin, tend;
324 | uint8_t *nodekey, *data, colorBit;
325 | uint16_t i, nodeID = 0 ;
326 | string classlabel;
327 | nodekey = new uint8_t[keysize];
328 | data = new uint8_t[msgsize];
329 |
330 | gettimeofday(&tbegin, NULL);
331 | memset(nodekey, 0, keysize); //nodekey[0] = 0
332 | i = 0;
333 | while(1){
334 |
335 | #ifdef AES_NOT_HASH
336 | crypt->encrypt(Xor(nodekey, keys[i], keysize), data, one, keysize);
337 | #else
338 | crypt->hash(data, msgsize, Xor(nodekey, keys[i], keysize), keysize);
339 | #endif
340 |
341 | colorBit = keys[i][keysize-1] & 0x01;
342 | //Decrypting the currentnode
343 | if (colorBit = 0x00){
344 | Xor(data, garbledTree + (2*i)*msgsize, msgsize);
345 | } else {
346 | Xor(data, garbledTree + (2*i+1)*msgsize, msgsize);
347 | }
348 | //evaluating the decrypted node
349 | if(data[0]){ //classification node
350 | //cout << " retrieved classification label! "; //TODO: print the classification value
351 | break;
352 | } else { //Decision node
353 | memcpy( &i, data+1, sizeof(uint16_t));
354 | memcpy( nodekey, data+3, keysize);
355 | }
356 | }
357 |
358 | gettimeofday(&tend, NULL);
359 | printf("CLIENT: Evaluated garbled decision tree in: %.0lf us\n" , time_diff_microsec(tbegin , tend));
360 |
361 | delete[] nodekey;
362 | delete[] data;
363 | return 0;
364 | }
365 |
--------------------------------------------------------------------------------
/ABY_example/dectree/common/crypto_party/paillier_party.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | \file paillier_party.h
3 | \author masoud.naderpour@helsinki.fi
4 | \copyright ABY - A Framework for Efficient Mixed-protocol Secure Two-party Computation
5 | Copyright (C) 2019 Engineering Cryptographic Protocols Group, TU Darmstadt
6 | This program is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU Lesser General Public License as published
8 | by the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 | ABY is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | GNU Lesser General Public License for more details.
14 | You should have received a copy of the GNU Lesser General Public License
15 | along with this program. If not, see .
16 | \brief Paillier crypto
17 | */
18 |
19 | #include "paillier_party.h"
20 |
21 | #define CHECKCOMM 0
22 | #define DEBUG 0
23 | #define NETDEBUG 0
24 | #define WINDOWSIZE 50000 //maximum size of a network packet in Byte
25 |
26 | PaillierParty::PaillierParty(uint32_t PaillierBits, uint32_t readkey) {
27 |
28 | m_nShareLength = 104;
29 | m_nPaillierBits = PaillierBits;
30 | m_nBuflen = 2 * (PaillierBits / 8 ); //size of one ciphertext to send via network. Paillier uses 2n bits == 2n/8 bytes
31 |
32 | #if DEBUG
33 | std::cout << "Created party with " << PaillierBits << " key bits " << std::endl;
34 | #endif
35 |
36 | gmp_randinit_default(m_randstate);
37 | gmp_randseed_ui(m_randstate, rand());
38 |
39 | if (readkey) {
40 | if (!readKey()){
41 | std::cout << "No key file. Generating a new Paillier key." << std::endl;
42 | generateKey();
43 | storeKey();
44 | }
45 | } else {
46 | generateKey();
47 | }
48 | }
49 |
50 | bool PaillierParty::readKey() {
51 |
52 | char smod[5];
53 | char slbit[4];
54 | char name[40] = "paillier_key_";
55 | const char* div = "_";
56 | const char* ext = ".bin";
57 |
58 | sprintf(smod, "%d", m_nPaillierBits);
59 |
60 | strcat(name, smod);
61 | // strcat(name, div);
62 | strcat(name, ext);
63 |
64 | //printf("reading Paillier key from %s\n", name);
65 |
66 | /* allocate the new key structures */
67 | m_localpub = (paillier_pubkey_t*) malloc(sizeof(paillier_pubkey_t));
68 | m_prv = (paillier_prvkey_t*) malloc(sizeof(paillier_prvkey_t));
69 |
70 | FILE *fp;
71 | fp = fopen(name, "r");
72 |
73 | if(!fp) {
74 | //printf("Cannot find Paillier key's file!\n");
75 | return 0;
76 | }
77 |
78 | /* initialize our integers */
79 | mpz_init(m_localpub->n);
80 | mpz_init(m_localpub->n_squared);
81 | mpz_init(m_localpub->n_plusone);
82 | mpz_init(m_prv->lambda);
83 | mpz_init(m_prv->x);
84 |
85 | mpz_inp_raw(m_prv->lambda, fp);
86 | mpz_inp_raw(m_prv->x, fp);
87 | mpz_inp_raw(m_localpub->n, fp);
88 | mpz_inp_raw(m_localpub->n_squared, fp);
89 | mpz_inp_raw(m_localpub->n_plusone, fp);
90 |
91 | fclose(fp);
92 |
93 | m_localpub->bits = m_nPaillierBits;
94 |
95 | return 1;
96 | }
97 |
98 | void PaillierParty::storeKey(){
99 |
100 | FILE *fp;
101 |
102 | char smod[5];
103 | char slbit[4];
104 | char name[40] = "paillier_key_";
105 | const char* div = "_";
106 | const char* ext = ".bin";
107 |
108 | sprintf(smod, "%d", m_nPaillierBits);
109 |
110 | strcat(name, smod);
111 | // strcat(name, div);
112 | strcat(name, ext);
113 |
114 | //printf("writing Paillier key to %s\n", name);
115 |
116 | fp = fopen(name, "w");
117 |
118 | mpz_out_raw(fp, m_prv->lambda);
119 | mpz_out_raw(fp, m_prv->x);
120 | mpz_out_raw(fp, m_localpub->n);
121 | mpz_out_raw(fp, m_localpub->n_squared);
122 | mpz_out_raw(fp, m_localpub->n_plusone);
123 |
124 | fclose(fp);
125 | }
126 |
127 | void PaillierParty::generateKey() {
128 |
129 | paillier_keygen( m_nPaillierBits, &m_localpub, &m_prv, paillier_get_rand_devrandom );
130 |
131 | }
132 |
133 | /**
134 | * deletes party and frees keys and randstate
135 | */
136 | PaillierParty::~PaillierParty() {
137 |
138 | gmp_randclear(m_randstate);
139 | paillier_freeprvkey(m_prv);
140 | paillier_freepubkey(m_localpub);
141 | paillier_freepubkey(m_remotepub);
142 |
143 | }
144 |
145 | /**
146 | * exchanges private keys with other party via sock, pre-calculates fixed-base representation of remote pub-key
147 | */
148 | void PaillierParty::keyExchange(channel* &chan) {
149 |
150 | //send public key
151 | sendmpz_t(m_localpub->n, chan);
152 |
153 | //receive and complete public key
154 | m_remotepub = (paillier_pubkey_t*) malloc(sizeof(paillier_pubkey_t));
155 | mpz_inits(m_remotepub->n, m_remotepub->n_squared, m_remotepub->n_plusone, NULL);
156 |
157 | receivempz_t(m_remotepub->n, chan); //n
158 | complete_pubkey(m_remotepub);
159 | m_remotepub->bits = m_localpub->bits;
160 |
161 | #if NETDEBUG
162 | std::cout << "KX done. This pubkey: " << m_localpub->n << " remotekey: " << m_remotepub->n << std::endl;
163 | #endif
164 | }
165 |
166 |
167 | /**
168 | * encrypt values in the plaintext vector
169 | */
170 | bool PaillierParty::encrypt(vector &plaintexts, BYTE* &ciphertexts){
171 |
172 | paillier_plaintext_t tmp, tmp2;
173 | paillier_ciphertext_t res;
174 | mpz_inits(tmp.m, tmp2.m, res.c, NULL);
175 |
176 | for(int i = 0;i < plaintexts.size();i++){
177 |
178 | mpz_set_ui(tmp.m, plaintexts[i]);
179 |
180 | paillier_enc(&res, m_localpub, &tmp, paillier_get_rand_devrandom);
181 |
182 | mpz_export(ciphertexts + i * m_nBuflen, NULL, 1, 1, 1, 0, res.c);
183 |
184 | // paillier_dec(&tmp2, m_localpub, m_prv, &res);
185 |
186 | //gmp_printf ("feature%d (%Zd) decryption is (%ZX)\n", i, tmp.m, tmp2.m);
187 | }
188 |
189 | paillier_freeplaintext( &tmp );
190 | paillier_freeplaintext( &tmp2 );
191 | paillier_freeciphertext( &res );
192 | return 0;
193 | }
194 |
195 | /**
196 | * encrypts & sends a Vec of plaintexts
197 | */
198 | void PaillierParty::encSndRcvVec(e_role role, vector &plaintexts, mpz_t* &ciphertexts, channel* &chan){
199 |
200 |
201 | struct timespec start, end;
202 | //uint32_t shareBytes = 8;
203 | uint32_t offset = 0;
204 |
205 |
206 | BYTE *m_encSndBuf, *m_encRcvBuf;
207 | m_encSndBuf = (BYTE*) calloc(plaintexts.size() * m_nBuflen, 1);
208 | m_encRcvBuf = (BYTE*) calloc(plaintexts.size() * m_nBuflen, 1);
209 |
210 | // send & receive encrypted values
211 | int window = WINDOWSIZE;
212 | int tosend = m_nBuflen * plaintexts.size();
213 | offset = 0;
214 |
215 | if (role == CLIENT) {
216 |
217 | clock_gettime(CLOCK_MONOTONIC, &start);
218 | encrypt(plaintexts, m_encSndBuf);
219 | clock_gettime(CLOCK_MONOTONIC, &end);
220 | //printf("CLIENT: Encrypted feature vector in %.0lf ms \n\n", getMillies(start, end));
221 |
222 | while (tosend > 0) {
223 |
224 | window = min(window, tosend);
225 |
226 | chan->send(m_encSndBuf + offset, window);
227 | //chan->blocking_receive(m_encRcvBuf + offset, window);
228 |
229 | tosend -= window;
230 | offset += window;
231 | }
232 |
233 | } else {
234 |
235 | clock_gettime(CLOCK_MONOTONIC, &start);
236 | while (tosend > 0) {
237 |
238 | window = min(window, tosend);
239 |
240 | //chan->send(m_encSndBuf + offset, window);
241 | chan->blocking_receive(m_encRcvBuf + offset, window);
242 |
243 | tosend -= window;
244 | offset += window;
245 | }
246 | clock_gettime(CLOCK_MONOTONIC, &end);
247 | printf("SERVER: Received encrypted feature vector in %.0lf ms \n", getMillies(start, end));
248 |
249 | ciphertexts = (mpz_t*) calloc(plaintexts.size(), sizeof(mpz_t));
250 |
251 | for(int i = 0; i < plaintexts.size();i++){
252 |
253 | mpz_init(ciphertexts[i]);
254 | mpz_import(ciphertexts[i], m_nBuflen, 1, 1, 1, 0, m_encRcvBuf + i * m_nBuflen);
255 | //gmp_printf ("ciphertext %d is %Zx\n", i, ciphertexts[i]);
256 | }
257 | }
258 |
259 | free(m_encSndBuf);
260 | free(m_encRcvBuf);
261 | }
262 |
263 | void PaillierParty::mskSndRcvVec(e_role role, mpz_t* &CTs, mpz_t* &rndMsks, vector &selectionVec, mpz_t* &blindedInputsVec, channel* &chan){
264 |
265 | struct timespec start, end, startRndEnc, endRndEnc;
266 | double serverRndEncTime = 0; //time takes to blind the client's input
267 |
268 | mpz_t g_pow_m, rnd, tmp, packed_ct;
269 | mpz_inits(g_pow_m, rnd, tmp, packed_ct, NULL);
270 |
271 | uint32_t statisticalParam = 40;
272 |
273 | uint64_t n_batch, batch_size = m_localpub->bits / (sizeof(uint64_t)*8 + statisticalParam); // batch_size = bits / 104
274 |
275 | uint64_t numDecisionNodes = selectionVec.size();
276 |
277 | if (batch_size > numDecisionNodes)
278 | n_batch = 1;
279 | else if (numDecisionNodes % batch_size == 0)
280 | n_batch = numDecisionNodes / batch_size;
281 | else
282 | n_batch= numDecisionNodes / batch_size + 1;
283 |
284 | //std::cout << "Paillier key size: " << m_localpub->bits << "\tPacking " << batch_size << " ciphertexts in one." << std::endl;
285 |
286 | BYTE *m_encSndBuf, *m_encRcvBuf;
287 | int bufSize = n_batch * m_nBuflen;
288 | m_encSndBuf = (BYTE*) calloc(bufSize, 1);
289 | m_encRcvBuf = (BYTE*) calloc(bufSize, 1);
290 |
291 | int window = WINDOWSIZE;
292 | int tosend = m_nBuflen * n_batch;
293 | int offset = 0;
294 | uint64_t counter = 0;
295 |
296 | if (role == SERVER) {
297 |
298 | clock_gettime(CLOCK_MONOTONIC, &start);
299 | mpz_t* sel_enc_attr = (mpz_t*) malloc(selectionVec.size() * sizeof(mpz_t));
300 |
301 | //-------select and blind features------------
302 | for (int i = 0; i < selectionVec.size(); i ++)
303 | {
304 | mpz_init(sel_enc_attr[i]);
305 |
306 | clock_gettime(CLOCK_MONOTONIC, &startRndEnc);
307 | mpz_powm(g_pow_m, m_remotepub->n_plusone, rndMsks[i], m_remotepub->n_squared);
308 | clock_gettime(CLOCK_MONOTONIC, &endRndEnc);
309 | serverRndEncTime += getMillies(startRndEnc, endRndEnc);
310 |
311 | mpz_mul(sel_enc_attr[i], CTs[selectionVec[i]], g_pow_m); // blind the feature homomorphically
312 | mpz_mod(sel_enc_attr[i], sel_enc_attr[i] , m_remotepub->n_squared);
313 | }
314 |
315 | //-------Pack the ciphertexts------------
316 | counter = 0;
317 | for (int i = 0; i < n_batch; i++)
318 | {
319 | for (int j = 0; j < batch_size; j++)
320 | {
321 | if (j == 0) {
322 | mpz_set(packed_ct, sel_enc_attr[counter++]);
323 | continue;
324 | }
325 | mpz_ui_pow_ui(tmp, 2, 104*j);
326 | mpz_powm(tmp, sel_enc_attr[counter++], tmp, m_remotepub->n_squared); //shifting
327 | mpz_mul(packed_ct, packed_ct, tmp); // adding to the packed CT
328 | mpz_mod(packed_ct, packed_ct, m_remotepub->n_squared);
329 | if (counter == selectionVec.size())
330 | break;
331 | }
332 | mpz_export(m_encSndBuf + i * m_nBuflen, NULL, 1, 1, 1, 0, packed_ct); // embeds the packed ct in Snd buffer
333 | }
334 |
335 | clock_gettime(CLOCK_MONOTONIC, &end);
336 | std::cout << "SERVER: Encrypted random numbers in " << serverRndEncTime << " ms" << std::endl;
337 | //printf("SERVER: selected features in %.0lf ms \n\n", getMillies(start, end) - serverRndEncTime);
338 |
339 | //----- send & receive encrypted values---------
340 |
341 | while (tosend > 0) {
342 |
343 | window = min(window, tosend);
344 |
345 | chan->send(m_encSndBuf + offset, window);
346 | //chan->blocking_receive(m_encRcvBuf + offset, window);
347 |
348 | tosend -= window;
349 | offset += window;
350 | }
351 |
352 | } else { //CLIENT
353 |
354 | clock_gettime(CLOCK_MONOTONIC, &start);
355 | while (tosend > 0) {
356 |
357 | window = min(window, tosend);
358 |
359 | //chan->send(m_encSndBuf + offset, window);
360 | chan->blocking_receive(m_encRcvBuf + offset, window);
361 |
362 | tosend -= window;
363 | offset += window;
364 | }
365 | clock_gettime(CLOCK_MONOTONIC, &end);
366 | printf("CLIENT: Received blinded features in %.0lf ms \n", getMillies(start, end));
367 |
368 | //reconstructs the encrypted blinded values from the received raw data buffer
369 |
370 | clock_gettime(CLOCK_MONOTONIC, &start);
371 |
372 | blindedInputsVec = (mpz_t*) calloc(selectionVec.size(), sizeof(mpz_t)); //inputs to the substraction circuit in plaintext
373 |
374 | mpz_t mod;
375 | mpz_init(mod);
376 | mpz_ui_pow_ui(mod, 2, 104);
377 |
378 | paillier_plaintext_t rcv_packed_ct; mpz_init(rcv_packed_ct.m);
379 | paillier_ciphertext_t tmpCT; mpz_init(tmpCT.c);
380 |
381 | counter = 0;
382 | for (int i = 0; i < n_batch; i++)
383 | {
384 | mpz_import(tmpCT.c, m_nBuflen, 1, 1, 1, 0, m_encRcvBuf + i * m_nBuflen);
385 | paillier_dec(&rcv_packed_ct, m_localpub, m_prv, &tmpCT); // decryps the inputs here before returning the vec
386 |
387 | for (int j = 0; j < batch_size; j++)
388 | {
389 | mpz_init(blindedInputsVec[counter]);
390 |
391 | mpz_mod(blindedInputsVec[counter], rcv_packed_ct.m, mod);
392 |
393 | mpz_fdiv_q(rcv_packed_ct.m, rcv_packed_ct.m, mod);
394 |
395 | counter++;
396 |
397 | if (counter == selectionVec.size())
398 | break;
399 | }
400 | }
401 |
402 | clock_gettime(CLOCK_MONOTONIC, &end);
403 | printf("CLIENT: Depacked & decrypted blinded features in %.0lf ms \n", getMillies(start, end));
404 |
405 | #if DEBUG
406 | for(int i = 0;i < mapping.size();i++) {
407 | std::cout << "random mask: " << rndMsks[i] << " \tfeature " << mapping[i] << "\tmasked value: "; gmp_printf("%Zd", blindedInputsVec[i]); std::cout << std::endl;
408 | }
409 | #endif
410 |
411 | }
412 |
413 | //paillier_freeplaintext(&tmp);
414 | //paillier_freeplaintext(&rnd);
415 | //TODO: free unnecessary bufs;
416 | }
417 |
418 | void PaillierParty::printBuf(BYTE* b, uint32_t len) {
419 | for (uint32_t i = 0; i < len; i++) {
420 | printf("%02x.", *(b + i));
421 | }
422 | std::cout << std::endl;
423 | }
424 |
425 | /**
426 | * send one mpz_t to sock
427 | */
428 | void PaillierParty::sendmpz_t(mpz_t t, channel* chan, BYTE * buf) {
429 |
430 | //clear upper bytes of the buffer, so tailing bytes are zero
431 | for (int i = mpz_sizeinbase(t, 256); i < m_nBuflen; i++) {
432 | *(buf + i) = 0;
433 | }
434 |
435 | #if NETDEBUG
436 | std::cout << mpz_sizeinbase(t, 256) << " vs. " << m_nBuflen << std::endl;
437 | #endif
438 |
439 | mpz_export(buf, NULL, -1, 1, 1, 0, t);
440 |
441 | //send bytes of t
442 | chan->send(buf, (uint64_t) m_nBuflen);
443 |
444 | #if NETDEBUG
445 | std::cout << std::endl << "SEND" << std::endl;
446 | for (int i = 0; i < m_nBuflen; i++) {
447 | printf("%02x.", *(buf + i));
448 | }
449 |
450 | std::cout << std::endl << "sent: " << t << " with len: " << m_nBuflen << " should have been " << mpz_sizeinbase(t, 256) << std::endl;
451 | #endif
452 | }
453 |
454 | /**
455 | * receive one mpz_t from sock. t must be initialized.
456 | */
457 | void PaillierParty::receivempz_t(mpz_t t, channel* chan, BYTE * buf) {
458 | chan->blocking_receive(buf, (uint64_t) m_nBuflen);
459 | mpz_import(t, m_nBuflen, -1, 1, 1, 0, buf);
460 |
461 | #if NETDEBUG
462 | std::cout << std::endl << "RECEIVE" << std::endl;
463 | for (int i = 0; i < m_nBuflen; i++) {
464 | printf("%02x.", *(buf + i));
465 | }
466 |
467 | std::cout << "received: " << t << " with len: " << m_nBuflen << std::endl;
468 | #endif
469 | }
470 |
471 | /**
472 | * send one mpz_t to sock, allocates buffer
473 | */
474 | void PaillierParty::sendmpz_t(mpz_t t, channel* chan) {
475 | unsigned int bytelen = mpz_sizeinbase(t, 256);
476 | BYTE* arr = (BYTE*) malloc(bytelen);
477 | mpz_export(arr, NULL, 1, 1, 1, 0, t);
478 |
479 | //send byte length
480 | chan->send((BYTE*) &bytelen, sizeof(bytelen));
481 |
482 | //send bytes of t
483 | chan->send(arr, (uint64_t) bytelen);
484 |
485 | free(arr);
486 | #if NETDEBUG
487 | std::cout << "sent: " << t << " with len: " << bytelen << std::endl;
488 | #endif
489 | }
490 |
491 | /**
492 | * receive one mpz_t from sock. t must be initialized.
493 | */
494 | void PaillierParty::receivempz_t(mpz_t t, channel* chan) {
495 | unsigned int bytelen;
496 |
497 | //reiceive byte length
498 | chan->blocking_receive((BYTE*) &bytelen, sizeof(bytelen));
499 | BYTE* arr = (BYTE*) malloc(bytelen);
500 |
501 | //receive bytes of t
502 | chan->blocking_receive(arr, (uint64_t) bytelen);
503 | mpz_import(t, bytelen, 1, 1, 1, 0, arr);
504 |
505 | free(arr);
506 | #if NETDEBUG
507 | std::cout << "received: " << t << " with len: " << bytelen << std::endl;
508 | #endif
509 | }
510 |
--------------------------------------------------------------------------------
/XCMP_files/benchmark_gt/hhh.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | \file hhh.cpp
3 | \author kiss@encrypto.cs.tu-darmstadt.de
4 | \copyright HHH protocol
5 | Copyright (C) 2019 Cryptography and Privacy Engineering Group, TU Darmstadt
6 | This program is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU Affero General Public License as published
8 | by the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 | This program is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | GNU Affero General Public License for more details.
14 | You should have received a copy of the GNU Affero General Public License
15 | along with this program. If not, see .
16 | \brief HHH protocol of Tai et al. implemented using the mcl library and the secure comparison implementation from https://github.com/fionser/XCMP
17 | */
18 |
19 | #include
20 | #include
21 | #include
22 | #include
23 | #include
24 | #include
25 | #include
26 | #include
27 | #include
28 | #include
29 | #include
30 | #include
31 | #include
32 | #include
33 | #include
34 | #include
35 | #include
36 |
37 | #include "network.hpp"
38 | #include "dectree.hpp"
39 | #define PROT 0 //0 for HHH, 1 for HH(G), 2 for (GG)/(HG)H where the parts in brackets are executed outside of this code before/after
40 | #define DT 0 //0 for wine", 1 for iris, 2 for breast cancer, 3 for digits, 4 for diabetes, 5 for linnerud, 6 for boston
41 |
42 | typedef mcl::FpT<> Fp;
43 | typedef mcl::FpT Zn; // use ZnTag because Zn is different class with Fp
44 | typedef mcl::EcT Ec;
45 | typedef mcl::ElgamalT