├── .gitignore
├── POC_code
├── README.md
├── bin
│ ├── blind_rsa_test
│ └── blind_rsa_test.dSYM
│ │ └── Contents
│ │ ├── Info.plist
│ │ └── Resources
│ │ └── DWARF
│ │ └── blind_rsa_test
├── include
│ ├── alice.h
│ ├── alice_client.h
│ ├── alice_interface.h
│ ├── bin.h
│ ├── blind_rsa.h
│ ├── bob.h
│ ├── constants.h
│ ├── ec.h
│ ├── encrypt.h
│ ├── hash.h
│ ├── memory.h
│ ├── network.h
│ ├── random.h
│ ├── scc.h
│ ├── scc_interface.h
│ ├── scc_wrapper_interface.h
│ ├── signer.h
│ ├── signer_interface.h
│ ├── timer.h
│ ├── tumbler.h
│ ├── tx.h
│ ├── utility.h
│ ├── zmq.hpp
│ └── zmq_addon.hpp
├── keys
│ ├── EC_private_alice.pem
│ ├── EC_private_bob.pem
│ ├── EC_private_test.pem
│ ├── EC_private_tumbler.pem
│ ├── EC_private_tumbler_main.pem
│ ├── EC_public_alice.pem
│ ├── EC_public_bob.pem
│ ├── EC_public_test.pem
│ ├── EC_public_tumbler.pem
│ ├── EC_public_tumbler_main.pem
│ ├── private_2048_test.pem
│ ├── private_2048_tumbler.pem
│ ├── public_2048_test.pem
│ └── public_2048_tumbler.pem
├── makefile
├── python
│ ├── tx.py
│ ├── tx_server.py
│ └── tx_test.py
├── requirements.txt
├── src
│ ├── alice.cpp
│ ├── alice_client.cpp
│ ├── alice_client_test.cpp
│ ├── bob.cpp
│ ├── bob_client.cpp
│ ├── crypto
│ │ ├── blind_rsa.cpp
│ │ ├── ec.cpp
│ │ ├── encrypt.cpp
│ │ ├── hash.cpp
│ │ └── random.cpp
│ ├── scc.cpp
│ ├── signer.cpp
│ ├── signer_server.cpp
│ ├── test
│ │ ├── bin_test.cpp
│ │ ├── blind_rsa_test.cpp
│ │ ├── ec_test.cpp
│ │ ├── encrypt_test.cpp
│ │ ├── hash_test.cpp
│ │ ├── scc_test.cpp
│ │ └── utility_test.cpp
│ ├── tumbler.cpp
│ ├── tumbler_server.cpp
│ ├── tx.cpp
│ └── utility
│ │ ├── bin.cpp
│ │ ├── generate_rsa.cpp
│ │ ├── memory.cpp
│ │ ├── network.cpp
│ │ ├── timer.cpp
│ │ └── utility.cpp
└── ubuntu_setup.sh
├── README.md
└── reference_implementation
├── README.md
├── requirements.txt
├── setup.py
├── tests
├── __init__.py
├── test_crypto.py
├── test_data
│ ├── client_ec_keys
│ │ ├── ec_client.pem
│ │ ├── ec_privkey.der
│ │ └── ec_pubkey.bin
│ ├── server_ec_keys
│ │ ├── ec_privkey.der
│ │ ├── ec_pubkey.bin
│ │ └── ec_server.pem
│ └── server_rsa_keys
│ │ ├── private_test.pem
│ │ └── public_test.pem
├── test_ec.py
├── test_puzzle_promise.py
├── test_puzzle_solver.py
└── test_rsa.py
├── tumblebit
├── __init__.py
├── crypto.py
├── ec.py
├── puzzle_promise.py
├── puzzle_solver.py
├── rsa.py
└── tx.py
└── ubuntu_setup.sh
/.gitignore:
--------------------------------------------------------------------------------
1 | .cache
2 | *.egg-info
3 | __pycache__
4 |
--------------------------------------------------------------------------------
/POC_code/README.md:
--------------------------------------------------------------------------------
1 | # Proof of Concept
2 |
3 |
4 | POC TumbleBit as an untrusted [classic tumbler](https://en.wikipedia.org/wiki/Cryptocurrency_tumbler).
5 |
6 | ----
7 | ### Warning
8 |
9 | This is proof-of-concept code and is not intended and should not be used for production.
10 |
11 | * Don't use the default keys if you plan on posting transactions on testnet or mainnet.
12 | * We have not audited this code for vulnerabilities and we are actively fixing memory corruption vulnerabilities.
13 | * There are known memory leaks in the networking code of the servers.
14 | * The servers currently do not handle more than one client at a time.
15 | * There are known [side channel attacks on ECDSA in openssl](https://www.tau.ac.il/~tromer/mobilesc/).
16 |
17 | ----
18 | ### Dependencies
19 |
20 | - LibreSSL Version 2.3.4 or higher
21 | - Boost
22 | - ZMQ
23 | - Bitcoind (Optional: for posting transactions)
24 | - Python dependencies: ```pip install -r requirements.txt```
25 | + python-bitcoinlib
26 | + simplejson
27 | + pyzmq
28 | + pycrypto
29 |
30 | For ubuntu, you can install the dependencies by running:
31 | ```
32 | ./ubuntu_setup.sh
33 | ```
34 |
35 | ### Building
36 |
37 | Default build setting is to have the clients and
38 | the servers on the same machine.
39 |
40 | If you want to run the servers on different machines,
41 | change TUMBLER_SERVER_SOCKET and SIGNER_SERVER_SOCKET in
42 | include/constants.h to point to the ip of your machine.
43 |
44 | ##### Note
45 | Should be in the **POC_code** directory
46 |
47 | All resulting binaries will be in the **bin** directory
48 |
49 | - Clients & Servers:
50 | + ```make```
51 | - Servers:
52 | + ```make tumbler_server```
53 | + ```make signer_server```
54 | - Clients:
55 | + ```make bob_client```
56 | + ```make alice_client_test```
57 | - Only runs the puzzle-solver protocol
58 | - Tests: Tests are located in src/test
59 | + ```make test_name```
60 |
61 | ### Running
62 |
63 | - Full Tumbler run:
64 | + ```./python/tx_server.py```
65 | + ```./bin/tumbler_server```
66 | + ```./bin/signer_server```
67 | + ```./bin/bob_client```
68 | - Just the Puzzle Solver protocol:
69 | + ```./python/tx_server.py```
70 | + ```./bin/signer_server```
71 | + ```./bin/alice_client_test```
72 |
--------------------------------------------------------------------------------
/POC_code/bin/blind_rsa_test:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BUSEC/TumbleBit/55829dc75c36554e710e723dedb510d62a57ca0c/POC_code/bin/blind_rsa_test
--------------------------------------------------------------------------------
/POC_code/bin/blind_rsa_test.dSYM/Contents/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | English
7 | CFBundleIdentifier
8 | com.apple.xcode.dsym.blind_rsa_test
9 | CFBundleInfoDictionaryVersion
10 | 6.0
11 | CFBundlePackageType
12 | dSYM
13 | CFBundleSignature
14 | ????
15 | CFBundleShortVersionString
16 | 1.0
17 | CFBundleVersion
18 | 1
19 |
20 |
21 |
--------------------------------------------------------------------------------
/POC_code/bin/blind_rsa_test.dSYM/Contents/Resources/DWARF/blind_rsa_test:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BUSEC/TumbleBit/55829dc75c36554e710e723dedb510d62a57ca0c/POC_code/bin/blind_rsa_test.dSYM/Contents/Resources/DWARF/blind_rsa_test
--------------------------------------------------------------------------------
/POC_code/include/alice.h:
--------------------------------------------------------------------------------
1 |
2 | #ifndef _alice_h
3 | #define _alice_h
4 |
5 | #include "assert.h"
6 |
7 | // Local
8 | #include "scc.h"
9 | #include "ec.h"
10 | #include "encrypt.h"
11 | #include "tx.h"
12 |
13 | class Alice
14 | {
15 |
16 | protected:
17 | RSA* rsa;
18 | EC_KEY* ec_key;
19 |
20 | // EC
21 | Bin *public_key;
22 | Bin *tumbler_public_key;
23 |
24 | // TX
25 | Bin* address;
26 | Bin* tumbler_address;
27 |
28 | Bin* escrow_redeem_script;
29 | Bin* escrow_funding_tx_id;
30 | Bin* escrow_lock_time;
31 | Bin* escrow_P2SH;
32 | Bin* escrow_signature;
33 |
34 | Bin* preimage_redeem_script;
35 | Bin* preimage_funding_tx_id;
36 | Bin* preimage_lock_time;
37 | Bin* preimage_sighash;
38 | Bin* preimage_P2SH;
39 | Bin* preimage_signature;
40 |
41 | Bin *y;
42 | Bin *y_sk;
43 |
44 | std::vector blinded_set;
45 | std::vector R; // Indices of real set
46 | std::vector F; // Indices of fake set
47 |
48 | std::vector real_rpk;
49 | std::vector real_keys;
50 | std::vector real_blinds;
51 |
52 | std::vector fake_r;
53 | std::vector fake_rpk;
54 |
55 | std::vector C; // Encrypted signatures : Form IV||encrypted_sig
56 | std::vector H; // Key hashes
57 |
58 | // Methods
59 | void setup(); // Creates the blinded set
60 | bool sign(Bin* tx, Bin* serial_sig); // EC Sign TX
61 |
62 |
63 | public:
64 | int rsa_len;
65 |
66 | // Constructors & Destructors
67 | Alice(Bin* y);
68 | Alice();
69 | ~Alice();
70 |
71 |
72 | // Sets
73 | void set_rsa(Bin* public_rsa);
74 | void set_party_address(Bin* address);
75 | void set_party_pubkey(Bin* public_key);
76 | void set_real_keys(std::vector& keys);
77 | void set_C(std::vector& c);
78 | void set_H(std::vector& h);
79 |
80 | // Gets
81 | Bin* get_pubkey();
82 | Bin* get_y_sk();
83 |
84 | Bin* get_preimage_redeem_script();
85 | Bin* get_preimage_signature();
86 | Bin* get_preimage_P2SH();
87 |
88 | Bin* get_escrow_redeem_script();
89 | Bin* get_escrow_funding_tx_id();
90 | Bin* get_escrow_signature();
91 | Bin* get_escrow_P2SH();
92 |
93 |
94 | std::vector get_R();
95 | std::vector get_F();
96 |
97 | std::vector* get_blinded_set();
98 | std::vector* get_fake_blinds();
99 | std::vector* get_real_blinds();
100 |
101 | // Methods
102 |
103 | bool setup_escrow_tx();
104 | bool setup_preimage_tx();
105 | bool verify_preimage_signature(Bin* signature);
106 |
107 | /*!
108 | * Verify that the keys decrypt the fake values
109 | *
110 | * \param[in] k Keys for fake values
111 | *
112 | * \return true on success, false on error.
113 | */
114 | bool verify_keys(std::vector& k);
115 |
116 | /*!
117 | * Get a valid decrytion and save it in y_sk.
118 | * real_keys should be set.
119 | *
120 | *
121 | * \return true on success, false on error.
122 | */
123 | bool get_decryption();
124 |
125 |
126 | };
127 |
128 | #endif
129 |
--------------------------------------------------------------------------------
/POC_code/include/alice_client.h:
--------------------------------------------------------------------------------
1 |
2 | #ifndef _alice_client_h
3 | #define _alice_client_h
4 |
5 | #include "assert.h"
6 |
7 | // Local
8 | #include "alice.h"
9 | #include "scc_interface.h"
10 | #include "network.h"
11 |
12 | /*!
13 | * Runs the client (Alice) for the scc protocol
14 | * to get a decryption of y and save in y_sk.
15 | *
16 | * \param[in] y An item encrypted with rsa
17 | * \param[out] y_sk A decryption of the item
18 | *
19 | * \return true on success, false on error.
20 | */
21 | bool get_decryption(Bin* y, Bin* y_sk);
22 |
23 |
24 | #endif
25 |
--------------------------------------------------------------------------------
/POC_code/include/alice_interface.h:
--------------------------------------------------------------------------------
1 |
2 | #ifndef _alice_interface_h
3 | #define _alice_interface_h
4 |
5 | #include "assert.h"
6 |
7 | // Local
8 | #include "scc.h"
9 | #include "ec.h"
10 | #include "encrypt.h"
11 |
12 |
13 | #include "zmq.hpp"
14 |
15 | class Alice_Interface
16 | {
17 | protected:
18 |
19 | Bin* y;
20 |
21 | std::vector C; // Commitments
22 | std::vector H; // Key hashes
23 |
24 |
25 | std::vector R; // Indices of real set
26 | std::vector F; // Indices of fake set
27 |
28 | std::vector fake_keys;
29 | std::vector real_keys;
30 |
31 | // TX related
32 | Bin* signer_pubkey;
33 | Bin* redeem_script;
34 | Bin* funding_tx_id;
35 | Bin* serial_real_keys;
36 | Bin* tx_fulfill;
37 |
38 | bool phase_0;
39 | bool phase_1;
40 | bool phase_2;
41 | bool phase_3;
42 | bool phase_4;
43 |
44 | void init(){
45 | phase_0 = false;
46 | phase_1 = false;
47 | phase_2 = false;
48 | phase_3 = false;
49 | phase_4 = false;
50 |
51 | signer_pubkey = NULL;
52 | redeem_script = NULL;
53 | funding_tx_id = NULL;
54 | tx_fulfill = NULL;
55 | serial_real_keys = NULL;
56 |
57 | }
58 |
59 | /*
60 | * Phase 0:
61 | * 1/ Receive:
62 | - Signer's public key
63 | */
64 | virtual bool exchange_public_key(){return false;};
65 |
66 | /*
67 | * Phase 1:
68 | * 1/ Generate blinded set (Init an Alice instance)
69 | * 2/ Send:
70 | - blinded_set
71 | * 3/ Receive:
72 | - C
73 | - H
74 | */
75 | virtual bool commitment(){return false;};
76 |
77 | /*
78 | * Phase 2:
79 | * 1/ Send:
80 | - F
81 | - fake_blinds
82 | * 3/ Receive :
83 | - Fake value keys
84 | * 3 / Verify fake keys (verify_keys())
85 | */
86 | virtual bool verify_fakes(){return false;};
87 |
88 | /*
89 | * Phase 3:
90 | * 1/ Get redeem_script & fund_tx_id from python
91 | * 1.1/ Send:
92 | - Alice's EC public key
93 | - Signer's EC public key
94 | - Real Key preimages
95 | * 1.2/ Receive:
96 | - redeem_script
97 | - fund_tx_id
98 | * 2/ Send:
99 | - redeem_script
100 | - funding_TX_id
101 | - y
102 | - real_blinds
103 | * 3/ Receive:
104 | - tx_fulfill
105 | */
106 | virtual bool verify_reals(){return false;};
107 |
108 |
109 | /*
110 | * Start SCC protocol
111 | */
112 | virtual bool start(){return false;};
113 |
114 |
115 |
116 | public:
117 |
118 | /*
119 | * Phase 4:
120 | * 1/ Get real keys from python
121 | * 1.1/ Send:
122 | - tx_fulfill
123 | * 1.2/ (Opt) Send number of keys - Default if 15
124 | * 1.3/ Receive:
125 | - real keys in serial form
126 | * 1.4/ Alice deserialize keys into vector
127 | * 2/ Get a valid decryption(y_sk) of y (get_decryption())
128 | * 3/ Return:
129 | - y_sk
130 | */
131 | virtual Bin* get_decryption(){return NULL;};
132 |
133 | // Constructors & Destructors
134 |
135 | virtual ~Alice_Interface(){
136 |
137 | // delete y;
138 |
139 | if (phase_0){
140 | delete signer_pubkey;
141 | }
142 |
143 | if (phase_1){
144 | free_Bins(C);
145 | free_Bins(H);
146 |
147 | }
148 |
149 | if (phase_2){
150 | free_Bins(fake_keys);
151 | }
152 |
153 | if (phase_3){
154 | delete redeem_script;
155 | delete funding_tx_id;
156 | delete tx_fulfill;
157 | }
158 |
159 | if (phase_4){
160 | delete serial_real_keys;
161 | free_Bins(real_keys);
162 | }
163 |
164 |
165 | };
166 |
167 |
168 | };
169 |
170 | #endif
171 |
--------------------------------------------------------------------------------
/POC_code/include/bin.h:
--------------------------------------------------------------------------------
1 | #ifndef _bin_h
2 | #define _bin_h
3 |
4 | #include
5 | #include
6 |
7 | class Bin
8 | {
9 | public:
10 | unsigned char * data;
11 | int len;
12 |
13 | // Constructors & Destructors
14 | Bin(){};
15 | Bin(int len_c);
16 | Bin(int len_c, unsigned char *data_c);
17 | Bin(const Bin &bin);
18 |
19 | ~Bin();
20 |
21 | // Methods
22 | unsigned char * serialize();
23 | void print();
24 |
25 | bool operator== (const Bin& b) const;
26 | bool operator!= (const Bin& b);
27 | };
28 |
29 | template
30 | struct pointer_equal
31 | {
32 | const T* to_find;
33 |
34 | bool operator()(const T* other) const
35 | {
36 | return *to_find == *other;
37 | }
38 | };
39 |
40 | // True if item is not null and len > 1
41 | bool defined(Bin* item);
42 | void delete_bin(Bin* item);
43 |
44 | #endif
45 |
--------------------------------------------------------------------------------
/POC_code/include/blind_rsa.h:
--------------------------------------------------------------------------------
1 | #ifndef _blind_rsa_h
2 | #define _blind_rsa_h
3 |
4 | #include
5 | #include
6 | #include
7 |
8 | #include "bin.h"
9 | #include "memory.h"
10 | #include "utility.h"
11 |
12 | /*!
13 | * Notes:
14 | * - Key path to public and private keys are in
15 | * PUBLIC & PRIVATE
16 | * - RSA keys are blinded when loaded to protect
17 | * against timing attacks
18 | */
19 |
20 | #define PUBLIC "./keys/public_"
21 | #define PRIVATE "./keys/private_"
22 | #define EXT ".pem"
23 |
24 | //============================================================================
25 |
26 | /*!
27 | * Generates an RSA public/private key pair of size n bits
28 | *
29 | * \param[in] bits size of RSA key in bits
30 | * \param[in] public_suffix suffix to be used in filename/path to save public key
31 | * \param[in] private_suffix suffix to be used in filename/path to save private key
32 | * \param[out] rsa RSA public key.
33 | *
34 | * \return true on sucess
35 | */
36 | bool generate_rsa_key(int bits, char* public_suffix, char* private_suffix);
37 |
38 |
39 | /*!
40 | * Loads RSA public key of size n bits and turns on key blinding.
41 | *
42 | * \param[in] bits size of RSA key in bits
43 | * \param[in] suffix suffix to be used in path to search for key
44 | *
45 | * \return a pointer to the RSA struct
46 | */
47 | RSA * get_public_rsa(int bits, char *suffix);
48 |
49 | /*!
50 | * Loads RSA public and private keys of size n bits and turns on key blinding.
51 | *
52 | * \param[in] bits size of RSA key in bits
53 | * \param[in] suffix suffix to be used in path to search for key
54 | *
55 | * \return a pointer to the RSA struct
56 | */
57 | RSA * get_private_rsa(int bits, char *suffix);
58 |
59 | //============================================================================
60 |
61 | /*!
62 | * Setup BN_Blinding structure.
63 | *
64 | * \param[in] rsa RSA public key.
65 | *
66 | * \return initalized BN_Blinding structure, NULL on error.
67 | */
68 | BN_BLINDING * setup_blinding(RSA *rsa);
69 |
70 | /*!
71 | * Setup BN_Blinding structure using r.
72 | *
73 | * \param[in] rsa RSA public key.
74 | * \param[in] r Random value of length RSA_size(rsa)
75 | *
76 | * \return initalized BN_Blinding structure, NULL on error.
77 | */
78 | BN_BLINDING * setup_blinding(RSA *rsa, Bin* r);
79 |
80 |
81 | /*!
82 | * Blind data and store result in unblind
83 | *
84 | * \param[in] blinding BN_Blinding initialized struct.
85 | * \param[in] msg Input data.
86 | * \param[out] blinded Output buffer.
87 | *
88 | * \return true on success, false on error.
89 | */
90 | bool blind(BN_BLINDING * blinding, Bin* msg, Bin* blinded);
91 |
92 | /*!
93 | * Unblind data and store result in unblind
94 | *
95 | * \param[in] blinding BN_Blinding initialized struct.
96 | * \param[in] rsa RSA public key.
97 | * \param[in] msg Input data.
98 | * \param[out] unblinded Output buffer.
99 | *
100 | * \return true on success, false on error.
101 | */
102 | bool unblind(BN_BLINDING * blinding, Bin* msg, Bin* unblinded);
103 |
104 | /*!
105 | * Unblind data and store result in reverted
106 | *
107 | * \param[in] rsa RSA public key.
108 | * \param[in] message Blinded data
109 | * \param[in] A The blind that was applied to the message
110 | * \param[out] reverted data with blind removed
111 | *
112 | * \return true on success, false on error.
113 | */
114 | bool revert_blind(RSA *rsa, Bin* message, Bin* A, Bin* reverted);
115 |
116 | //============================================================================
117 |
118 | /*!
119 | * Verify RSA Signature.
120 | *
121 | * \param[in] rsa RSA public key.
122 | * \param[in] msg Input data.
123 | * \param[out] sig Output buffer.
124 | *
125 | * \return true on success, false on error.
126 | */
127 | bool verify(RSA *rsa, Bin* msg, Bin* sig);
128 |
129 | /*!
130 | * Sign Message using RSA.
131 | *
132 | * \param[in] rsa RSA public key.
133 | * \param[in] msg Input data.
134 | * \param[out] sig Output buffer.
135 | *
136 | * \return true on success, false on error.
137 | */
138 | bool sign(RSA *rsa, Bin* msg, Bin* sig);
139 |
140 |
141 | #endif
142 |
--------------------------------------------------------------------------------
/POC_code/include/bob.h:
--------------------------------------------------------------------------------
1 |
2 | #ifndef _bob_h
3 | #define _bob_h
4 |
5 | #include "assert.h"
6 | #include
7 |
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 |
14 | #include "scc.h"
15 | #include "ec.h"
16 | #include "tx.h"
17 | #include "utility.h"
18 | #include "encrypt.h"
19 |
20 | class Bob
21 | {
22 |
23 | protected:
24 | RSA* rsa;
25 |
26 | EC_KEY *ec_server;
27 | EC_KEY *ec_bob;
28 | Bin* pubkey;
29 |
30 | bool verified;
31 |
32 |
33 | //=============================================
34 | //======= TX Related
35 | //=============================================
36 |
37 | // Receive
38 | Bin* funding_tx_id;
39 | Bin* redeem_script;
40 |
41 | Bin* tx_fulfill;
42 |
43 | std::vector real_tx_addresses; // M real TX
44 | std::vector real_tx_hashes; // Hashed transactions - Hash256
45 |
46 | // Won't be sending the fakes
47 | std::vector fake_tx; // The r's for the N fake transaction
48 | std::vector fake_tx_hashes; // H(00...00||r's)
49 |
50 | //=============================================
51 | //======= Protocol
52 | //=============================================
53 |
54 | Bin* y_sk;
55 | Bin* W;
56 | Bin* W_blind;
57 |
58 | std::vector tx_set; // Superset of real_tx_hashes and fake_tx_hashes randomly permuted
59 | std::vector R; // Indices for real tx in tx_set
60 | std::vector F; // Indices for fake tx in tx_set
61 |
62 | Bin* salt;
63 | Bin* h_r;
64 | Bin* h_f;
65 |
66 | std::vector Z;
67 | std::vector commitments;
68 | std::vector quotients;
69 | std::vector epsilons;
70 |
71 | //=============================================
72 | //======= Functions
73 | //=============================================
74 |
75 | bool blind_epsilon();
76 |
77 | // Verification
78 | bool verify_quotients(); // Verify that the quotients validate with Z
79 | bool verify_signatures(std::vector epsilon); // Verify the fake signatures
80 | bool verify_epsilon();
81 | // Recovery
82 | bool recover_epsilons(); // Recover epsilons from Z using redeemed epsilon
83 | Bin* recover_signature(int* index); // Recover one valid signature
84 |
85 | // TX
86 | void generate_tx_set(); // Generates the set of fake and real txs
87 | bool create_txs(); // Uses tx_offer to generate real tx's
88 | bool submit_tx(); // Submits tx_fulfill
89 |
90 |
91 | // Other
92 | bool sign(Bin* tx, Bin* serial_sig); // EC Sign TX
93 | void write_state();
94 |
95 |
96 | public:
97 | int rsa_len; // Size of RSA modulus in bytes
98 |
99 | // Constructors & Destructors
100 | Bob();
101 | ~Bob();
102 |
103 | // Sets
104 | void set_funding_tx_id(Bin* id);
105 | void set_redeem_script(Bin* script);
106 | void set_party_pubkey(Bin* serial);
107 | void set_rsa(Bin* public_rsa);
108 | void set_recovered_epsilon(Bin* epsilon);
109 |
110 | // Gets
111 | std::vector get_R();
112 | std::vector get_F();
113 | std::vector* get_tx_set();
114 | std::vector* get_fake_tx();
115 | Bin* get_pubkey();
116 | Bin* get_W();
117 | Bin* get_tx_fulfill();
118 | Bin* get_salt();
119 | Bin* get_h_r();
120 | Bin* get_h_f();
121 |
122 | /*!
123 | * Verify data recieved from intermediary
124 | *
125 | * \param[in] zs Encrypted epsilons.
126 | * \param[in] commitment
127 | * \param[in] epsilon Random numbers used to generate encryption keys used
128 | * on the EC signatures. For Fake tx.
129 | * \param[in] quotients Vector of epsilon quotients. For Real tx.
130 | *
131 | * \return true on successful verification
132 | */
133 | bool verify_recieved_data(
134 | std::vector zs,
135 | std::vector commitment,
136 | std::vector epsilon,
137 | std::vector quotient);
138 |
139 |
140 | // Post fulfill TX
141 | // Recovers epsiolons and a signature in the process
142 | bool post_tx();
143 |
144 |
145 | };
146 |
147 | #endif
148 |
--------------------------------------------------------------------------------
/POC_code/include/constants.h:
--------------------------------------------------------------------------------
1 | #ifndef _constants_h
2 | #define _constants_h
3 |
4 | #include
5 | #include
6 |
7 | // SCC
8 | static const unsigned int M = 15 ; // Number of reals
9 | static const unsigned int N = 285; // Number of fakes
10 |
11 | // SCC Wrapper
12 | static const int K = 42 ; // SCC Wrapper K reals and K fakes
13 |
14 | // Length of key used in commitments
15 | static const unsigned int KEY_LEN = 16; // bytes
16 |
17 | // Hash lengths
18 | static const int HASH_512 = SHA512_DIGEST_LENGTH; // bytes
19 | static const int HASH_256 = SHA256_DIGEST_LENGTH; // bytes
20 | static const int HASH_160 = RIPEMD160_DIGEST_LENGTH; // bytes
21 |
22 | // Testnet Addresses
23 | const char TUMBLER_ADDRESS[35] = "mzaMTvKBDiYoqkHaDz3w7AmHHETHEQKUiW";
24 | const char ALICE_ADDRESS[35] = "mvESmmYToV1dugQjNdXvA8C8ra6Q2Hyu7d";
25 |
26 | // Only change IP - Not port
27 | const char TUMBLER_SERVER_SOCKET[21] = "tcp://localhost:5557";
28 | const char SIGNER_SERVER_SOCKET[21] = "tcp://localhost:5558";
29 |
30 | #endif
31 |
--------------------------------------------------------------------------------
/POC_code/include/ec.h:
--------------------------------------------------------------------------------
1 | #ifndef _ec_h
2 | #define _ec_h
3 |
4 | #include
5 |
6 | #include
7 | #include
8 |
9 | #include "bin.h"
10 | #include "memory.h"
11 | #include "utility.h"
12 | #include "constants.h"
13 |
14 | /*!
15 | * Generates an Elliptic Curve (EC) public/private key pair
16 | * using secp256k1 curve.
17 | *
18 | * \param[in] public_suffix suffix used in filename/path to save public key
19 | * \param[in] private_suffix suffix used in filename/path to save private key
20 | *
21 | * \return true on sucess
22 | */
23 | bool generate_EC_key(const char* public_suffix, const char* private_suffix);
24 |
25 |
26 | /*!
27 | * Gets the EC private or public key from key_path
28 | *
29 | * \param[in] key_path Path to .pem file
30 | * \param[in] private_key Bool indicating to fetch private key or not
31 | *
32 | * \return EC_KEY * on success, NULL on failure
33 | */
34 | EC_KEY * get_ec_key(const char *key_path, bool private_key);
35 |
36 |
37 | /*!
38 | * Gets the EC private or public key by suffix
39 | *
40 | * \param[in] suffix key suffix
41 | * \param[in] private_key Bool indicating to fetch private key or not
42 | *
43 | * \return EC_KEY * on success, NULL on failure
44 | */
45 | EC_KEY * get_ec_key_by_suffix(const char *suffix, bool private_key);
46 |
47 |
48 | /*!
49 | * Gets the EC key using secret
50 | *
51 | * \param[in] secret Secret to use
52 | *
53 | * \return EC_KEY * on success, NULL on failure
54 | */
55 | EC_KEY * get_key_from_secret(Bin* secret);
56 |
57 | //============================================================================
58 |
59 |
60 | /*!
61 | * Signs a message using ECDSA
62 | *
63 | * \param[in] key EC key
64 | * \param[in] hash Message to sign
65 | *
66 | * \return ECDSA_SIG * on success, NULL on failure
67 | */
68 | ECDSA_SIG* EC_sign(EC_KEY * eckey, Bin* hash);
69 |
70 | /*!
71 | * Verifies a ECDSA signed message
72 | *
73 | * \param[in] key EC key
74 | * \param[in] hash Message to sign
75 | * \param[in] signature ECDSA signature
76 | *
77 | * \return true when message successfully verifies, false on failure
78 | */
79 | bool EC_verify (EC_KEY * eckey, Bin* hash, ECDSA_SIG* signature);
80 |
81 | /*!
82 | * Converts ECDSA sig to a bitcoin compatible signature -- lower s value
83 | *
84 | * \param[in/out] sig ECDSA signature
85 | * \param[in] key EC key
86 | *
87 | * \return true when message successfully verifies, false on failure
88 | */
89 | bool convert_sig_to_standard_der(ECDSA_SIG *sig, EC_KEY *key);
90 |
91 | //============================================================================
92 |
93 | /*!
94 | * Serializes a ECDSA_SIG
95 | * Allocates a pointer that saves the serial representation that should freed later.
96 | *
97 | * \param[in] sig ECDSA signature
98 | * \param[out] serial Bin to save result
99 | *
100 | * \return true on success
101 | */
102 | bool serialize_ec_signature(ECDSA_SIG *sig, Bin* serial);
103 | bool serialize_ec_signature_der(ECDSA_SIG *sig, Bin* serial);
104 |
105 | /*!
106 | * Deserializes a ECDSA_SIG
107 | *
108 | * \param[in] serial Serial representation of ECDSA signature
109 | *
110 | * \return ECDSA_SIG * on success, NULL on failure
111 | */
112 | ECDSA_SIG *deserialize_ec_signature(Bin* serial);
113 | ECDSA_SIG *deserialize_ec_signature_der(Bin* serial);
114 |
115 | //============================================================================
116 |
117 |
118 | /*!
119 | * Serializes a ec public key.
120 | *
121 | * \param[in] key ECDSA signature
122 | * \param[out] serial Bin to save result
123 | *
124 | * \return true on success
125 | */
126 | bool serialize_ec_publickey(EC_KEY *key, Bin* serial);
127 |
128 |
129 | /*!
130 | * Deserializes a public ec key
131 | *
132 | * \param[in] serial Serial representation of ec public key
133 | *
134 | * \return EC_KEY* on success, NULL on failure
135 | */
136 | EC_KEY* deserialize_ec_publickey(Bin* serial);
137 |
138 |
139 | /*!
140 | * Note: Might not be needed
141 | * Serializes a ec private key.
142 | * Allocates a pointer that saves the serial representation that should freed later.
143 | *
144 | * \param[in] key EC private key
145 | * \param[out] serial Bin to save result
146 | *
147 | * \return true on success
148 | */
149 | bool serialize_ec_privatekey(EC_KEY *key, Bin* serial);
150 |
151 |
152 | #endif
153 |
--------------------------------------------------------------------------------
/POC_code/include/encrypt.h:
--------------------------------------------------------------------------------
1 | #ifndef _encrypt_h
2 | #define _encrypt_h
3 |
4 | #include "bin.h"
5 | #include "memory.h"
6 | #include "random.h"
7 | #include "constants.h"
8 |
9 | #include
10 |
11 | //============================================================================
12 |
13 | /*!
14 | * Encryptes message
15 | *
16 | * NOTE: Default encrypt uses xor and assumes message is 512 bits
17 | *
18 | * \param[in] plaintext Input data.
19 | * \param[out] key Key used in
20 | * \param[out] ciphertext Encrypted output iv||cipher
21 | *
22 | * \return true on success
23 | */
24 | bool encrypt(Bin* plain_text, Bin *key, Bin* cipher_text); // XOR
25 | bool encrypt_chacha(Bin* plain_text, Bin *key, Bin* cipher_text);
26 |
27 | /*!
28 | * Decryptes message
29 | *
30 | * \param[in] key Key
31 | * \param[in] ciphertext Encrypted data in form iv||cipher
32 | * \param[out] plaintext Decrypted text
33 | *
34 | * \return true on success
35 | */
36 | bool decrypt(Bin* cipher_text, Bin *key, Bin* plain_text); // XOR
37 | bool decrypt_chacha(Bin* cipher_text, Bin *key, Bin* plain_text);
38 |
39 | //============================================================================
40 |
41 | /*!
42 | * Encrypts/Decryptes message using xor
43 | * Assumes message and key have the same length.
44 | *
45 | * \param[in] m Message to encrypt
46 | * \param[in] k Key to use
47 | * \param[out] len Length of message and key
48 | *
49 | * \return true on success
50 | */
51 | unsigned char * XOR_enc_dec(Bin* m, Bin* k, int len);
52 |
53 | /*!
54 | * Encrypts/Decryptes message using chacha
55 | *
56 | * \param[out] out Result stored in out
57 | * \param[in] in Message to use
58 | * \param[in] key Key to use
59 | * \param[in] iv IV to use
60 | *
61 | * \return true on success
62 | */
63 | bool chacha(Bin* out, Bin* in, Bin* key, Bin* iv);
64 |
65 | //============================================================================
66 | #endif
67 |
--------------------------------------------------------------------------------
/POC_code/include/hash.h:
--------------------------------------------------------------------------------
1 | #ifndef _hash_h
2 | #define _hash_h
3 |
4 | #include
5 | #include
6 |
7 | #include "bin.h"
8 | #include "memory.h"
9 | #include "constants.h"
10 |
11 | /*!
12 | * Compute Full Domain Hash.
13 | *
14 | * \param[in] rsa RSA public key.
15 | * \param[in] msg Input data.
16 | * \param[in] hash Hash function.
17 | *
18 | * \return pointer to the msg hash, NULL on error.
19 | */
20 | Bin* full_domain_hash(RSA *rsa, Bin* msg, const EVP_MD *hash);
21 |
22 | /*!
23 | * Compute SHA256(SHA256(msg))
24 | *
25 | * \param[in] msg Input data.
26 | *
27 | * \return pointer to the msg hash, NULL on error.
28 | */
29 | Bin* hash256(Bin* msg);
30 |
31 | /*!
32 | * Compute hmac SHA256 of msg.
33 | *
34 | * \param[in] msg Input data.
35 | *
36 | * \return pointer to the msg hash, NULL on error.
37 | */
38 | Bin* hmac256(Bin* msg, Bin* key);
39 |
40 | #endif
41 |
--------------------------------------------------------------------------------
/POC_code/include/memory.h:
--------------------------------------------------------------------------------
1 | #ifndef _memory_h
2 | #define _memory_h
3 |
4 | // Local
5 | #include "bin.h"
6 |
7 | // C
8 | #include
9 | // #include
10 | #include
11 | #include
12 |
13 | // C++
14 | #include
15 | #include
16 |
17 | // SSL
18 | #include
19 |
20 |
21 | void tfree(void *ptr);
22 | void* tmalloc(size_t size);
23 |
24 |
25 | /*!
26 | * Frees BN_BLINDING structs pointed to in the vector
27 | *
28 | * \param[int] b A vector of BN_BLINDING structs
29 | *
30 | */
31 | void free_blinds(std::vector b);
32 |
33 | /*!
34 | * Frees Bin objects pointed to in the vector
35 | *
36 | * \param[int] bins A vector of Bin pointers
37 | *
38 | */
39 | void free_Bins(std::vector bins);
40 |
41 | int timingsafe_memcmp(const void *b1, const void *b2, size_t len);
42 |
43 |
44 | #endif
45 |
--------------------------------------------------------------------------------
/POC_code/include/network.h:
--------------------------------------------------------------------------------
1 | #ifndef _network_h
2 | #define _network_h
3 |
4 | #include
5 |
6 | #include "zmq.hpp"
7 |
8 | #include "scc.h"
9 |
10 | // Interrupt handeler
11 | static inline void s_signal_handler (int signal_value)
12 | {
13 | }
14 |
15 | static inline void s_catch_signals (void)
16 | {
17 | struct sigaction action;
18 | action.sa_handler = s_signal_handler;
19 | action.sa_flags = 0;
20 | sigemptyset (&action.sa_mask);
21 | sigaction (SIGINT, &action, NULL);
22 | sigaction (SIGTERM, &action, NULL);
23 | };
24 |
25 | void receive(zmq::socket_t &socket, std::vector& msgs);
26 |
27 | void send(zmq::socket_t &socket, std::vector& msgs);
28 |
29 | #endif
30 |
--------------------------------------------------------------------------------
/POC_code/include/random.h:
--------------------------------------------------------------------------------
1 | #ifndef _random_h
2 | #define _random_h
3 |
4 | #include "bin.h"
5 | #include "memory.h"
6 | #include "utility.h"
7 | #include
8 |
9 | /*!
10 | * Generates a random number of bits length
11 | *
12 | * \param[in] bits bits to generate
13 | *
14 | * \return a random number of n bits
15 | */
16 | unsigned char * get_random(int bits);
17 |
18 | /*!
19 | * Generates a random number of bits length less than n
20 | *
21 | * \param[in] bits bits to generate
22 | * \param[in] n A BIGNUM
23 | *
24 | * \return a random number of n bits
25 | */
26 | unsigned char * get_random(int bits, BIGNUM *n);
27 |
28 | #endif
29 |
--------------------------------------------------------------------------------
/POC_code/include/scc.h:
--------------------------------------------------------------------------------
1 |
2 | #ifndef _scc_h
3 | #define _scc_h
4 |
5 | #include "utility.h"
6 | #include "blind_rsa.h"
7 |
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 |
14 | //============================================================================
15 |
16 | /*!
17 | * Applies blinds to message
18 | *
19 | * \param[in] message A message to blind
20 | * \param[in] blinds A vector of initilized BN_BLINDING structs.
21 | * \param[out] blinded A vector that will hold the blinded m's.
22 | *
23 | * \return true on success, false on error.
24 | */
25 | bool apply_blinds(Bin* message, std::vector &blinds, std::vector &blinded);
26 |
27 | /*!
28 | * Removes the blinds from the messages in blinded
29 | *
30 | * \param[out] blinded A vector that holds blinded messages.
31 | * \param[in] m_len Length of the blinded message.
32 | * \param[in] blinds A vector of initilized BN_BLINDING structs.
33 | * \param[out] blinded A vector that will hold the unblinded messages.
34 | *
35 | * \return true on success, false on error.
36 | */
37 | bool remove_blinds(std::vector &blinded, int len, std::vector &blinds,
38 | std::vector &unblinded);
39 |
40 | /*!
41 | * Generate blinding factors
42 | *
43 | * \param[in] rsa RSA public key.
44 | * \param[in] n Number of blinds to generate
45 | * \param[out] blinds A vector to store the initilized BN_BLINDING structs.
46 | *
47 | * \return true on success, false on error.
48 | */
49 | bool create_blinds(RSA * rsa, int n, std::vector &blinds);
50 |
51 | //============================================================================
52 |
53 |
54 | /*!
55 | * Finds the indices of the elements of the "what" vector in "in" vector
56 | *
57 | * \param[in] in The main vector
58 | * \param[in] what The subvector to find the indices for
59 | * \param[out] indices A vector of indices for what
60 | *
61 | * \return true on success, false on error.
62 | */
63 | bool find_indices(std::vector &in, std::vector &what, std::vector &indices);
64 |
65 | //============================================================================
66 |
67 | /*!
68 | * Serializes a vector of size n with items of len
69 | *
70 | * \param[out] serial Serial representation
71 | * \param[in] vec Vector to store results in
72 | * \param[in] n Number of items
73 | * \param[in] len Length of items
74 | *
75 | * \return true on success, false on error.
76 | */
77 | bool serialize_vector(Bin* serial, std::vector& vec, int n, int len);
78 |
79 |
80 | /*!
81 | * Deserializes to a vector of size n with items of len
82 | *
83 | * \param[in] serial Serial representation
84 | * \param[out] vec Vector to store results in
85 | * \param[in] n Number of items
86 | * \param[in] len Length of items
87 | *
88 | * \return true on success, false on error.
89 | */
90 | bool deserialize_vector(Bin* serial, std::vector& vec, int n, int len);
91 |
92 |
93 | /*!
94 | * Serializes a integer vector of size n
95 | *
96 | * \param[out] serial Serial representation
97 | * \param[in] vec Vector to store results in
98 | * \param[in] n Number of items
99 | *
100 | * \return true on success, false on error.
101 | */
102 | bool serialize_int_vector(Bin* serial, std::vector& vec, int n);
103 |
104 |
105 | /*!
106 | * Deserializes to an integer vector of size N
107 | *
108 | * \param[in] serial Serial representation
109 | * \param[out] vec Vector to store results in
110 | * \param[in] n Number of items
111 | *
112 | * \return true on success, false on error.
113 | */
114 | bool deserialize_int_vector(Bin* serial, std::vector& vec, int n);
115 |
116 | //============================================================================
117 | #endif
118 |
--------------------------------------------------------------------------------
/POC_code/include/scc_interface.h:
--------------------------------------------------------------------------------
1 |
2 | #ifndef _scc_interface_h
3 | #define _scc_interface_h
4 |
5 | #include "assert.h"
6 |
7 | // Local
8 | #include "scc.h"
9 | #include "ec.h"
10 | #include "encrypt.h"
11 | #include "constants.h"
12 | #include "tx.h"
13 |
14 | class SCC_Interface
15 | {
16 | protected:
17 |
18 | Bin* y;
19 |
20 | std::vector C; // Commitments
21 | std::vector H; // Key hashes
22 |
23 |
24 | std::vector R; // Indices of real set
25 | std::vector F; // Indices of fake set
26 |
27 | std::vector fake_keys;
28 | std::vector real_keys;
29 |
30 | // TX related
31 | Bin* signer_pubkey;
32 | Bin* alice_pubkey;
33 |
34 | Bin* redeem_script;
35 | Bin* funding_tx_id;
36 | Bin* serial_real_keys;
37 | Bin* tx_fulfill;
38 |
39 | bool phase_0;
40 | bool phase_1;
41 | bool phase_2;
42 | bool phase_4;
43 |
44 | void init(){
45 | phase_0 = false;
46 | phase_1 = false;
47 | phase_2 = false;
48 | phase_4 = false;
49 |
50 | }
51 |
52 | /*
53 | * Phase 0:
54 | * Alice:
55 | * 1/ Receive:
56 | * - Signer's public key
57 | *
58 | * Signer:
59 | * 1/ Send:
60 | * - public key
61 | */
62 | virtual bool exchange_public_key(){return false;};
63 |
64 | /*
65 | * Phase 1:
66 | * Alice
67 | * 1/ Generate blinded set (Init an Alice instance)
68 | * 2/ Send:
69 | * - blinded_set
70 | * 3/ Receive:
71 | * - C
72 | * - H
73 | *
74 | * Signer:
75 | * 1/ Receive:
76 | * - blinded_set
77 | * 2/ Sign blinded set & encrypts sigs (sign_blinded_set())
78 | * 3/ Send:
79 | * - C
80 | * - H
81 | */
82 | virtual bool commitment(){return false;};
83 |
84 | /*
85 | * Phase 2:
86 | * Alice:
87 | * 1/ Send:
88 | * - F
89 | * - R
90 | * - fake_blinds
91 | * 2/ Receive :
92 | * - Fake value keys
93 | * 3 / Verify fake keys (verify_keys())
94 | *
95 | * Signer:
96 | * 1/ Receive:
97 | * - F
98 | * - R
99 | * - fake_blinds
100 | * 2/ Verify fake values (verify_fakes())
101 | * 3/ Send:
102 | * - Fake value keys
103 | */
104 | virtual bool verify_fakes(){return false;};
105 |
106 | /*
107 | * Phase 3:
108 | * Alice:
109 | * 1/ Get redeem_script & fund_tx_id from python
110 | * 1.1/ Send:
111 | * - Alice's EC public key
112 | * - Signer's EC public key
113 | * - Real Key preimages
114 | * 1.2/ Receive:
115 | * - redeem_script
116 | * - fund_tx_id
117 | * 2/ Send:
118 | * - redeem_script
119 | * - funding_TX_id
120 | * - y
121 | * - real_blinds
122 | * 3/ Receive:
123 | * - tx_fulfill
124 | *
125 | * Signer:
126 | * 1/ Receive:
127 | * - redeem_script
128 | * - funding_TX_id
129 | * - y
130 | * - real_blinds
131 | * 2/ Verify real values (verify_reals())
132 | * 3/ Get TX fulfill from python
133 | * 3.1/ Send:
134 | * - redeem_script
135 | * - address
136 | * - funding_TX_id
137 | * 3.2/ Receive:
138 | * - raw_tx
139 | * - sig_hash
140 | * 3.3/ Send:
141 | * - real Keys
142 | * - signed SigHash
143 | * - Raw_TX
144 | * - redeem_script
145 | * 3.4/ Receive: - tx_fulfill
146 | * 4/ Send:
147 | * - tx_fulfill
148 | */
149 | virtual bool verify_reals(){return false;};
150 |
151 |
152 | /*
153 | * Phase 4:
154 | * Alice only:
155 | * 1/ Get real keys from python
156 | * 1.1/ Send:
157 | * -tx_fulfill
158 | * 1.2/ (Opt) Send number of keys - Default if 15
159 | * 1.3/ Receive:
160 | * -real keys in serial form
161 | * 1.4/ Alice deserialize keys into vector
162 | * 2/ Get a valid decryption(y_sk) of y (get_decryption())
163 | * 3/ Return:
164 | * - y_sk
165 | */
166 | virtual bool get_decryption_from_tx(){return false;};
167 |
168 |
169 |
170 | public:
171 |
172 |
173 | virtual Bin* get_decryption(){return NULL;};
174 |
175 | /*
176 | * Start SCC protocol
177 | */
178 | virtual bool start(){return false;};
179 |
180 | // Constructors & Destructors
181 |
182 | virtual ~SCC_Interface(){
183 |
184 | if (phase_0){
185 | delete signer_pubkey;
186 | }
187 |
188 | if (phase_1){
189 | free_Bins(C);
190 | free_Bins(H);
191 |
192 | }
193 |
194 | if (phase_2){
195 | free_Bins(fake_keys);
196 | }
197 |
198 |
199 | if (phase_4){
200 | free_Bins(real_keys);
201 | }
202 |
203 |
204 | };
205 |
206 |
207 | };
208 |
209 | #endif
210 |
--------------------------------------------------------------------------------
/POC_code/include/scc_wrapper_interface.h:
--------------------------------------------------------------------------------
1 |
2 | #ifndef _scc_wrapper_interface_h
3 | #define _scc_wrapper_interface_h
4 |
5 | #include "assert.h"
6 |
7 | // Local
8 | #include "scc.h"
9 |
10 | class SCC_Wrapper_Interface
11 | {
12 | protected:
13 | std::vector C; // Commitments
14 | std::vector Z; // Key hashes
15 |
16 | std::vector fake;
17 | std::vector quotients;
18 | std::vector fake_epsilons;
19 |
20 |
21 | std::vector R; // Indices of real set
22 | std::vector F; // Indices of fake set
23 |
24 | // TX related
25 | Bin* payer_pubkey;
26 | Bin* redeemer_pubkey;
27 |
28 | Bin* redeem_script;
29 | Bin* funding_tx_id;
30 |
31 |
32 | /*
33 | * Phase 0:
34 | * Bob:
35 | * 1/ Send:
36 | * - public key
37 | * 2/ Receive:
38 | * - Tumbler's RSA public key
39 | * - Tumbler's EC public key
40 | * - redeem_script
41 | * - funding_tx_id
42 | *
43 | * Tumbler:
44 | * 1/ Receive:
45 | * - Bob's EC public key
46 | * 2/ Create TX_offer
47 | * 3/ Send:
48 | * - public key
49 | * - redeem_script
50 | * - funding_tx_id
51 | */
52 | virtual bool exchange(){return false;};
53 |
54 | /*
55 | * Phase 1:
56 | * Bob:
57 | * 1/ Send:
58 | * - tx_set
59 | * 2/ Receive:
60 | * - C
61 | * - Z
62 | *
63 | * Tumbler:
64 | * 1/ Receive:
65 | * - tx_set
66 | * 2/ Sign tx_set set
67 | * 3/ Send:
68 | * - C
69 | * - Z
70 | */
71 | virtual bool commitment(){return false;};
72 |
73 | /*
74 | * Phase 2:
75 | * Bob:
76 | * 1/ Send:
77 | * - R
78 | * - F
79 | * - fake_tx's
80 | * 2/ Receive :
81 | * - fake epsilon's
82 | * - quotients
83 | * 3 / Verify fake epsilon's
84 | * 4 / Verify quotients
85 | *
86 | * Tumbler:
87 | * 1/ Receive:
88 | * - R
89 | * - F
90 | * - fake_tx's
91 | * 2/ Verify fake tx's
92 | * 3/ Send:
93 | * - fake epsilon's
94 | * - quotients
95 | */
96 | virtual bool verify(){return false;};
97 |
98 | /*
99 | * Phase 3:
100 | * Bob:
101 | * 1/ Send Alice encrypted epsiolon -- Z_0
102 | * 2/ Recieve decryption -- epsiolon_0
103 | * 3/ Recover epsiolons
104 | * 4/ Recover valid signature
105 | * 5/ post tx
106 | */
107 | virtual bool post(){return false;};
108 |
109 |
110 |
111 | public:
112 |
113 | /*
114 | * Start SCC Wrapper protocol
115 | */
116 | virtual bool start(){return false;};
117 |
118 |
119 | };
120 |
121 | #endif
122 |
--------------------------------------------------------------------------------
/POC_code/include/signer.h:
--------------------------------------------------------------------------------
1 |
2 | #ifndef _signer_h
3 | #define _signer_h
4 |
5 | #include "assert.h"
6 | #include
7 |
8 | // Local
9 | #include "scc.h"
10 | #include "ec.h"
11 | #include "encrypt.h"
12 | #include "tx.h"
13 |
14 |
15 | class Signer
16 | {
17 |
18 | protected:
19 | RSA* rsa;
20 | Bin* rsa_pub;
21 |
22 | // EC
23 | EC_KEY *key;
24 | Bin *public_key;
25 |
26 | // Flags
27 | bool signed_values;
28 | bool verified_fakes;
29 | bool verified_real;
30 |
31 | std::vector blinded_set;
32 | std::vector R; // Indices of real set
33 | std::vector F; // Indices of fake set
34 |
35 | std::vector C; // Encrypted signatures : Form IV||encrypted_sig
36 | std::vector K; // Encryption keys
37 | std::vector H; // Key hashes
38 |
39 |
40 | // TX
41 | Bin* tumbler_address;
42 |
43 | Bin* escrow_redeem_script;
44 | Bin* escrow_funding_tx_id;
45 | Bin* escrow_party_signature;
46 |
47 | Bin* preimage_P2SH;
48 | Bin* preimage_redeem_script;
49 | Bin* preimage_funding_tx_id;
50 | Bin* preimage_party_signature;
51 | Bin* escrow_preimage_signature;
52 |
53 | Bin* fund_preimage_tx_fulfill;
54 | Bin* preimage_tx_fulfill;
55 | Bin* escrow_tx_fulfill;
56 |
57 |
58 | std::vector real_keys; // Keys used on real set
59 | std::vector fake_keys; // Keys used on fake set
60 |
61 | void write_state();
62 | bool ec_sign(Bin* serial_sig, Bin* sig_hash);
63 |
64 | public:
65 | int rsa_len;
66 |
67 | // Constructors & Destructors
68 | Signer();
69 | ~Signer();
70 |
71 | // Gets
72 | Bin* get_rsa();
73 | Bin* get_pubkey();
74 | Bin* get_escrow_preimage_signature();
75 | std::vector* get_C();
76 | std::vector* get_H();
77 | std::vector* get_fake_keys();
78 | std::vector* get_real_keys();
79 |
80 | // Sets
81 | void set_preimage_redeem_script(Bin* redeem_script);
82 | void set_preimage_signature(Bin* signature);
83 | void set_preimage_P2SH(Bin* address);
84 |
85 | void set_escrow_redeem_script(Bin* redeem_script);
86 | void set_escrow_funding_tx_id(Bin* funding_tx_id);
87 | void set_escrow_signature(Bin* signature);
88 |
89 | // Methods
90 |
91 | bool spend_escrow_tx();
92 | bool spend_preimage_tx();
93 | bool spend_escrow_preimage_tx();
94 | bool sign_escrow_preimage_tx();
95 |
96 | /*!
97 | * Signs blinded set using rsa private key
98 | *
99 | * \param[in] blinded_set set to sign
100 | *
101 | * \return true on success, false on error.
102 | */
103 | bool sign_blinded_set(std::vector blinded_set);
104 |
105 | /*!
106 | * Verify values claimed to be fake
107 | *
108 | * \param[in] randoms The randoms used in fakes
109 | * \param[in] newF Indices of fake items
110 | *
111 | * \return true on success, false on error.
112 | */
113 | bool verify_fakes(std::vector randoms, std::vector newF);
114 |
115 | /*!
116 | * Verify that real values all unblind to one value, y.
117 | *
118 | * \param[in] y The value the reals should ublind to
119 | * \param[in] blinds The blinds applied to y
120 | * \param[in] newR Indices of Real items
121 | *
122 | * \return true on success, false on error.
123 | */
124 | bool verify_reals(Bin* y, std::vectorblinds, std::vector newR);
125 |
126 |
127 | };
128 |
129 | #endif
130 |
--------------------------------------------------------------------------------
/POC_code/include/signer_interface.h:
--------------------------------------------------------------------------------
1 |
2 | #ifndef _signer_interface_h
3 | #define _signer_interface_h
4 |
5 | #include "assert.h"
6 |
7 | // Local
8 | #include "scc.h"
9 | #include "ec.h"
10 | #include "encrypt.h"
11 |
12 | class Signer_Interface
13 | {
14 |
15 | protected:
16 |
17 | std::vector blinded_set;
18 |
19 | // Blinds
20 | std::vector fake_blinds;
21 | std::vector real_blinds;
22 |
23 | std::vector R; // Indices of real set
24 | std::vector F; // Indices of fake set
25 |
26 |
27 | // Encrypted episolon
28 | Bin* y;
29 |
30 |
31 | // TX related
32 | Bin* redeem_script;
33 | Bin* funding_tx_id;
34 | Bin* sig_hash;
35 | Bin* raw_tx;
36 | Bin* tx_fulfill;
37 |
38 | bool phase_0;
39 | bool phase_1;
40 | bool phase_2;
41 | bool phase_3;
42 |
43 | /*
44 | * Phase 0:
45 | * 1/ Send:
46 | - public key
47 | */
48 | virtual bool exchange_public_key();
49 |
50 | /*
51 | * Phase 1:
52 | * 1/ Receive:
53 | - blinded_set
54 | * 2/ Sign blinded set & encrypts sigs (sign_blinded_set())
55 | * 3/ Send:
56 | - C
57 | - H
58 | */
59 | virtual bool commitment();
60 |
61 |
62 | /*
63 | * Phase 2:
64 | * 1/ Receive:
65 | - F
66 | - fake_blinds
67 | * 2/ Verify fake values (verify_fakes())
68 | * 3/ Send:
69 | - Fake value keys
70 | */
71 | virtual bool verify_fakes();
72 |
73 |
74 |
75 | /*
76 | * Phase 3:
77 | * 1/ Receive:
78 | - redeem_script
79 | - funding_TX_id
80 | - y
81 | - real_blinds
82 | * 2/ Verify real values (verify_reals())
83 | * 3/ Get TX fulfill from python
84 | * 3.1/ Send:
85 | - redeem_script
86 | - address
87 | - funding_TX_id
88 | * 3.2/ Receive:
89 | - raw_tx
90 | - sig_hash
91 | * 3.3/ Send:
92 | - real Keys
93 | - signed SigHash
94 | - Raw_TX
95 | - redeem_script
96 | * 3.4/ Receive: - tx_fulfill
97 | * 4/ Send:
98 | - tx_fulfill
99 | */
100 | virtual bool verify_reals();
101 |
102 |
103 |
104 | public:
105 | /*
106 | * Start SCC protocol
107 | */
108 | virtual bool start();
109 |
110 | ~Signer_Interface(){
111 |
112 | if (phase_1){
113 | free_Bins(blinded_set);
114 | }
115 |
116 | if (phase_2){
117 | free_Bins(fake_blinds);
118 | }
119 |
120 | if (phase_3){
121 |
122 | free_Bins(real_blinds);
123 |
124 | delete y;
125 | delete raw_tx;
126 | delete sig_hash;
127 | delete redeem_script;
128 | delete funding_tx_id;
129 | delete tx_fulfill;
130 | }
131 |
132 |
133 | };
134 |
135 | };
136 |
137 | #endif
138 |
--------------------------------------------------------------------------------
/POC_code/include/timer.h:
--------------------------------------------------------------------------------
1 |
2 | #ifndef _timer_h
3 | #define _timer_h
4 |
5 | #include
6 | #include
7 | #include
8 | #include
9 |
10 | typedef boost::chrono::process_real_cpu_clock::time_point time_point;
11 | typedef boost::chrono::duration double_second;
12 | typedef boost::chrono::process_real_cpu_clock real_time;
13 |
14 | class Timer
15 | {
16 |
17 | private:
18 |
19 | FILE *file;
20 | char* description;
21 |
22 | // Clock Time
23 | clock_t c_start;
24 | clock_t c_end;
25 | double c_duration;
26 |
27 | // Real Time
28 | time_point r_start;
29 | time_point r_end;
30 | double_second r_duration;
31 |
32 | public:
33 | Timer();
34 | Timer(char *name);
35 | ~Timer();
36 |
37 | void start();
38 | void end();
39 | void print();
40 |
41 | // In seconds
42 | double get_clock_time();
43 | double get_real_time();
44 |
45 | };
46 |
47 | #endif
48 |
--------------------------------------------------------------------------------
/POC_code/include/tumbler.h:
--------------------------------------------------------------------------------
1 |
2 | #ifndef _tumbler_h
3 | #define _tumbler_h
4 |
5 | #include "assert.h"
6 | #include
7 |
8 | #include
9 | #include
10 | #include
11 | #include
12 |
13 | #include "scc.h"
14 | #include "ec.h"
15 | #include "tx.h"
16 | #include "utility.h"
17 | #include "encrypt.h"
18 |
19 | #include "zmq.hpp"
20 |
21 | class Tumbler
22 | {
23 |
24 | protected:
25 | RSA* rsa;
26 | EC_KEY *ec;
27 | bool verified;
28 |
29 | Bin* rsa_pub;
30 | Bin* ec_pubkey;
31 | Bin* bob_ec_pubkey;
32 | Bin* address;
33 |
34 | Bin* p2sh_address;
35 | Bin* lock_time;
36 | Bin* redeem_script;
37 | Bin* funding_tx_id;
38 |
39 | std::vector tx; // TX set -- should be of size numN + numM
40 |
41 | std::vector epsilon; // N bit randoms
42 | std::vector C; // Commitment -- Encrypted signatures
43 | std::vector Z; // RSA encryptions of the epsilons
44 | std::vector quotients; // epsilon_(i+1) / epsilon_i mod rsa->n
45 |
46 | std::vector R; // Indices for real tx in tx_set
47 | std::vector F; // Indices for fake tx in tx_set
48 | std::vector epsilon_f; // epsilons for fakes
49 |
50 | Bin* salt;
51 | Bin* h_r;
52 | Bin* h_f;
53 |
54 | bool create_quotients();
55 | bool create_refund_tx();
56 |
57 | public:
58 | int rsa_len; // Size of RSA modulus in bytes
59 |
60 | bool create_offer_tx();
61 |
62 | // Constructors & Destructors
63 | Tumbler();
64 | ~Tumbler();
65 |
66 | // Gets
67 | Bin* get_redeem_script();
68 | Bin* get_funding_tx_id();
69 |
70 | std::vector* get_Z();
71 | std::vector* get_commitment();
72 | std::vector* get_epsilons();
73 | std::vector* get_quotients();
74 |
75 | Bin* get_pubkey();
76 | Bin* get_rsa();
77 |
78 | // Sets
79 | void set_R(std::vector r);
80 | void set_F(std::vector f);
81 | void set_h_r(Bin* h);
82 | void set_h_f(Bin* h);
83 | void set_salt(Bin* r);
84 | void set_party_pubkey(Bin* public_key);
85 |
86 | /*!
87 | * Sign transactions using ECDSA
88 | *
89 | * \param[in] tx_set Bitcoin transactions to sign
90 | *
91 | * \return true on success
92 | */
93 | bool sign_transactions(std::vector& tx_set);
94 |
95 | /*!
96 | * Verify that the recieved randoms hash to the fake transactions.
97 | * Needs R & F to be set before being called.
98 | *
99 | * \param[in] r Encrypted epsilons.
100 | *
101 | * \return true on success
102 | */
103 | bool verify_fake_tx(std::vector& r);
104 |
105 | };
106 |
107 | #endif
108 |
--------------------------------------------------------------------------------
/POC_code/include/tx.h:
--------------------------------------------------------------------------------
1 | #ifndef _tx_h
2 | #define _tx_h
3 |
4 |
5 | #include "utility.h"
6 | #include "network.h"
7 | #include "constants.h"
8 | #include "hash.h"
9 | #include "scc.h"
10 |
11 | /*!
12 | * Gets the signature hash of a transaction spending from a P2SH address
13 | * Funds go to specified address
14 | *
15 | * \param[in] redeem_script P2SH redeem script
16 | * \param[in] address Output address
17 | * \param[in] funding_tx_id TXid of P2SH funding TX
18 | * \param[out] raw_tx TX in raw byte form
19 | * \param[out] sig_hash Signature Hash
20 | *
21 | * \return true on success
22 | */
23 | bool get_tx(Bin* redeem_script, Bin* address, Bin* funding_tx_id, Bin* raw_tx, Bin* sig_hash, bool preimage=false);
24 |
25 | /*!
26 | * Gets the signature hash of a transaction spending from a P2SH address
27 | * Funds go to the returned random address (different address for each call)
28 | *
29 | * \param[in] redeem_script P2SH redeem script
30 | * \param[in] funding_tx_id TXid of P2SH funding TX
31 | * \param[out] sig_hash Signature Hash
32 | * \param[out] address Output address
33 | *
34 | * \return true on success
35 | */
36 | bool get_tx_with_address(Bin* redeem_script, Bin* funding_tx_id, Bin* sig_hash, Bin* address);
37 |
38 | /*!
39 | * Gets the txid of the raw trandaction as a hex string
40 | *
41 | * \param[in] tx raw tx in byte form
42 | * \param[out] tx_id hex form big endian
43 | *
44 | * \return true on success
45 | */
46 | bool get_id_from_tx(Bin* tx, Bin* tx_id);
47 |
48 | /*!
49 | * Gets the signature hash of a transaction refunding from a P2SH address
50 | * Funds go to specified address
51 | *
52 | * \param[in] redeem_script P2SH redeem script
53 | * \param[in] address Output address
54 | * \param[in] funding_tx_id TXid of P2SH funding TX
55 | * \param[in] lock_time The block the tx is locked to
56 | * \param[out] raw_tx TX in raw byte form
57 | * \param[out] sig_hash Signature Hash
58 | *
59 | * \return true on success
60 | */
61 | bool get_refund_tx(Bin* redeem_script, Bin* address, Bin* funding_tx_id, Bin* lock_time, Bin* raw_tx, Bin* sig_hash);
62 |
63 | /*!
64 | * Creates a transaction that fulfills refunds the funds in the P2SH
65 | * Returns the complete raw tx that can be posted
66 | *
67 | * \param[in] signature EC signature of funder
68 | * \param[in] raw_tx TX in raw byte form
69 | * \param[in] redeem_script P2SH redeem script
70 | * \param[out] refund_tx Complete TX in raw byte form
71 | *
72 | * \return true on success
73 | */
74 | bool send_refund_tx(Bin* signature, Bin* raw_tx, Bin* redeem_script, Bin* refund_tx);
75 |
76 | /*!
77 | * Sets up and funds a preimage P2SH address
78 | *
79 | * \param[in] real_hashes The images vector
80 | * \param[in] funder_pubkey EC public key of funder
81 | * \param[in] redeemer_pubkey EC public key of redeemer
82 | * \param[out] redeem_script P2SH redeem script
83 | * \param[out] funding_tx_id TXid of P2SH funding TX
84 | *
85 | * \return true on success
86 | */
87 | bool setup_preimage(std::vector& real_hashes, Bin* funder_pubkey, Bin* redeemer_pubkey, Bin* redeem_script, Bin* funding_tx_id, Bin* p2sh_address, Bin* lock_time);
88 |
89 | /*!
90 | * Creates a transaction that fulfills that preimage P2SH conditions
91 | * Returns the complete raw tx that can be posted
92 | *
93 | * \param[in] real_keys The preimage vector
94 | * \param[in] redeem_script P2SH redeem script
95 | * \param[in] raw_tx TX in raw byte form
96 | * \param[in] redeemer_sig EC signature of redeemer
97 | * \param[out] tx_fulfill Complete TX in raw byte form
98 | *
99 | * \return true on success
100 | */
101 | bool spend_preimage(std::vector& real_keys, Bin* redeem_script, Bin*raw_tx, Bin* redeemer_sig, Bin* tx_fulfill);
102 |
103 | /*!
104 | * Extracts the keys (images) in serial form from the raw tx that
105 | * fulfills the conditions of the preimage P2SH
106 | *
107 | * \param[in] tx_fulfill Complete TX in raw byte form
108 | * \param[out] serial_real_keys Keys in serial form
109 | *
110 | * \return true on success
111 | */
112 | bool get_keys_from_tx(Bin* tx_fulfill, Bin* serial_real_keys);
113 |
114 | /*!
115 | * Sets up and funds a 2-of-2 escrow P2SH address
116 | *
117 | * \param[in] payer_pubkey EC public key of funder
118 | * \param[in] redeemer_pubkey EC public key of redeemer
119 | * \param[out] redeem_script P2SH redeem script
120 | * \param[out] funding_tx_id TXid of P2SH funding TX
121 | *
122 | * \return true on success
123 | */
124 | bool setup_escrow(Bin* payer_pubkey, Bin* redeemer_pubkey, Bin* redeem_script, Bin* funding_tx_id, Bin* p2sh_address, Bin* lock_time);
125 |
126 |
127 | /*!
128 | * Creates a transaction that fulfills that escrow P2SH conditions
129 | * Returns the complete raw tx that can be posted
130 | *
131 | * \param[in] raw_tx TX in raw byte form
132 | * \param[in] payer_sig EC signature of redeemer
133 | * \param[in] redeemer_sig EC signature of redeemer
134 | * \param[in] address Output address
135 | * \param[in] redeem_script P2SH redeem script
136 | * \param[in] funding_tx_id TXid of P2SH funding TX
137 | * \param[out] tx_fulfill Complete TX in raw byte form
138 | *
139 | * \return true on success
140 | */
141 | bool spend_escrow(Bin* payer_sig, Bin* redeemer_sig, Bin* address, Bin* redeem_script, Bin* funding_tx_id, Bin* tx_fulfill);
142 |
143 | #endif
144 |
--------------------------------------------------------------------------------
/POC_code/include/utility.h:
--------------------------------------------------------------------------------
1 | #ifndef _utility_h
2 | #define _utility_h
3 |
4 | #include "bin.h"
5 | #include "memory.h"
6 | #include
7 | #include
8 |
9 |
10 | // Need this to print/access blinding struct values
11 | struct bn_blinding_st
12 | {
13 | BIGNUM *A;
14 | BIGNUM *Ai;
15 | BIGNUM *e;
16 | BIGNUM *mod; /* just a reference */
17 | };
18 |
19 | //============================================================================
20 |
21 | /*!
22 | * Serialize a BigNum f to a buffer of fixed length.
23 | *
24 | * \param[in] f Bignum to be serialized.
25 | * \param[out] bin Binary string which f is serialized into.
26 | * \param[in] bin_len Length of bin.
27 | *
28 | * \return Size of bytes serialized.
29 | */
30 | int BNToBin(BIGNUM *f, unsigned char * bin, int bin_len);
31 |
32 | //============================================================================
33 |
34 | /*!
35 | * Prints bignum data in hex form
36 | *
37 | * \param[in] bn a BIGNUM
38 | *
39 | */
40 | void print_BN(BIGNUM* bn);
41 |
42 | /*!
43 | * Prints input data in hex form
44 | *
45 | * \param[in] len Length of data
46 | * \param[in] data The string to print out in hex format
47 | *
48 | */
49 | void print_hex(int len, unsigned char *data);
50 |
51 | /*!
52 | * Prints out all the key/strings in the vector.
53 | *
54 | * \param[int] m A vector of strings (keys)
55 | *
56 | */
57 | void print_keys(std::vector m);
58 |
59 | /*!
60 | * Prints out R and R inverse from the blinding struct
61 | *
62 | * \param[int] blind An initilizes blinding struct
63 | *
64 | */
65 | void print_blind(BN_BLINDING* blind);
66 |
67 | /*!
68 | * Prints out R and R inverse for all the blinds in the vector.
69 | *
70 | * \param[int] blinds A vector of blinds (BN_BLINDING)
71 | *
72 | */
73 | void print_blinds(std::vector blinds);
74 |
75 | //============================================================================
76 |
77 | /*!
78 | * Returns a pointer to the hex form of the input
79 | *
80 | * \param[in] msg in bin format
81 | *
82 | */
83 | char * get_hex_str(Bin* msg);
84 |
85 | /*!
86 | * Returns a pointer to the reversed hex form of the input
87 | *
88 | * \param[in] msg in bin format
89 | *
90 | */
91 | char * get_hex_str_rev(Bin* msg);
92 |
93 | //============================================================================
94 |
95 | #endif
96 |
--------------------------------------------------------------------------------
/POC_code/include/zmq_addon.hpp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BUSEC/TumbleBit/55829dc75c36554e710e723dedb510d62a57ca0c/POC_code/include/zmq_addon.hpp
--------------------------------------------------------------------------------
/POC_code/keys/EC_private_alice.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN PUBLIC KEY-----
2 | MIH1MIGuBgcqhkjOPQIBMIGiAgEBMCwGByqGSM49AQECIQD/////////////////
3 | ///////////////////+///8LzAGBAEABAEHBEEEeb5mfvncu6xVoGKVzocLBwKb
4 | /NstzijZWfKBWxb4F5hIOtp3JqPEZV2k+/wOEQio/Re0SKaFVBmcR9CP+xDUuAIh
5 | AP////////////////////66rtzmr0igO7/SXozQNkFBAgEBA0IABNG3DYhQqf9W
6 | ntpgRfW/D5pCihic80EQwmeCJ/F+abE68CFqNIVJ49QMZfL612dlBt6dPR7nSN5p
7 | knmoP7rNsTE=
8 | -----END PUBLIC KEY-----
9 | -----BEGIN PRIVATE KEY-----
10 | MIIBIwIBADCBrgYHKoZIzj0CATCBogIBATAsBgcqhkjOPQEBAiEA////////////
11 | /////////////////////////v///C8wBgQBAAQBBwRBBHm+Zn753LusVaBilc6H
12 | CwcCm/zbLc4o2VnygVsW+BeYSDradyajxGVdpPv8DhEIqP0XtEimhVQZnEfQj/sQ
13 | 1LgCIQD////////////////////+uq7c5q9IoDu/0l6M0DZBQQIBAQRtMGsCAQEE
14 | IFDdeOkhwgaUQBWxjUmHhFJM3G98WbxImh6NHZBaK/ljoUQDQgAE0bcNiFCp/1ae
15 | 2mBF9b8PmkKKGJzzQRDCZ4In8X5psTrwIWo0hUnj1Axl8vrXZ2UG3p09HudI3mmS
16 | eag/us2xMQ==
17 | -----END PRIVATE KEY-----
18 |
--------------------------------------------------------------------------------
/POC_code/keys/EC_private_bob.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN PUBLIC KEY-----
2 | MIH1MIGuBgcqhkjOPQIBMIGiAgEBMCwGByqGSM49AQECIQD/////////////////
3 | ///////////////////+///8LzAGBAEABAEHBEEEeb5mfvncu6xVoGKVzocLBwKb
4 | /NstzijZWfKBWxb4F5hIOtp3JqPEZV2k+/wOEQio/Re0SKaFVBmcR9CP+xDUuAIh
5 | AP////////////////////66rtzmr0igO7/SXozQNkFBAgEBA0IABF97mocn5eka
6 | P9CPOQHcwBv/QIHTvCE4+kq/A2niVl4ESrF6FhY2Xuw0fb4mKzbVF4gk5ZwJ8Zz/
7 | jMHJgfD9em4=
8 | -----END PUBLIC KEY-----
9 | -----BEGIN PRIVATE KEY-----
10 | MIIBIwIBADCBrgYHKoZIzj0CATCBogIBATAsBgcqhkjOPQEBAiEA////////////
11 | /////////////////////////v///C8wBgQBAAQBBwRBBHm+Zn753LusVaBilc6H
12 | CwcCm/zbLc4o2VnygVsW+BeYSDradyajxGVdpPv8DhEIqP0XtEimhVQZnEfQj/sQ
13 | 1LgCIQD////////////////////+uq7c5q9IoDu/0l6M0DZBQQIBAQRtMGsCAQEE
14 | IC3RpJa+GRNJfORBtyokJiWmPtmbzBiZGY0wGzCTSygJoUQDQgAEX3uahyfl6Ro/
15 | 0I85AdzAG/9AgdO8ITj6Sr8DaeJWXgRKsXoWFjZe7DR9viYrNtUXiCTlnAnxnP+M
16 | wcmB8P16bg==
17 | -----END PRIVATE KEY-----
18 |
--------------------------------------------------------------------------------
/POC_code/keys/EC_private_test.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN PUBLIC KEY-----
2 | MIH1MIGuBgcqhkjOPQIBMIGiAgEBMCwGByqGSM49AQECIQD/////////////////
3 | ///////////////////+///8LzAGBAEABAEHBEEEeb5mfvncu6xVoGKVzocLBwKb
4 | /NstzijZWfKBWxb4F5hIOtp3JqPEZV2k+/wOEQio/Re0SKaFVBmcR9CP+xDUuAIh
5 | AP////////////////////66rtzmr0igO7/SXozQNkFBAgEBA0IABPVeKpIv2bpE
6 | kmwvjkfonSlwkWrsAGp/aXZNXwhXUJhMnPzZTZu8CQKmwkmZmSJEyaFUBY+jAoWP
7 | S9vv/kz/yZ8=
8 | -----END PUBLIC KEY-----
9 | -----BEGIN PRIVATE KEY-----
10 | MIIBIwIBADCBrgYHKoZIzj0CATCBogIBATAsBgcqhkjOPQEBAiEA////////////
11 | /////////////////////////v///C8wBgQBAAQBBwRBBHm+Zn753LusVaBilc6H
12 | CwcCm/zbLc4o2VnygVsW+BeYSDradyajxGVdpPv8DhEIqP0XtEimhVQZnEfQj/sQ
13 | 1LgCIQD////////////////////+uq7c5q9IoDu/0l6M0DZBQQIBAQRtMGsCAQEE
14 | IOOSqRpYEZmIsE87hdHZdejCJ1NBoN2b3f1euvrSnccAoUQDQgAE9V4qki/ZukSS
15 | bC+OR+idKXCRauwAan9pdk1fCFdQmEyc/NlNm7wJAqbCSZmZIkTJoVQFj6MChY9L
16 | 2+/+TP/Jnw==
17 | -----END PRIVATE KEY-----
18 |
--------------------------------------------------------------------------------
/POC_code/keys/EC_private_tumbler.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN PUBLIC KEY-----
2 | MIH1MIGuBgcqhkjOPQIBMIGiAgEBMCwGByqGSM49AQECIQD/////////////////
3 | ///////////////////+///8LzAGBAEABAEHBEEEeb5mfvncu6xVoGKVzocLBwKb
4 | /NstzijZWfKBWxb4F5hIOtp3JqPEZV2k+/wOEQio/Re0SKaFVBmcR9CP+xDUuAIh
5 | AP////////////////////66rtzmr0igO7/SXozQNkFBAgEBA0IABGQNimsBwJ8A
6 | jG5e8QyeueXTZTIBXVGlzNANAuFnzD5lrO10djaHOm0/m5ddrJKTPr8mQlmW9g0t
7 | BGhGeYZD/8w=
8 | -----END PUBLIC KEY-----
9 | -----BEGIN PRIVATE KEY-----
10 | MIIBIwIBADCBrgYHKoZIzj0CATCBogIBATAsBgcqhkjOPQEBAiEA////////////
11 | /////////////////////////v///C8wBgQBAAQBBwRBBHm+Zn753LusVaBilc6H
12 | CwcCm/zbLc4o2VnygVsW+BeYSDradyajxGVdpPv8DhEIqP0XtEimhVQZnEfQj/sQ
13 | 1LgCIQD////////////////////+uq7c5q9IoDu/0l6M0DZBQQIBAQRtMGsCAQEE
14 | ILgAn20g75DhWYwbgdQy16KiFam09aXRpLvRW6gMXWahoUQDQgAEZA2KawHAnwCM
15 | bl7xDJ655dNlMgFdUaXM0A0C4WfMPmWs7XR2Noc6bT+bl12skpM+vyZCWZb2DS0E
16 | aEZ5hkP/zA==
17 | -----END PRIVATE KEY-----
18 |
--------------------------------------------------------------------------------
/POC_code/keys/EC_private_tumbler_main.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN PUBLIC KEY-----
2 | MIH1MIGuBgcqhkjOPQIBMIGiAgEBMCwGByqGSM49AQECIQD/////////////////
3 | ///////////////////+///8LzAGBAEABAEHBEEEeb5mfvncu6xVoGKVzocLBwKb
4 | /NstzijZWfKBWxb4F5hIOtp3JqPEZV2k+/wOEQio/Re0SKaFVBmcR9CP+xDUuAIh
5 | AP////////////////////66rtzmr0igO7/SXozQNkFBAgEBA0IABBGotNrxDMR9
6 | aF6aZHm51lGH19zDD4jfBvpeG7Nl7/PqyHbILbFx3ylUGh5wZoOG1dRyhfpvpTnf
7 | mask4YdNHdY=
8 | -----END PUBLIC KEY-----
9 | -----BEGIN PRIVATE KEY-----
10 | MIIBIwIBADCBrgYHKoZIzj0CATCBogIBATAsBgcqhkjOPQEBAiEA////////////
11 | /////////////////////////v///C8wBgQBAAQBBwRBBHm+Zn753LusVaBilc6H
12 | CwcCm/zbLc4o2VnygVsW+BeYSDradyajxGVdpPv8DhEIqP0XtEimhVQZnEfQj/sQ
13 | 1LgCIQD////////////////////+uq7c5q9IoDu/0l6M0DZBQQIBAQRtMGsCAQEE
14 | IH+JhHr1DZ9UFibPPGRGvzJVxH1n0nq5+U/d4pnBLTDDoUQDQgAEEai02vEMxH1o
15 | XppkebnWUYfX3MMPiN8G+l4bs2Xv8+rIdsgtsXHfKVQaHnBmg4bV1HKF+m+lOd+Z
16 | qyThh00d1g==
17 | -----END PRIVATE KEY-----
18 |
--------------------------------------------------------------------------------
/POC_code/keys/EC_public_alice.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN PUBLIC KEY-----
2 | MIH1MIGuBgcqhkjOPQIBMIGiAgEBMCwGByqGSM49AQECIQD/////////////////
3 | ///////////////////+///8LzAGBAEABAEHBEEEeb5mfvncu6xVoGKVzocLBwKb
4 | /NstzijZWfKBWxb4F5hIOtp3JqPEZV2k+/wOEQio/Re0SKaFVBmcR9CP+xDUuAIh
5 | AP////////////////////66rtzmr0igO7/SXozQNkFBAgEBA0IABNG3DYhQqf9W
6 | ntpgRfW/D5pCihic80EQwmeCJ/F+abE68CFqNIVJ49QMZfL612dlBt6dPR7nSN5p
7 | knmoP7rNsTE=
8 | -----END PUBLIC KEY-----
9 |
--------------------------------------------------------------------------------
/POC_code/keys/EC_public_bob.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN PUBLIC KEY-----
2 | MIH1MIGuBgcqhkjOPQIBMIGiAgEBMCwGByqGSM49AQECIQD/////////////////
3 | ///////////////////+///8LzAGBAEABAEHBEEEeb5mfvncu6xVoGKVzocLBwKb
4 | /NstzijZWfKBWxb4F5hIOtp3JqPEZV2k+/wOEQio/Re0SKaFVBmcR9CP+xDUuAIh
5 | AP////////////////////66rtzmr0igO7/SXozQNkFBAgEBA0IABF97mocn5eka
6 | P9CPOQHcwBv/QIHTvCE4+kq/A2niVl4ESrF6FhY2Xuw0fb4mKzbVF4gk5ZwJ8Zz/
7 | jMHJgfD9em4=
8 | -----END PUBLIC KEY-----
9 |
--------------------------------------------------------------------------------
/POC_code/keys/EC_public_test.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN PUBLIC KEY-----
2 | MIH1MIGuBgcqhkjOPQIBMIGiAgEBMCwGByqGSM49AQECIQD/////////////////
3 | ///////////////////+///8LzAGBAEABAEHBEEEeb5mfvncu6xVoGKVzocLBwKb
4 | /NstzijZWfKBWxb4F5hIOtp3JqPEZV2k+/wOEQio/Re0SKaFVBmcR9CP+xDUuAIh
5 | AP////////////////////66rtzmr0igO7/SXozQNkFBAgEBA0IABPVeKpIv2bpE
6 | kmwvjkfonSlwkWrsAGp/aXZNXwhXUJhMnPzZTZu8CQKmwkmZmSJEyaFUBY+jAoWP
7 | S9vv/kz/yZ8=
8 | -----END PUBLIC KEY-----
9 |
--------------------------------------------------------------------------------
/POC_code/keys/EC_public_tumbler.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN PUBLIC KEY-----
2 | MIH1MIGuBgcqhkjOPQIBMIGiAgEBMCwGByqGSM49AQECIQD/////////////////
3 | ///////////////////+///8LzAGBAEABAEHBEEEeb5mfvncu6xVoGKVzocLBwKb
4 | /NstzijZWfKBWxb4F5hIOtp3JqPEZV2k+/wOEQio/Re0SKaFVBmcR9CP+xDUuAIh
5 | AP////////////////////66rtzmr0igO7/SXozQNkFBAgEBA0IABGQNimsBwJ8A
6 | jG5e8QyeueXTZTIBXVGlzNANAuFnzD5lrO10djaHOm0/m5ddrJKTPr8mQlmW9g0t
7 | BGhGeYZD/8w=
8 | -----END PUBLIC KEY-----
9 |
--------------------------------------------------------------------------------
/POC_code/keys/EC_public_tumbler_main.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN PUBLIC KEY-----
2 | MIH1MIGuBgcqhkjOPQIBMIGiAgEBMCwGByqGSM49AQECIQD/////////////////
3 | ///////////////////+///8LzAGBAEABAEHBEEEeb5mfvncu6xVoGKVzocLBwKb
4 | /NstzijZWfKBWxb4F5hIOtp3JqPEZV2k+/wOEQio/Re0SKaFVBmcR9CP+xDUuAIh
5 | AP////////////////////66rtzmr0igO7/SXozQNkFBAgEBA0IABBGotNrxDMR9
6 | aF6aZHm51lGH19zDD4jfBvpeG7Nl7/PqyHbILbFx3ylUGh5wZoOG1dRyhfpvpTnf
7 | mask4YdNHdY=
8 | -----END PUBLIC KEY-----
9 |
--------------------------------------------------------------------------------
/POC_code/keys/private_2048_test.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN RSA PRIVATE KEY-----
2 | MIIEpAIBAAKCAQEArqDcYDN5G30tEr090DpwS7ZhASNTI/tHfZ/0qCHjjpQzKS5o
3 | cpgY6LGt9dqXqmSb7J32Uu0kbp9yd3BU7rwdiin8n4ke18GnquCy+3LuomkSvvDH
4 | PoI4gfSa7pfaFwoeb/95PA+1Z2WuIn6n7CICpzjNtMhrQUoUxKAxK/w2NjwjpXH+
5 | ypK6CyvkBOg+Jm5vLxUQPiwZWdemznIMmAT6rR1bMqnl5B17HQkRYlXrzVtWXH24
6 | dpWi8h3SXynNPa1je1XcUrY04VVj+tSh0zbF/+FGvOu+3614sSgyymp/Y5GkdPhI
7 | cL/OamXtI7Dm1mf8JKQrS3YZiNWv8NzuC0cPDQIDAQABAoIBAQCqQXua75RsEKcZ
8 | VhgmJFPH/ZCmI2Kz+hHBkWpfYmsSX7thszVyRIhElrcctHqaTm0XTQsT3tFeaWaY
9 | vJSSDiZexoDeqjm/8bcfCuR186BmCDuWnfokH6IoUeucI8EmJV93ooT44ffjT2dv
10 | ijz+JEqh7ufgEmc/yJJnAifu0n+ob21EDGMROxhObzlvdCgAzKxTwFS7602eoFJE
11 | qHrzJW2MlCoIAsCV5HvzN+jLvNFBUrclQkhcSPZTw8lVVij+7ygFmmk9LdiQDbx8
12 | 0prjXAHWdzDqdQ6dogSRP5wOFmkWSpsfnotJJ8qr4qQU1ahhgI4uoueZrbxMCSq0
13 | 47W6H0WhAoGBANzUx40tmV1p37T56csZqkMJqEODctr5fNpHwIzMLPqBfa2BumTd
14 | Y09vL/ven+9dFGpYcCdSndVmo6O5GqERpHLgaVJjZehVq+rZP+tPyv1knBbIN4vD
15 | Y8KJqpEx8u5TwqTFlftXfKunhw1Ued5cHl66OaEKGGFmzpc0/93X5L77AoGBAMpw
16 | aCGvULKWbw6UWMY8usK5pbCy5xqhbbz1/83UHJbfC2EJs181cFjn4PwdWJkuRBFC
17 | rVL3FvqnvR5cmRE6VFzTdECBUIhMjup1BCCMwKs0cWvzZdwsqfy4SQtooq4VBK4q
18 | 8CbtBJ5ve1pIVTSNe6ZD6tHPLNkTSz6QJpzB/uuXAoGAIhffrxYpJVjhJsmmpKqT
19 | tMHa7oFuzAvUkMafHZ2wHAS96Hms00GywWLDH7mhK41NR5XbytZgc7/i57X+PHvC
20 | zdGDsSqTYylG330m9ydciX5s8r96g+NolXI3mS8C+HSKCnJO030QTFgS66XtIr1K
21 | GwnZN9mdJfx/TKzsC833DN0CgYANyS/eM2EseEAh3wpYnaQeRKQ670P7tUiS2LHN
22 | 44b64z+UISP89NesxkW1BY6WB+eMwVyqTLdc5HVljurBmJZMJ/4/sk64qXYGE2fv
23 | i4ZHYm/i6RVjtArzcd1PkJWbg0TpU3U9QWDSJUdiM5DR3lywSum/1fr44W57WTe3
24 | 7yIcCwKBgQCtRICk3b7HJE+L9Mq7KCUUXC6WyCMIp7n6j84H6TjqeWTil4lT/pZK
25 | lLlVEDWxIH9mtXgpVnj4RLvuk2jSC4TI/JecsQtqPi1raaZhkfiGu73HaesW2u6q
26 | zWtAq24EHkmMPyxjtP1Gv2FXD3ksbC/1tZnKb4tFSmc8hBOKD3PbjQ==
27 | -----END RSA PRIVATE KEY-----
28 |
--------------------------------------------------------------------------------
/POC_code/keys/private_2048_tumbler.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN RSA PRIVATE KEY-----
2 | MIIEpQIBAAKCAQEAtYjVMf/U6qibELdSoo9L6K1RKId9Bc0h6epIWIxfc5P4bXqV
3 | y65ISzKdF9hu86LGUoGONyqmJV12Bs6AL59bTf6nBjuaz02T66jZ7+7PLRJEdcFf
4 | JgK5PeG1d9RVVUXiNvZ+nA6X0TnTfWyNKPKEskXrAj56UfHefWucoW6nQrPeY+7i
5 | dEw8BZ/WusFDJq5eFY7qKT2Pp2424huDPuQqfSBWMsQIvG26U9umYfBYEScwgOgp
6 | thXAqrEAvQW52QBFtLDG1gx+IXMRkur5b68c7ZNcFYCuXd8XbPfDFQxfG4wkJ0Ms
7 | AAtqR8nbfRG1x+/edhnAob5vsl+4jDjhp3E07QIDAQABAoIBAQCux1FMVF4wl6jE
8 | TVx4OrMBEG2FMf2DKl8ukWyaJHx6EMsszMuQUPo1vENXhAA+/kcnhKjiIGPascND
9 | BmqQb0M/MqCo9ZY1ZSG30NgTk79QS7gyD72GITUsiTVoa7zE3wXPmT+JDNvKi3w9
10 | 09eMxwJPidWcUX7/inmGE6e4HYtYQan8sJydB+rOm2TFers7JrOdinP6eGliCFwH
11 | DF/khUUtMX6QFlXS/qWxBVwMRPUTx5SaoMgFRxCxLQeVKmpIdo3aU1pYCB/gZ0Et
12 | Nm5b1496T+BJ/u/kvNwPX3o7FczRG6FFyPzmOBM/zhIOkjG4vuhbOFiiq0Q/tFlH
13 | 0C5+ezdZAoGBANt3XD+uxmrmX1++gQ2GuyjBnT2v1bRG9apVX549P5F3/n0izElw
14 | IdPZ8ynBGdj6AS12Hcqk3k0Tt5Xmb16oTUK3W5zXSmyBWl5Y0zG1TemptJjA1a9r
15 | C+sNimJ6NFXER1oBzygG5FEbSUhtzCoTGsi8M06mGLd86s2uxjFmKY+vAoGBANPA
16 | /wnVYldv3f/hE+0wOUGpJxWbuEEvmWEl/xPhI+Wmc3zLsJvn6WvvOKkWnzMg/yR9
17 | G67IUiXcfbwzPLPu9h/Q+5hSDNOripACOiNcx+X8BSZNWATVMC1J6v9V8dlCdjA2
18 | C8aRJaG9MTNIgmTmUb3IPlcxgLTL/e68JAbQ+nAjAoGBAKYk8HNNjuyyxpUnFW/2
19 | BY5PNQjUKsa1yZlP1HlpCMzJuKFnTJx0BUfqgcmkZDr82RNfjiIxOhHD0YHr13gj
20 | lYniYbqUycTnEFDIkenZxcgVL6FMqviH45fowlDXDvO3CgU7xWYaAZLdQ1dPt/ZK
21 | TEaXI4hw+dk++ksH+wa+vswFAoGANsNh8fQak8xdmJBoK95d4GpTrlXwaANcYnCG
22 | MGj4dKsAkRTInvlyN7TNbYVpNLri4Vftsd0iyaHlbqe9mjdBtebBOpp1sMRbeHTq
23 | /jw/gm4UEtzL16we4oeMW+6pNmvmzv8bOoZNOjAIql+lQV0DZNaFsN0fkSJ0kKpd
24 | ktm2+wsCgYEAqoDuBlQGr8HY4Ln/xbRIXrmY0V5lndYcnfUqxzlmTAYPynxQ407q
25 | I02jEFuj9HJKS71zZmNYaRBEv4P5f+RfpOXemGURjG6mcOSm12297ZU625nhHlKc
26 | ZnYqxwLMgJCWrDkN8pulG5K3SCgFNI4TURmu3qJ35fNoC11T0ycJX20=
27 | -----END RSA PRIVATE KEY-----
28 |
--------------------------------------------------------------------------------
/POC_code/keys/public_2048_test.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN RSA PUBLIC KEY-----
2 | MIIBCgKCAQEArqDcYDN5G30tEr090DpwS7ZhASNTI/tHfZ/0qCHjjpQzKS5ocpgY
3 | 6LGt9dqXqmSb7J32Uu0kbp9yd3BU7rwdiin8n4ke18GnquCy+3LuomkSvvDHPoI4
4 | gfSa7pfaFwoeb/95PA+1Z2WuIn6n7CICpzjNtMhrQUoUxKAxK/w2NjwjpXH+ypK6
5 | CyvkBOg+Jm5vLxUQPiwZWdemznIMmAT6rR1bMqnl5B17HQkRYlXrzVtWXH24dpWi
6 | 8h3SXynNPa1je1XcUrY04VVj+tSh0zbF/+FGvOu+3614sSgyymp/Y5GkdPhIcL/O
7 | amXtI7Dm1mf8JKQrS3YZiNWv8NzuC0cPDQIDAQAB
8 | -----END RSA PUBLIC KEY-----
9 |
--------------------------------------------------------------------------------
/POC_code/keys/public_2048_tumbler.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN RSA PUBLIC KEY-----
2 | MIIBCgKCAQEAtYjVMf/U6qibELdSoo9L6K1RKId9Bc0h6epIWIxfc5P4bXqVy65I
3 | SzKdF9hu86LGUoGONyqmJV12Bs6AL59bTf6nBjuaz02T66jZ7+7PLRJEdcFfJgK5
4 | PeG1d9RVVUXiNvZ+nA6X0TnTfWyNKPKEskXrAj56UfHefWucoW6nQrPeY+7idEw8
5 | BZ/WusFDJq5eFY7qKT2Pp2424huDPuQqfSBWMsQIvG26U9umYfBYEScwgOgpthXA
6 | qrEAvQW52QBFtLDG1gx+IXMRkur5b68c7ZNcFYCuXd8XbPfDFQxfG4wkJ0MsAAtq
7 | R8nbfRG1x+/edhnAob5vsl+4jDjhp3E07QIDAQAB
8 | -----END RSA PUBLIC KEY-----
9 |
--------------------------------------------------------------------------------
/POC_code/makefile:
--------------------------------------------------------------------------------
1 | # Adapted from https://web.stanford.edu/class/cs107/guide_make.html
2 |
3 | ###########################################################################
4 | ## Build Flags & Library Dependencies
5 | ###########################################################################
6 |
7 | CC = g++
8 | CFLAGS = -g -Wall
9 | # CFLAGS += -Dmemcmp=timingsafe_memcmp
10 | LDFLAGS = -lssl -lcrypto -lboost_unit_test_framework -lboost_chrono -lboost_system -lzmq
11 | INCLUDE = -I ./include
12 |
13 | # The CFLAGS variable sets compile flags for gcc:
14 | # -g compile with debug information
15 | # -Wall give verbose compiler warnings
16 |
17 | # Add path to libressl if OSX or Ubuntu-(if compiled from source)
18 | UNAME_S := $(shell uname -s)
19 | ifeq ($(UNAME_S),Darwin)
20 | LDFLAGS += -L/usr/local/opt/libressl/lib
21 | INCLUDE += -I/usr/local/opt/libressl/include
22 | endif
23 |
24 | ifeq ($(UNAME_S),Linux)
25 | LDFLAGS += -L/usr/local/lib
26 | endif
27 |
28 | .PHONY: clean BIN_DIR
29 |
30 | ###########################################################################
31 | ## Global Variables
32 | ###########################################################################
33 |
34 | BIN = bin/
35 | SOURCE = src/
36 | LIB = ./bin/
37 | TEST = ./src/test/
38 | CRYPTO = $(SOURCE)crypto/
39 | UTILITY = $(SOURCE)utility/
40 |
41 | all: BIN_DIR bob_client tumbler_server signer_server
42 |
43 | # Create Bin Directory
44 | BIN_DIR:
45 | test -d bin || mkdir bin
46 |
47 | ###########################################################################
48 | ## UTILITY
49 | ###########################################################################
50 |
51 | UTILITY_SOURCES = /utility.cpp /bin.cpp /network.cpp /timer.cpp /memory.cpp
52 | UTILITY_OBJECTS = $(subst /,$(BIN),$(UTILITY_SOURCES:.cpp=.o))
53 | UTILITY_TEST_TARGETS = utility_test bin_test
54 | DEPEND = $(UTILITY_OBJECTS)
55 |
56 | # Compile Objects
57 | $(UTILITY_OBJECTS):
58 | $(CC) $(CFLAGS) -c $(subst $(BIN),$(UTILITY), $(@:.o=.cpp)) -o $@ $(INCLUDE)
59 |
60 |
61 | # Compile Targets
62 | $(UTILITY_TEST_TARGETS) : $(DEPEND)
63 | $(CC) $(CFLAGS) -o $(BIN)$@ $(TEST)$@.cpp $^ $(INCLUDE) $(LDFLAGS)
64 |
65 | ###########################################################################
66 | ## Crypto
67 | ###########################################################################
68 |
69 | CRYPTO_SOURCES = /blind_rsa.cpp /ec.cpp /encrypt.cpp /hash.cpp /random.cpp
70 | CRYPTO_OBJECTS = $(subst /,$(BIN),$(CRYPTO_SOURCES:.cpp=.o))
71 | CRYPTO_TEST_TARGETS = blind_rsa_test ec_test encrypt_test hash_test
72 | DEPEND += $(CRYPTO_OBJECTS)
73 |
74 | # Compile Objects
75 | $(CRYPTO_OBJECTS):
76 | $(CC) $(CFLAGS) -c $(subst $(BIN),$(CRYPTO), $(@:.o=.cpp)) -o $@ $(INCLUDE)
77 |
78 |
79 | # Compile Targets
80 | $(CRYPTO_TEST_TARGETS) : $(DEPEND)
81 | $(CC) $(CFLAGS) -o $(BIN)$@ $(TEST)$@.cpp $^ $(INCLUDE) $(LDFLAGS)
82 |
83 | ###########################################################################
84 | ## Protocol Dependencies
85 | ###########################################################################
86 |
87 | SCC_SOURCES = /scc.cpp /tx.cpp
88 | SCC_OBJECTS = $(subst /,$(BIN),$(SCC_SOURCES:.cpp=.o))
89 | SCC_TEST_TARGETS = scc_test
90 | DEPEND += $(SCC_OBJECTS)
91 |
92 | # Compile Objects
93 | $(SCC_OBJECTS):
94 | $(CC) $(CFLAGS) -c $(subst $(BIN),$(SOURCE), $(@:.o=.cpp)) -o $@ $(INCLUDE)
95 |
96 |
97 | # Compile Targets
98 | $(SCC_TEST_TARGETS) : $(DEPEND)
99 | $(CC) $(CFLAGS) -o $(BIN)$@ $(TEST)$@.cpp $^ $(INCLUDE) $(LDFLAGS)
100 |
101 | ###########################################################################
102 | ## Client -- Alice & Bob (same machine)
103 | ###########################################################################
104 |
105 | CLIENT_SOURCES = /alice.cpp /alice_client.cpp /bob.cpp
106 | CLIENT_OBJECTS = $(subst /,$(BIN),$(CLIENT_SOURCES:.cpp=.o))
107 | CLIENT_TARGETS = bob_client alice_client_test
108 |
109 | # Compile Objects
110 | $(CLIENT_OBJECTS):
111 | $(CC) $(CFLAGS) -c $(subst $(BIN),$(SOURCE), $(@:.o=.cpp)) -o $@ $(INCLUDE)
112 |
113 |
114 | # Compile Targets
115 | $(CLIENT_TARGETS) : $(DEPEND) $(CLIENT_OBJECTS)
116 | $(CC) $(CFLAGS) -o $(BIN)$@ $(SOURCE)$@.cpp $^ $(INCLUDE) $(LDFLAGS)
117 |
118 | ###########################################################################
119 | ## Server -- The Tumbler System
120 | ###########################################################################
121 |
122 | SERVER_SOURCES = /tumbler.cpp /signer.cpp
123 | SERVER_OBJECTS = $(subst /,$(BIN),$(SERVER_SOURCES:.cpp=.o))
124 | SERVER_TARGETS = tumbler_server signer_server
125 |
126 | # Compile Objects
127 | $(SERVER_OBJECTS):
128 | $(CC) $(CFLAGS) -c $(subst $(BIN),$(SOURCE), $(@:.o=.cpp)) -o $@ $(INCLUDE)
129 |
130 |
131 | # Compile Targets
132 | $(SERVER_TARGETS) :$(DEPEND) $(SERVER_OBJECTS)
133 | $(CC) $(CFLAGS) -o $(BIN)$@ $(SOURCE)$@.cpp $^ $(INCLUDE) $(LDFLAGS)
134 |
135 | ###########################################################################
136 | ## Other Targets
137 | ###########################################################################
138 |
139 | clean:
140 | rm -rf $(BIN)*
141 |
--------------------------------------------------------------------------------
/POC_code/python/tx_server.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | from tx import *
3 |
4 | # stdlib
5 | import time
6 | import signal
7 | import hashlib
8 | import binascii
9 |
10 | # 3rd Party
11 | import zmq
12 | from bitcoin import SelectParams
13 |
14 | ###########################################################################
15 | ## SETTINGS
16 | ###########################################################################
17 |
18 |
19 | LOCK_TIME = 6
20 | N_HASHES = 15
21 | HASH_LEN = 20
22 | TUMBLER_ADDRESS = "mzaMTvKBDiYoqkHaDz3w7AmHHETHEQKUiWs"
23 | AMOUNT = 0.001
24 | FEE = 0.0006
25 | MINE_FEE = 0.0001
26 |
27 | AMOUNT_FUND = AMOUNT + FEE
28 |
29 | tx_o = TX(test=True)
30 | # tx_o = TX()
31 |
32 | ###########################################################################
33 | ## HELPERS
34 | ###########################################################################
35 |
36 |
37 | def error(n, e):
38 | return "Wrong number of arguments" + \
39 | "got %d expected %d" % (n, e)
40 |
41 |
42 | def get_keys_from_tx(socket, msg):
43 | e = 2
44 | if len(msg) != e:
45 | socket.send(error(len(msg), e))
46 | return
47 |
48 | keys = tx_o.get_keys_from_tx(msg[1], N_HASHES)
49 | serial_keys = tx_o.serialize_list(keys)
50 |
51 | socket.send(serial_keys)
52 | return
53 |
54 | ###########################################################################
55 | ## PREIMAGE
56 | ###########################################################################
57 |
58 |
59 | def setup_preimage(socket, msg):
60 | e = 4
61 | if len(msg) != e:
62 | socket.send(error(len(msg), e))
63 | return
64 |
65 | hashes = tx_o.get_hashes_from_serial(msg[3], N_HASHES,
66 | HASH_LEN)
67 |
68 | amount2 = AMOUNT + FEE
69 | result = tx_o.setup_preimage(msg[1], msg[2], hashes, amount2,
70 | LOCK_TIME)
71 | reply = [result[0], result[1], result[2], result[3]]
72 |
73 | socket.send_multipart(reply)
74 | return
75 |
76 |
77 | def spend_preimage(socket, msg):
78 | e = 5
79 | if len(msg) != e:
80 | socket.send(error(len(msg), e))
81 | return
82 |
83 | keys = tx_o.get_keys_from_serial(msg[1])
84 | tx = tx_o.spend_preimage(keys, msg[2], msg[3], msg[4])
85 |
86 | socket.send(tx)
87 | return
88 |
89 | ###########################################################################
90 | ## ESCROW
91 | ###########################################################################
92 |
93 |
94 | def setup_escrow(socket, msg):
95 | e = 3
96 | if len(msg) != e:
97 | socket.send(error(len(msg), e))
98 | return
99 |
100 | result = tx_o.setup_escrow(msg[1], msg[2], AMOUNT, LOCK_TIME)
101 | reply = [result[0], result[1], result[2], result[3]]
102 |
103 | socket.send_multipart(reply)
104 | return
105 |
106 |
107 | def spend_escrow(socket, msg):
108 | e = 5
109 | if len(msg) != e:
110 | socket.send(error(len(msg), e))
111 | return
112 |
113 | tx = tx_o.spend_escrow(msg[1], msg[2], msg[3], msg[4])
114 | socket.send(tx)
115 | return
116 |
117 |
118 | def spend_escrow_with_address(socket, msg):
119 | e = 6
120 | if len(msg) != e:
121 | socket.send(error(len(msg), e))
122 | return
123 |
124 | # 1 - payer_sig, 2 - redeemer_sig
125 | # 3 - address, 4 - redeem_script
126 | # 5 - funding_tx_id
127 |
128 | temp_tx, _ = tx_o.get_tx(msg[4], msg[3],
129 | AMOUNT - MINE_FEE, msg[5])
130 | tx = tx_o.spend_escrow(msg[1], msg[2], temp_tx, msg[4])
131 |
132 | socket.send(tx)
133 | return
134 |
135 | ###########################################################################
136 | ## GET TX
137 | ###########################################################################
138 |
139 |
140 | def get_tx_with_address(socket, msg):
141 | e = 3
142 | if len(msg) != e:
143 | socket.send(error(len(msg), e))
144 | return
145 |
146 | address = get_btc_address()[0]
147 | _, sighash = tx_o.get_tx(msg[1], address,
148 | AMOUNT - MINE_FEE, msg[2])
149 | reply = [sighash, address]
150 |
151 | socket.send_multipart(reply)
152 | return
153 |
154 |
155 | def get_tx_with_vout(socket, msg):
156 | e = 5
157 | if len(msg) != e:
158 | socket.send(error(len(msg), e))
159 | return
160 |
161 | _, sighash = tx_o.get_tx(msg[1], msg[2],
162 | AMOUNT - MINE_FEE, msg[3], vout=msg[4])
163 |
164 | reply = [sighash, address]
165 | socket.send_multipart(reply)
166 | return
167 |
168 |
169 | def get_tx(socket, msg):
170 | e = 5
171 | if len(msg) != e:
172 | socket.send(error(len(msg), e))
173 | return
174 |
175 | if msg[4] == "preimage":
176 | amount = AMOUNT - (2 * MINE_FEE)
177 | print "PREIAMGE"
178 | else:
179 | amount = AMOUNT - MINE_FEE
180 |
181 | tx, sighash = tx_o.get_tx(msg[1], msg[2],
182 | amount, msg[3])
183 |
184 | reply = [tx, sighash]
185 | socket.send_multipart(reply)
186 |
187 | ###########################################################################
188 | ## REFUND
189 | ###########################################################################
190 |
191 |
192 | def get_tx_refund(socket, msg):
193 | if len(msg) != 5:
194 | error = "Wrong number of arguments to %s, " + \
195 | "got %d expected 4" % (msg[0], len(msg))
196 | socket.send(error)
197 |
198 | print "Lock time is %d" % int(msg[4])
199 |
200 | # Check to see if it's preimage tx
201 | if len(msg[1]) > 300:
202 | amount = AMOUNT - (2 * MINE_FEE)
203 | else:
204 | amount = AMOUNT - MINE_FEE
205 |
206 | tx, sighash = tx_o.get_tx(msg[1], msg[2],
207 | amount, msg[3],
208 | lock_time=int(msg[4]))
209 |
210 | reply = [tx, sighash]
211 | socket.send_multipart(reply)
212 | return
213 |
214 |
215 | def get_refund_tx_with_vout(socket, msg):
216 | e = 6
217 | if len(msg) != e:
218 | socket.send(error(len(msg), e))
219 | return
220 |
221 | tx, sighash = tx_o.get_tx(msg[1], msg[2],
222 | amount, msg[3],
223 | lock_time=int(msg[4]), vout=msg[5])
224 |
225 | reply = [tx, sighash]
226 | socket.send_multipart(reply)
227 | return
228 |
229 |
230 | def send_refund_tx(socket, msg):
231 | e = 4
232 | if len(msg) != e:
233 | socket.send(error(len(msg), e))
234 | return
235 |
236 | tx = tx_o.refund_tx(msg[1], msg[2], msg[3])
237 | socket.send(tx)
238 | return
239 |
240 | ###########################################################################
241 | ## MAIN
242 | ###########################################################################
243 |
244 | options = {
245 | "setup_preimage": setup_preimage,
246 | "spend_preimage": spend_preimage,
247 | "setup_escrow": setup_escrow,
248 | "spend_escrow": spend_escrow,
249 | "spend_escrow_with_address": spend_escrow_with_address,
250 | "get_tx_with_address": get_tx_with_address,
251 | "get_tx": get_tx,
252 | "get_tx_refund": get_tx_refund,
253 | "send_refund_tx": send_refund_tx,
254 | "get_keys_from_tx": get_keys_from_tx,
255 | "get_refund_tx_with_vout": get_refund_tx_with_vout,
256 | "get_tx_with_vout": get_tx_with_vout
257 | }
258 |
259 |
260 | def main():
261 |
262 | SelectParams('testnet')
263 |
264 | context = zmq.Context()
265 | socket = context.socket(zmq.REP)
266 | socket.bind("ipc:///tmp/TumbleBit_tx")
267 |
268 | try:
269 | while True:
270 |
271 | msg = socket.recv_multipart()
272 | # print "Received message %s" % msg
273 | if msg[0] in options:
274 | print "Entering -> %s" % msg[0]
275 | options[msg[0]](socket, msg)
276 | print "Exiting -> %s" % msg[0]
277 | else:
278 | # printf
279 | socket.send(b"METHOD NOT AVAILABLE")
280 | except KeyboardInterrupt:
281 | print "Interrupt received. Stoping ...."
282 | finally:
283 | # Clean up
284 | socket.close()
285 | context.term()
286 |
287 |
288 | if __name__ == "__main__":
289 | main()
290 |
--------------------------------------------------------------------------------
/POC_code/python/tx_test.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # TODO: Add unit tests
3 |
4 | # stdlib
5 | import hashlib
6 | import binascii
7 |
8 | # 3rd part
9 | import zmq
10 | from bitcoin import SelectParams
11 | from bitcoin.core.key import CECKey
12 |
13 | # Local
14 | from tx import TX
15 |
16 |
17 | ###############################################################################
18 | ## Helpers for Testing
19 | ###############################################################################
20 |
21 |
22 | def ripemd160(msg):
23 | h = hashlib.new('ripemd160')
24 | h.update(msg)
25 | return h.digest()
26 |
27 |
28 | def sha256(msg):
29 | h = hashlib.sha256()
30 | h.update(msg)
31 | return h.digest()
32 |
33 | ###############################################################################
34 | ## Server Tests
35 | ###############################################################################
36 |
37 |
38 | def preimage_client():
39 |
40 | # Setup socket
41 | context = zmq.Context()
42 | socket = context.socket(zmq.REQ)
43 | socket.connect("ipc:///tmp/TumbleBit_tx")
44 |
45 | # Setup keys
46 | data = open("./keys/EC_private_test.bin", "rb").read()
47 | alice = CECKey()
48 | alice.set_privkey(data)
49 |
50 | data = open("./keys/EC_private_test2.bin", "rb").read()
51 | bob = CECKey()
52 | bob.set_privkey(data)
53 |
54 | # Setup Images & Hashes
55 | preimages = [(sha256("test" + str(x)))[:16] for x in range(1, 16)]
56 | hashes = [ripemd160(x) for x in preimages]
57 |
58 | serial_hashes = ""
59 | for i in range(len(hashes)):
60 | serial_hashes += hashes[i]
61 |
62 | serial_preimages = ""
63 | for i in range(len(preimages)):
64 | serial_preimages += preimages[i]
65 |
66 | # Phase 1 -- Setup
67 | msg = [b"setup_preimage", alice.get_pubkey(), bob.get_pubkey(),
68 | serial_hashes]
69 | socket.send_multipart(msg)
70 |
71 | reply = socket.recv_multipart()
72 | redeem_script = reply[0]
73 | fund_tx = reply[1]
74 |
75 | # print "Done with PHASE1"
76 |
77 | # Phase 2 -- Get TX sighash
78 | address = "mweZnPjTeyGHVS2d3SojAGujY36sd3wQ49"
79 |
80 | msg = [b"get_tx", redeem_script, address, fund_tx]
81 | socket.send_multipart(msg)
82 |
83 | reply = socket.recv_multipart()
84 | tx = reply[0]
85 | sighash = reply[1]
86 |
87 | # print "Done with PHASE2"
88 |
89 | # Sign
90 | alice_sig = alice.sign(sighash) # Used for refund
91 | bob_sig = bob.sign(sighash) # Used for redeem
92 |
93 | # Phase 3 -- Spending tx
94 | msg = [b"spend_preimage", serial_preimages, bob_sig, tx, redeem_script]
95 | socket.send_multipart(msg)
96 |
97 | reply = socket.recv()
98 | spending_tx = reply
99 |
100 | # print "Done with PHASE3"
101 |
102 | # Phase 4 -- Refunding tx
103 | msg = [b"send_refund_tx", alice_sig, tx, redeem_script]
104 | socket.send_multipart(msg)
105 |
106 | reply = socket.recv()
107 | refund_tx = reply
108 |
109 | # print "Done with PHASE4"
110 |
111 | print "PREIMAGE: Spending tx is: %s" % binascii.hexlify(spending_tx)
112 | print "\n\n"
113 | print "PREIMAGE: Refund tx is: %s" % binascii.hexlify(refund_tx)
114 |
115 | # Clean up
116 | socket.close()
117 | context.term()
118 |
119 |
120 | def escrow_client():
121 | # Setup socket
122 | context = zmq.Context()
123 | socket = context.socket(zmq.REQ)
124 | socket.connect("ipc:///tmp/TumbleBit_tx")
125 |
126 | # Setup keys
127 | data = open("./keys/EC_private_test.bin", "rb").read()
128 | alice = CECKey()
129 | alice.set_privkey(data)
130 |
131 | data = open("./keys/EC_private_test2.bin", "rb").read()
132 | bob = CECKey()
133 | bob.set_privkey(data)
134 |
135 | # Phase 1 -- Setup
136 | msg = [b"setup_escrow", alice.get_pubkey(), bob.get_pubkey()]
137 | socket.send_multipart(msg)
138 |
139 | reply = socket.recv_multipart()
140 | redeem_script = reply[0]
141 | fund_tx = reply[1]
142 |
143 | # print "Done with PHASE1"
144 |
145 | # Phase 2 -- Get TX sighash
146 | address = "mweZnPjTeyGHVS2d3SojAGujY36sd3wQ49"
147 |
148 | msg = [b"get_tx", redeem_script, address, fund_tx]
149 | socket.send_multipart(msg)
150 |
151 | reply = socket.recv_multipart()
152 | tx = reply[0]
153 | sighash = reply[1]
154 |
155 | # print "Done with PHASE2"
156 |
157 | # Sign
158 | alice_sig = alice.sign(sighash)
159 | bob_sig = bob.sign(sighash)
160 |
161 | # Phase 3 -- Spending tx
162 | msg = [b"spend_escrow", alice_sig, bob_sig, tx, redeem_script]
163 | socket.send_multipart(msg)
164 |
165 | reply = socket.recv()
166 | spending_tx = reply
167 |
168 | # print "Done with PHASE3"
169 |
170 | # Phase 4 -- Refunding tx
171 | msg = [b"send_refund_tx", alice_sig, tx, redeem_script]
172 | socket.send_multipart(msg)
173 |
174 | reply = socket.recv()
175 | refund_tx = reply
176 |
177 | # print "Done with PHASE4"
178 |
179 | print "ESCROW: Spending tx is: %s" % binascii.hexlify(spending_tx)
180 | print "\n\n"
181 | print "ESCROW: Refund tx is: %s" % binascii.hexlify(refund_tx)
182 |
183 | # Clean up
184 | socket.close()
185 | context.term()
186 |
187 | ###############################################################################
188 | ## Module Tests
189 | ###############################################################################
190 |
191 |
192 | def preimage_example():
193 | '''
194 | Refund test:
195 | P2SH Address:
196 | 2MscMqe6Ag5NmZKCsELKDPJRJWnPR6GGD9B
197 |
198 | Funding tx:
199 | d49038dd9141f77c230208fe1cdd24937c61a1b63f40b8a87ab50971970ac2b7
200 | Spending tx nlocktime = 10:
201 |
202 | Refund TX:
203 | f77245db1c81b49c72464e61e3738a60f6e21c0bb744f8729def4a9877082e73
204 |
205 | Preimage test:
206 | P2SH Address:
207 | 2NEFkj2gMZguX3QtFp31XKfnRdUpEoXTVNv
208 |
209 | Funding tx:
210 | 91e6953fdcc15687ffc54e76d55ed4b92ef60cd483e0633ef226f7509513c7d2
211 | Spending tx nlocktime = 10:
212 |
213 | Spending TX:
214 | e006b7d1566045e136c13446114e51513f1453a7e2eb7e534d04bd7dc09532f7
215 |
216 | Other:
217 | 1/
218 | P2SH Address: 2N6uq4bLT6UTqqxNo7YQ5TyRrFVWSRAFyxT
219 | Funding TX:
220 | 8f717d1babd532b337cb80e743844f270129c744ebfc1ff7f6b43c1d855adc75
221 | Spending TX:
222 | b9cfbbdef00319db95c0beae8f73de4f7639eacc9b2006a70d64b494673921eb
223 |
224 | '''
225 | SelectParams('testnet')
226 |
227 | tx = TX(test=True)
228 |
229 | print "=" * 50
230 | print ("=" * 10 + " PREIMAGE EXAMPLE")
231 | print "=" * 50 + "\n"
232 |
233 | # Setup keys
234 | data = open("./keys/EC_private_test.bin", "rb").read()
235 | alice = CECKey()
236 | alice.set_privkey(data)
237 |
238 | data = open("./keys/EC_private_test2.bin", "rb").read()
239 | bob = CECKey()
240 | bob.set_privkey(data)
241 |
242 | preimages = [sha256("test" + str(x)) for x in range(1, 16)]
243 | hashes = [ripemd160(x) for x in preimages]
244 |
245 | # Serialize hashes
246 | serial_hashes = ""
247 | for i in range(len(hashes)):
248 | serial_hashes += hashes[i]
249 | tx.get_hashes_from_serial(serial_hashes, 15, 20)
250 |
251 | amount = 0.001 # In bitcoins
252 | redeem_script, funding_tx = tx.setup_preimage(alice.get_pubkey(),
253 | bob.get_pubkey(), hashes,
254 | amount, 10)
255 |
256 | # Funding tx id + redeeming bitcoin address
257 | funding_tx = "8f717d1babd532b337cb80e743844f270" + \
258 | "129c744ebfc1ff7f6b43c1d855adc75"
259 | address = "mweZnPjTeyGHVS2d3SojAGujY36sd3wQ49"
260 |
261 | # Note: Make sure pick correct vout - default is 0
262 | tx2, sighash = tx.get_tx(redeem_script, address,
263 | amount - 0.0001, funding_tx, 5)
264 |
265 | # Sign
266 | alice_sig = alice.sign(sighash)
267 | bob_sig = bob.sign(sighash)
268 |
269 | redeem_tx = tx.spend_preimage(preimages, bob_sig, tx2, redeem_script)
270 | print "REDEEM TX is:\n%s\n" % binascii.hexlify(redeem_tx)
271 |
272 | refunded_tx = tx.refund_tx(alice_sig, tx2, redeem_script)
273 | print "REFUND TX is:\n%s\n" % binascii.hexlify(refunded_tx)
274 |
275 | serial_keys = tx.get_keys_from_tx(redeem_tx)
276 | # print "SERIAL KEYS:\n%s\n" % binascii.hexlify(serial_keys)
277 |
278 | # # write to file to test in c++
279 | # target = open("keys.bin", 'wb')
280 | # target.write(serial_keys)
281 | # target.close()
282 |
283 | print "=" * 50 + "\n\n"
284 |
285 |
286 | def escrow_example():
287 | '''
288 | P2SH Address:
289 | 2MzDcMCxcZnNnAZzFqsyuyZ4vuNCB6Qjvxd
290 |
291 | Funding tx:
292 | db1b045ea09581a51a5b5f851e7e3a64542123885e071fd6d4ff7428703a2504
293 | Spending tx nlocktime = 30:
294 |
295 | Refund TX:
296 | 23daa9d3868255bab14d5dfe46f7fb787aaef49b17d0014902e36e4491440311
297 | '''
298 | SelectParams('testnet')
299 |
300 | tx = TX(test=True)
301 |
302 | print "=" * 50
303 | print ("=" * 10 + " ESCROW EXAMPLE")
304 | print "=" * 50 + "\n"
305 |
306 | # Setup keys
307 | data = open("./keys/EC_private_test.bin", "rb").read()
308 | alice = CECKey()
309 | alice.set_privkey(data)
310 |
311 | data = open("./keys/EC_private_test2.bin", "rb").read()
312 | bob = CECKey()
313 | bob.set_privkey(data)
314 |
315 | amount = 0.001 # In bitcoins
316 |
317 | redeem_script, p2sh_address = tx.setup_escrow(alice.get_pubkey(),
318 | bob.get_pubkey(), amount, 30)
319 |
320 | # Funding tx id + redeeming bitcoin address
321 | funding_tx = "db1b045ea09581a51a5b5f851e7e3a6" + \
322 | "4542123885e071fd6d4ff7428703a2504"
323 | address = "mweZnPjTeyGHVS2d3SojAGujY36sd3wQ49"
324 |
325 | # Note: Make sure pick correct vout - default is 0
326 | tx2, sighash = tx.get_tx(redeem_script, address,
327 | amount - 0.0001, funding_tx, 20, vout=1)
328 |
329 | # Sign
330 | alice_sig = alice.sign(sighash)
331 | bob_sig = bob.sign(sighash)
332 |
333 | print "P2SH %s" % p2sh_address
334 | print "Redeem script:\n%s\n" % binascii.hexlify(redeem_script)
335 | print "Redeem script Hash:\n%s\n" % binascii.hexlify(sha256(sha256(redeem_script)))
336 |
337 | redeem_tx = tx.spend_escrow(alice_sig, bob_sig, tx2, redeem_script)
338 | print "REDEEM TX is:\n%s\n" % binascii.hexlify(redeem_tx)
339 |
340 | refunded_tx = tx.refund_tx(alice_sig, tx2, redeem_script)
341 | print "REFUND TX is:\n%s\n" % binascii.hexlify(refunded_tx)
342 | print "=" * 50 + "\n\n"
343 |
344 |
345 | ###############################################################################
346 | ## MAIN
347 | ###############################################################################
348 |
349 |
350 | def main():
351 | escrow_example()
352 | # preimage_example()
353 | # preimage_client()
354 | # escrow_client()
355 |
356 | if __name__ == '__main__':
357 | main()
358 |
--------------------------------------------------------------------------------
/POC_code/requirements.txt:
--------------------------------------------------------------------------------
1 | python-bitcoinlib
2 | simplejson
3 | pyzmq
4 | pycrypto
5 |
--------------------------------------------------------------------------------
/POC_code/src/alice_client.cpp:
--------------------------------------------------------------------------------
1 | #include "timer.h"
2 | #include "alice_client.h"
3 |
4 | class Alice_Client : public SCC_Interface {
5 |
6 | private:
7 | Alice alice;
8 |
9 | // Network
10 | zmq::socket_t& socket;
11 |
12 | std::vector requests; // Received
13 | std::vector reply; // Sent
14 |
15 | Bin* address;
16 |
17 | public:
18 |
19 | Alice_Client(zmq::socket_t& s, Bin* y, char* address_str): alice(y), socket(s){
20 |
21 | socket.connect(SIGNER_SERVER_SOCKET);
22 |
23 | init();
24 | this->y = y;
25 |
26 | address = new Bin(strlen(address_str));
27 | memcpy(address->data, address_str, address->len);
28 | }
29 |
30 | Alice_Client(zmq::socket_t& s, Bin* y): alice(y), socket(s){
31 |
32 | socket.connect(SIGNER_SERVER_SOCKET);
33 |
34 | init();
35 | this->y = y;
36 |
37 | address = new Bin(strlen(TUMBLER_ADDRESS));
38 | memcpy(address->data, TUMBLER_ADDRESS, address->len);
39 | }
40 |
41 | ~Alice_Client(){
42 |
43 | delete address;
44 | };
45 |
46 | bool start(){
47 |
48 | alice.set_party_address(address);
49 |
50 | //=====================================
51 | // SCC Protocol
52 | //=====================================
53 |
54 | Timer timer = Timer((char *) "scc_protocol\0");
55 | timer.start();
56 |
57 | if (!exchange_public_key()){
58 | printf("Failed in exchange_public_key\n");
59 | return false;
60 | }
61 |
62 | if (!commitment()){
63 | printf("Failed in commitment\n");
64 | return false;
65 | }
66 |
67 | if (!verify_fakes()){
68 | printf("Failed in verify_fakes\n");
69 | return false;
70 | }
71 |
72 | if (!verify_reals()){
73 | printf("Failed in verify_reals\n");
74 | return false;
75 | }
76 |
77 | if(!get_decryption_from_tx()){
78 | printf("Failed in get_decryption_from_tx\n");
79 | return false;
80 | }
81 |
82 | timer.end();
83 |
84 | return true;
85 | }
86 |
87 | Bin* get_decryption(){
88 | return alice.get_y_sk();
89 | }
90 |
91 | protected:
92 |
93 | bool exchange_public_key(){
94 |
95 | Bin* temp = new Bin(19);
96 | memcpy(temp->data, "exchange_public_key", 19);
97 |
98 | requests.push_back(temp);
99 | send(socket, requests);
100 |
101 | delete temp;
102 | requests.clear();
103 |
104 | receive(socket, reply);
105 | if(reply.size() != 2){
106 | free_Bins(reply);
107 | reply.clear();
108 | return false;
109 | }
110 |
111 | signer_pubkey = reply.at(0);
112 | alice.set_party_pubkey(signer_pubkey);
113 | alice.set_rsa(reply.at(1));
114 |
115 | if(!alice.setup_escrow_tx()){
116 | printf("Failed in setup escrow\n");
117 | return false;
118 | }
119 |
120 | delete reply.at(1);
121 | reply.clear();
122 | phase_0 = true;
123 | return true;
124 | }
125 |
126 | bool commitment(){
127 |
128 | Bin* temp = new Bin(10);
129 | memcpy(temp->data, "commitment", 10);
130 |
131 | Bin *b_set = new Bin();
132 | std::vector blinded_set = *alice.get_blinded_set();
133 |
134 | if (!serialize_vector(b_set, blinded_set, (N + M), alice.rsa_len)){
135 | return false;
136 | }
137 |
138 | requests.push_back(temp);
139 | requests.push_back(b_set);
140 | requests.push_back(alice.get_escrow_redeem_script());
141 | requests.push_back(alice.get_escrow_funding_tx_id());
142 | send(socket, requests);
143 |
144 | // free_Bins(requests);
145 | delete temp;
146 | delete b_set;
147 | requests.clear();
148 |
149 | receive(socket, reply);
150 | if(reply.size() != 2){
151 | free_Bins(reply);
152 | reply.clear();
153 | return false;
154 | }
155 |
156 | if (!deserialize_vector(reply.at(0), C, M + N, alice.rsa_len + 8)){
157 | return false;
158 | }
159 |
160 | if (!deserialize_vector(reply.at(1), H, M + N, HASH_160)){
161 | return false;
162 | }
163 |
164 | alice.set_C(C);
165 | alice.set_H(H);
166 |
167 | free_Bins(reply);
168 | reply.clear();
169 |
170 | phase_1 = true;
171 | return true;
172 | }
173 |
174 | bool verify_fakes(){
175 |
176 | if(!alice.setup_preimage_tx()){
177 | printf("Failed in setup preimage\n");
178 | return false;
179 | }
180 |
181 | Bin *r = new Bin();
182 | Bin *f = new Bin();
183 |
184 | R = alice.get_R();
185 | F = alice.get_F();
186 |
187 | Bin* temp = new Bin(12);
188 | memcpy(temp->data, "verify_fakes", 12);
189 |
190 | if (!serialize_int_vector(r, R, M)){
191 | delete r;
192 | return false;
193 | }
194 |
195 | if (!serialize_int_vector(f, F, N)){
196 | delete f;
197 | return false;
198 | }
199 |
200 | Bin* fake_blinds = new Bin();
201 | if (!serialize_vector(fake_blinds, *alice.get_fake_blinds(), N , alice.rsa_len)){
202 | return false;
203 | }
204 |
205 | requests.push_back(temp);
206 | requests.push_back(f);
207 | requests.push_back(r);
208 | requests.push_back(fake_blinds);
209 | requests.push_back(alice.get_preimage_P2SH());
210 | send(socket, requests);
211 |
212 | // Cleanup
213 | delete temp;
214 | delete f;
215 | delete r;
216 | delete fake_blinds;
217 | requests.clear();
218 |
219 | receive(socket, reply);
220 | if(reply.size() != 2){
221 | free_Bins(reply);
222 | reply.clear();
223 | return false;
224 | }
225 |
226 | if (!deserialize_vector(reply.at(0), fake_keys, N, KEY_LEN)){
227 | return false;
228 | }
229 |
230 | if(!alice.verify_preimage_signature(reply.at(1))){
231 | return false;
232 | }
233 |
234 | if (!alice.verify_keys(fake_keys)){
235 | return false;
236 | }
237 |
238 | free_Bins(reply);
239 | reply.clear();
240 |
241 | phase_2 = true;
242 | return true;
243 | }
244 |
245 | bool verify_reals(){
246 |
247 | Bin* temp = new Bin(12);
248 | memcpy(temp->data, "verify_reals", 12);
249 |
250 |
251 | Bin* real_blinds = new Bin();
252 | if (!serialize_vector(real_blinds, *alice.get_real_blinds(), M , alice.rsa_len)){
253 | return false;
254 | }
255 |
256 | Bin* sig = alice.get_preimage_signature();
257 | if(sig == NULL){
258 | printf("Failed in get signature\n");
259 | return false;
260 | }
261 |
262 |
263 | requests.push_back(temp);
264 | requests.push_back(alice.get_preimage_redeem_script());
265 | requests.push_back(sig);
266 | requests.push_back(y);
267 | requests.push_back(real_blinds);
268 | send(socket, requests);
269 |
270 | delete temp;
271 | delete real_blinds;
272 | requests.clear();
273 |
274 | receive(socket, reply);
275 | if(reply.size() != 1){
276 | free_Bins(reply);
277 | reply.clear();
278 | return false;
279 | }
280 |
281 | serial_real_keys = reply.at(0);
282 | if(!deserialize_vector(serial_real_keys, real_keys, M, KEY_LEN)){
283 | printf("Failed in deserialize_keys\n");
284 | return false;
285 | }
286 |
287 | delete reply.at(0);;
288 | reply.clear();
289 | return true;
290 | }
291 |
292 | bool get_decryption_from_tx(){
293 |
294 | Timer timer = Timer((char *) "scc_decryption\0");
295 | timer.start();
296 |
297 | alice.set_real_keys(real_keys);
298 | if(!alice.get_decryption()){
299 | printf("Failed in alice.get_decryption\n");
300 | return false;
301 | }
302 |
303 | Bin* temp = new Bin(16);
304 | memcpy(temp->data, "escrow_signature", 16);
305 |
306 | requests.push_back(temp);
307 | requests.push_back(alice.get_escrow_signature());
308 |
309 | send(socket, requests);
310 | delete temp;
311 | requests.clear();
312 |
313 | receive(socket, reply);
314 | if(reply.size() != 1){
315 | free_Bins(reply);
316 | reply.clear();
317 | return false;
318 | }
319 | free_Bins(reply);
320 | reply.clear();
321 |
322 | timer.end();
323 |
324 |
325 | phase_4 = true;
326 | return true;
327 | }
328 |
329 | };
330 |
331 | bool get_decryption(Bin* y, Bin* y_sk){
332 |
333 | if(!defined(y) || y_sk == NULL){
334 | return false;
335 | }
336 |
337 | zmq::context_t context(1);
338 | zmq::socket_t socket(context, ZMQ_REQ);
339 |
340 |
341 | Alice_Client alice_client = Alice_Client(socket, y);
342 | if(!alice_client.start()){
343 | return false;
344 | }
345 |
346 | Bin* decryption = alice_client.get_decryption();
347 | if (!defined(decryption)){
348 | return false;
349 | }
350 |
351 | // Copy result
352 | y_sk->len = decryption->len;
353 | y_sk->data = (unsigned char *) malloc(y_sk->len);
354 | memcpy(y_sk->data, decryption->data, y_sk->len);
355 |
356 | return true;
357 | }
358 |
--------------------------------------------------------------------------------
/POC_code/src/alice_client_test.cpp:
--------------------------------------------------------------------------------
1 | #define BOOST_TEST_DYN_LINK
2 | #define BOOST_TEST_MODULE alice_client
3 | #include
4 |
5 | #include "alice_client.h"
6 |
7 |
8 | BOOST_AUTO_TEST_CASE(client){
9 |
10 | bool status;
11 |
12 | // Setup RSA
13 | RSA * rsa = get_public_rsa(2048, (char *)"tumbler");
14 | BOOST_REQUIRE_MESSAGE(rsa != NULL, "test_alice_client: Failed load RSA key");
15 | int rsa_len = RSA_size(rsa);
16 |
17 | Bin* y_sk = new Bin();
18 |
19 | // Create epsilon
20 | Bin* epsilon = new Bin();
21 | Bin *y = new Bin(rsa_len);
22 | epsilon->len = rsa_len;
23 | epsilon->data = get_random(rsa_len * 8, rsa->n);
24 |
25 | // Encrypt epsilon
26 | int s = RSA_public_encrypt(rsa_len, epsilon->data, y->data, rsa, RSA_NO_PADDING);
27 | BOOST_REQUIRE_MESSAGE(s != -1, "test_alice_client: Failed to create e^pk");
28 |
29 | status = get_decryption(y, y_sk);
30 | BOOST_REQUIRE_MESSAGE(status == true, "test_alice_client: Failed to get decryption");
31 |
32 |
33 | BOOST_REQUIRE_MESSAGE(*y_sk == *epsilon, "test_alice_client: Decryption is invalid!");
34 | printf("Success!\n");
35 |
36 | // Cleanup
37 | delete y;
38 | delete y_sk;
39 | delete epsilon;
40 | RSA_free(rsa);
41 | }
42 |
--------------------------------------------------------------------------------
/POC_code/src/bob_client.cpp:
--------------------------------------------------------------------------------
1 | #include "bob.h"
2 | #include "alice_client.h"
3 | #include "network.h"
4 | #include "scc_wrapper_interface.h"
5 | #include "timer.h"
6 |
7 | class Bob_client: SCC_Wrapper_Interface {
8 |
9 | private:
10 | Bob bob;
11 |
12 | // Network
13 | zmq::socket_t& socket;
14 |
15 | std::vector requests; // Sent
16 | std::vector reply; // Received
17 |
18 | std::vector C;
19 | std::vector Z;
20 | std::vector quotients;
21 | std::vector fake_epsilons;
22 |
23 |
24 | Bin* redeem_script;
25 | Bin* funding_tx_id;
26 | Bin* pub_key;
27 |
28 | public:
29 |
30 | Bob_client(zmq::socket_t& s): socket(s){
31 |
32 | socket.connect(TUMBLER_SERVER_SOCKET);
33 |
34 | }
35 |
36 | ~Bob_client(){
37 |
38 | delete_bin(redeem_script);
39 | delete_bin(funding_tx_id);
40 | delete_bin(pub_key);
41 |
42 | free_Bins(C);
43 | free_Bins(Z);
44 | free_Bins(fake_epsilons);
45 | free_Bins(quotients);
46 |
47 | };
48 |
49 | bool start(){
50 | Timer timer = Timer((char *) "wrapper_protocol\0");
51 | timer.start();
52 |
53 | //=====================================
54 | // SCC Wrapper Protocol
55 | //=====================================
56 | if (!exchange()){
57 | printf("Failed in exchange\n");
58 | return false;
59 | }
60 |
61 | if (!commitment()){
62 | printf("Failed in commitment\n");
63 | return false;
64 | }
65 |
66 | if (!verify()){
67 | printf("Failed in verify\n");
68 | return false;
69 | }
70 | timer.end();
71 |
72 | if(!post()){
73 | printf("Failed in post\n");
74 | return false;
75 | }
76 |
77 | return true;
78 | }
79 |
80 | protected:
81 |
82 | bool exchange(){
83 |
84 | Bin* temp = new Bin(8);
85 | memcpy(temp->data, "exchange", 8);
86 |
87 | Bin* bob_pubkey = bob.get_pubkey();
88 |
89 | requests.push_back(temp);
90 | requests.push_back(bob_pubkey);
91 | send(socket, requests);
92 |
93 | delete temp;
94 | requests.clear();
95 |
96 | receive(socket, reply);
97 |
98 | if(reply.size() != 4){
99 | free_Bins(reply);
100 | reply.clear();
101 | return false;
102 | }
103 |
104 | pub_key = reply.at(0);
105 | redeem_script = reply.at(2);
106 | funding_tx_id = reply.at(3);
107 |
108 | bob.set_party_pubkey(pub_key);
109 | bob.set_rsa(reply.at(1));
110 | bob.set_redeem_script(redeem_script);
111 | bob.set_funding_tx_id(funding_tx_id);
112 |
113 |
114 | delete reply.at(1);
115 |
116 | reply.clear();
117 |
118 | return true;
119 | }
120 |
121 | bool commitment(){
122 |
123 | Bin* temp = new Bin(10);
124 | memcpy(temp->data, "commitment", 10);
125 |
126 | Bin *tx_set = new Bin();
127 | if (!serialize_vector(tx_set, *bob.get_tx_set(), (2 * K), HASH_256)){
128 | return false;
129 | }
130 |
131 | requests.push_back(temp);
132 | requests.push_back(tx_set);
133 | requests.push_back(bob.get_h_r());
134 | requests.push_back(bob.get_h_f());
135 | send(socket, requests);
136 |
137 | delete temp;
138 | delete tx_set;
139 | requests.clear();
140 |
141 |
142 | receive(socket, reply);
143 | if(reply.size() != 2){
144 | free_Bins(reply);
145 | reply.clear();
146 | return false;
147 | }
148 |
149 |
150 | if (!deserialize_vector(reply.at(0), C, 2 * K, HASH_512)){
151 | return false;
152 | }
153 |
154 | if (!deserialize_vector(reply.at(1), Z, 2 * K, bob.rsa_len)){
155 | return false;
156 | }
157 |
158 | free_Bins(reply);
159 | reply.clear();
160 |
161 | return true;
162 | }
163 |
164 | bool verify(){
165 |
166 | Bin *R = new Bin();
167 | Bin *F = new Bin();
168 | Bin *fake_tx = new Bin();
169 |
170 | std::vectorr = bob.get_R();
171 | std::vectorf = bob.get_F();
172 |
173 | Bin* temp = new Bin(6);
174 | memcpy(temp->data, "verify", 6);
175 |
176 | if (!serialize_int_vector(R, r, K)){
177 | delete R;
178 | return false;
179 | }
180 |
181 | if (!serialize_int_vector(F, f, K)){
182 | delete F;
183 | return false;
184 | }
185 |
186 |
187 | if (!serialize_vector(fake_tx, *bob.get_fake_tx(), K, HASH_256)){
188 | return false;
189 | }
190 |
191 | requests.push_back(temp);
192 | requests.push_back(R);
193 | requests.push_back(F);
194 | requests.push_back(fake_tx);
195 | requests.push_back(bob.get_salt());
196 | send(socket, requests);
197 |
198 | requests.pop_back();
199 | free_Bins(requests);
200 | requests.clear();
201 |
202 | receive(socket, reply);
203 | if(reply.size() != 2){
204 | free_Bins(reply);
205 | reply.clear();
206 | return false;
207 | }
208 |
209 |
210 | if (!deserialize_vector(reply.at(0), quotients, K - 1, bob.rsa_len)){
211 | return false;
212 | }
213 |
214 | if (!deserialize_vector(reply.at(1), fake_epsilons, K, bob.rsa_len)){
215 | return false;
216 | }
217 |
218 | if (!bob.verify_recieved_data(Z, C, fake_epsilons, quotients)){
219 | return false;
220 | }
221 |
222 | free_Bins(reply);
223 | reply.clear();
224 |
225 | return true;
226 | }
227 |
228 | bool post(){
229 |
230 | Bin* W = bob.get_W();
231 |
232 | Bin* epsiolon = new Bin();
233 | if (!get_decryption(W, epsiolon)){
234 | return false;
235 | }
236 |
237 |
238 | bob.set_recovered_epsilon(epsiolon);
239 | if(!bob.post_tx()){
240 | return false;
241 | }
242 |
243 | Bin* tx = bob.get_tx_fulfill();
244 | printf("\n\nTX fulfill is:\n");
245 | tx->print();
246 | printf("\n\n");
247 |
248 | // Cleanup
249 | delete epsiolon;
250 |
251 | return true;
252 | }
253 |
254 | };
255 |
256 | int main () {
257 |
258 | zmq::context_t context(1);
259 | zmq::socket_t socket(context, ZMQ_REQ);
260 |
261 | Timer timer = Timer((char *) "total\0");
262 | timer.start();
263 |
264 |
265 | Bob_client bob_client = Bob_client(socket);
266 | bob_client.start();
267 |
268 | timer.end();
269 | printf("Total:\n");
270 | timer.print();
271 |
272 | }
273 |
--------------------------------------------------------------------------------
/POC_code/src/crypto/encrypt.cpp:
--------------------------------------------------------------------------------
1 | #include "encrypt.h"
2 |
3 | //============================================================================
4 | //====== XOR Functions
5 | //============================================================================
6 |
7 | bool encrypt(Bin* plain_text, Bin *key, Bin* cipher_text){
8 |
9 | if (!defined(plain_text) || !defined(key) ||
10 | plain_text->len != 64 || cipher_text == NULL){
11 | return false;
12 | }
13 |
14 | // Hash
15 | Bin *temp_h = new Bin(HASH_512);
16 | SHA512(key->data, key->len, temp_h->data);
17 |
18 | // Decrypt
19 | cipher_text->len = plain_text->len;
20 | cipher_text->data = XOR_enc_dec(plain_text, temp_h, plain_text->len);
21 |
22 | delete temp_h;
23 |
24 | return true;
25 | }
26 |
27 | bool decrypt(Bin* cipher_text, Bin *key, Bin* plain_text){
28 |
29 | if (!defined(key) || !defined(cipher_text) ||
30 | cipher_text->len != 64 || plain_text == NULL){
31 | return false;
32 | }
33 |
34 | // Hash
35 | Bin *temp_h = new Bin(HASH_512);
36 | SHA512(key->data, key->len, temp_h->data);
37 |
38 | // Decrypt
39 | plain_text->len = cipher_text->len;
40 | plain_text->data = XOR_enc_dec(cipher_text, temp_h, cipher_text->len);
41 |
42 | delete temp_h;
43 |
44 | return true;
45 | }
46 |
47 | unsigned char * XOR_enc_dec(Bin* m, Bin* k, int len){
48 | if (m->len != k->len){
49 | return NULL;
50 | }
51 |
52 | unsigned char * result = (unsigned char *) tmalloc(len * sizeof(unsigned char));
53 | for (int i = 0; i < len; i++){
54 | result[i] = m->data[i] ^ k->data[i];
55 | }
56 | return result;
57 | }
58 |
59 | //============================================================================
60 | //====== CHACHA Functions
61 | //============================================================================
62 |
63 | bool encrypt_chacha(Bin* plain_text, Bin *key, Bin* cipher_text){
64 |
65 | if (!defined(plain_text) || key == NULL || plain_text == NULL){
66 | return false;
67 | }
68 |
69 | key->len = KEY_LEN;
70 | key->data = get_random(KEY_LEN * 8);
71 |
72 | Bin iv = Bin();
73 | iv.len = 8;
74 | iv.data = get_random(8*8);
75 |
76 | Bin cipher = Bin(plain_text->len);
77 |
78 | // Encrypt
79 | chacha(&cipher, plain_text, key, &iv);
80 |
81 | cipher_text->len = plain_text->len + 8;
82 | cipher_text->data = (unsigned char *) malloc(cipher_text->len);
83 | memcpy(cipher_text->data, iv.data, 8);
84 | memcpy(cipher_text->data + 8, cipher.data, plain_text->len);
85 |
86 | return true;
87 | }
88 |
89 | bool decrypt_chacha(Bin* cipher_text, Bin *key, Bin* plain_text){
90 |
91 | if (!defined(key) || !defined(cipher_text) || plain_text == NULL){
92 | return false;
93 | }
94 |
95 | Bin iv = Bin(8);
96 | Bin cipher = Bin(cipher_text->len - 8);
97 |
98 | memcpy(iv.data, cipher_text->data, 8);
99 | memcpy(cipher.data, cipher_text->data + 8, cipher.len);
100 |
101 |
102 | // Decrypt sig
103 | plain_text->len = cipher.len;
104 | plain_text->data = (unsigned char *) tmalloc(cipher.len);
105 | chacha(plain_text, &cipher, key, &iv);
106 |
107 | return true;
108 | }
109 |
110 | bool chacha(Bin* out, Bin* in, Bin* key, Bin* iv){
111 | if (out == NULL || !defined(in) || !defined(key) || key->len != 16 || !defined(iv)){
112 | return false;
113 | }
114 |
115 | ChaCha_ctx ctx;
116 |
117 | ChaCha_set_key(&ctx, key->data, 128);
118 | ChaCha_set_iv(&ctx, iv->data, NULL);
119 | ChaCha(&ctx, out->data, in->data, in->len);
120 |
121 | return true;
122 | }
123 |
--------------------------------------------------------------------------------
/POC_code/src/crypto/hash.cpp:
--------------------------------------------------------------------------------
1 | #include "hash.h"
2 |
3 | Bin* full_domain_hash(RSA *rsa, Bin* msg, const EVP_MD *hash){
4 | if (!defined(msg) || hash == NULL || rsa == NULL){
5 | return NULL;
6 | }
7 |
8 | int mask_len = BN_num_bytes(rsa->n);
9 | unsigned char * mask = (unsigned char *) tmalloc(mask_len);
10 | mask[0] = 0;
11 |
12 | // Had a problem with sizeof(mask) - 1, since mask has changed to a pointer
13 | if (PKCS1_MGF1(mask + 1, mask_len - 1, msg->data, msg->len, hash) != 0) {
14 | printf("FDH failed.\n");
15 | return NULL;
16 | }
17 |
18 | Bin* h = new Bin();
19 | h->len = mask_len;
20 | h->data = mask;
21 |
22 | return h;
23 | }
24 |
25 | Bin* hash256(Bin* msg){
26 | Bin* hash = new Bin(HASH_256);
27 | Bin* temp_hash = new Bin(HASH_256);
28 |
29 | SHA256(msg->data, msg->len, temp_hash->data);
30 | SHA256(temp_hash->data, temp_hash->len, hash->data);
31 |
32 | delete temp_hash;
33 |
34 | return hash;
35 | }
36 |
37 | Bin* hmac256(Bin* msg, Bin* key){
38 |
39 | Bin* output = new Bin(32);
40 |
41 | if(HMAC(EVP_sha256(),key->data, key->len, msg->data, msg->len,
42 | output->data, NULL) == NULL){
43 | return NULL;
44 | }
45 |
46 | return output;
47 | }
48 |
--------------------------------------------------------------------------------
/POC_code/src/crypto/random.cpp:
--------------------------------------------------------------------------------
1 | #include "random.h"
2 |
3 | unsigned char * get_random(int bits){
4 | BN_CTX *ctx;
5 | BIGNUM *r = NULL;
6 | unsigned char * r_str = NULL;
7 | int r_len;
8 |
9 | ctx = BN_CTX_new();
10 | if (ctx == NULL) {
11 | printf("get_random: Couldn't get new CTX\n");
12 | return NULL;
13 | }
14 | BN_CTX_start(ctx);
15 | r = BN_CTX_get(ctx);
16 |
17 | //https://www.openssl.org/docs/manmaster/crypto/BN_rand.html
18 | int s = BN_rand(r, bits, 0, 1);
19 | if (s == 0) {
20 | printf("get_random: Couldn't generate random number\n");
21 | return NULL;
22 | }
23 |
24 | r_len = BN_num_bytes(r);
25 | r_str = (unsigned char *) tmalloc(r_len);
26 | BN_bn2bin(r, r_str);
27 |
28 | BN_free(r);
29 | BN_CTX_end(ctx);
30 | BN_CTX_free(ctx);
31 |
32 | return r_str;
33 | }
34 |
35 | unsigned char * get_random(int bits, BIGNUM *n){
36 | BN_CTX *ctx;
37 | BIGNUM *r = NULL;
38 | unsigned char * r_str = NULL;
39 |
40 | ctx = BN_CTX_new();
41 | if (ctx == NULL) {
42 | printf("get_random: Couldn't get new CTX\n");
43 | return NULL;
44 | }
45 | BN_CTX_start(ctx);
46 | r = BN_CTX_get(ctx);
47 |
48 | //https://www.openssl.org/docs/manmaster/crypto/BN_rand.html
49 | int s = BN_rand_range(r, n);
50 | if (s == 0) {
51 | printf("get_random: Couldn't generate random number\n");
52 | return NULL;
53 | }
54 |
55 | BN_num_bytes(r);
56 | r_str = (unsigned char *) tmalloc(bits / 8);
57 | BNToBin(r, r_str, bits / 8);
58 |
59 | BN_free(r);
60 | BN_CTX_end(ctx);
61 | BN_CTX_free(ctx);
62 |
63 | return r_str;
64 | }
65 |
--------------------------------------------------------------------------------
/POC_code/src/scc.cpp:
--------------------------------------------------------------------------------
1 | #include "scc.h"
2 |
3 | //============================================================================
4 |
5 | bool apply_blinds(Bin* message, std::vector &blinds, std::vector &blinded){
6 | int r;
7 | Bin* temp;
8 | for (unsigned int i = 0; i < blinds.size(); i++){
9 | temp = new Bin(message->len);
10 | r = blind(blinds.at(i), message, temp);
11 | if (r == 1){
12 | blinded.push_back(temp);
13 | }
14 | else {
15 | // Something went wrong
16 | return false;
17 | }
18 | }
19 |
20 | return true;
21 | }
22 |
23 | bool remove_blinds(std::vector &blinded, int len, std::vector &blinds,
24 | std::vector &unblinded){
25 |
26 | int r;
27 | Bin* temp;
28 | for (unsigned int i = 0; i < blinds.size(); i++){
29 | temp = new Bin(len);
30 | r = unblind(blinds.at(i), blinded.at(i), temp);
31 | if (r == 1){
32 | blinded.push_back(temp);
33 | }
34 | else {
35 | // Something went wrong
36 | return false;
37 | }
38 | }
39 |
40 | return true;
41 | }
42 |
43 | bool create_blinds(RSA * rsa, int n, std::vector &blinds){
44 | BN_BLINDING * b;
45 | for (int i=0; i < n; i++){
46 | b = setup_blinding(rsa);
47 | // b = setup_blinding_deterministic(rsa);
48 | if (b != NULL){
49 | blinds.push_back(b);
50 | }
51 | else {
52 | printf("Couldn't generate blind.");
53 | return false;
54 | }
55 | }
56 |
57 | return true;
58 | }
59 |
60 |
61 | //============================================================================
62 |
63 | int shuffle_random (int i) { return std::rand()%i;}
64 |
65 |
66 | bool find_indices(std::vector &in, std::vector &what, std::vector &indices)
67 | {
68 | std::vector::iterator iter;
69 | size_t id;
70 | for (unsigned int i = 0; i < what.size(); i++){
71 | pointer_equal predicate = {what.at(i)};
72 | iter = std::find_if(in.begin(),in.end(), predicate);
73 | id = iter - in.begin();
74 | indices.push_back(id);
75 | }
76 |
77 | return true;
78 | }
79 |
80 |
81 | //============================================================================
82 |
83 | // N is the number of items
84 | bool serialize_vector(Bin* serial, std::vector& vec, int n, int len){
85 | if (vec.size() != (unsigned int) n){
86 | printf("serialize_vector: Vec size is %lu, expected %d", vec.size(), n);
87 | return false;
88 | }
89 |
90 | serial->len = n * len;
91 | serial->data = (unsigned char *) tmalloc(serial->len);
92 |
93 | unsigned char *p = serial->data;
94 | for(int i=0; i < n; i++){
95 |
96 | memcpy(p, vec.at(i)->data, len);
97 | p = p + len;
98 | }
99 |
100 | return true;
101 | }
102 |
103 | // N is the number of items
104 | bool deserialize_vector(Bin* serial, std::vector& vec, int n, int len){
105 | if (serial== NULL || serial->len != (len * n)){
106 | return false;
107 | }
108 |
109 | Bin *temp = NULL;
110 | unsigned char *p = serial->data;
111 | for(int i=0; i < n; i++){
112 | temp = new Bin(len);
113 | memcpy(temp->data, p + (len * i), len);
114 | vec.push_back(temp);
115 | }
116 |
117 | return true;
118 | }
119 |
120 | // N is the number of items
121 | bool serialize_int_vector(Bin* serial, std::vector& vec, int n){
122 | if (vec.size() != (unsigned int) n){
123 | printf("serialize_vector: Vec size is %lu, expected %d", vec.size(), n);
124 | return false;
125 | }
126 |
127 | int len = sizeof(int);
128 | serial->len = n * len;
129 | serial->data = (unsigned char *) tmalloc(serial->len);
130 |
131 | unsigned char *p = serial->data;
132 | for(int i=0; i < n; i++){
133 |
134 | memcpy(p, &vec.at(i), len);
135 | p = p + len;
136 | }
137 |
138 | return true;
139 | }
140 |
141 | // N is the number of items
142 | bool deserialize_int_vector(Bin* serial, std::vector& vec, int n){
143 |
144 | int len = sizeof(int);
145 | if (serial== NULL || serial->len != (len * n)){
146 | return false;
147 | }
148 |
149 | int temp;
150 | unsigned char *p = serial->data;
151 | for(int i=0; i < n; i++){
152 | memcpy(&temp, p + (len * i), len);
153 | vec.push_back(temp);
154 | }
155 |
156 | return true;
157 | }
158 |
159 |
160 | //============================================================================
161 |
--------------------------------------------------------------------------------
/POC_code/src/signer_server.cpp:
--------------------------------------------------------------------------------
1 | #include "signer.h"
2 | #include "strings.h"
3 | #include "network.h"
4 | #include "tx.h"
5 | #include
6 |
7 | //============================================================================
8 | //======= PROTOCOL
9 | //============================================================================
10 |
11 | bool exchange_public_key(Signer &signer, std::vector& requests, std::vector& reply){
12 |
13 | if (requests.size() != 1){
14 | return false;
15 | }
16 |
17 | reply.push_back(signer.get_pubkey());
18 | reply.push_back(signer.get_rsa());
19 |
20 | return true;
21 | }
22 |
23 | bool commitment(Signer &signer, std::vector& requests, std::vector& reply, std::vector& blinded_set){
24 |
25 | if (requests.size() != 4){
26 | return false;
27 | }
28 |
29 | // Deserialize
30 | if (!deserialize_vector(requests.at(1), blinded_set, M + N, signer.rsa_len)){
31 | return false;
32 | }
33 |
34 | signer.set_escrow_redeem_script(requests.at(2));
35 | signer.set_escrow_funding_tx_id(requests.at(3));
36 |
37 | delete requests.at(0);
38 | delete requests.at(1);
39 |
40 | // Sign
41 | if (!signer.sign_blinded_set(blinded_set)){
42 | return false;
43 | }
44 |
45 | // Serialize
46 | Bin* C = new Bin();
47 | if (!serialize_vector(C, *signer.get_C(), M + N, signer.rsa_len + 8)){
48 | return false;
49 | }
50 |
51 | Bin* H = new Bin();
52 | if (!serialize_vector(H, *signer.get_H(), M + N, HASH_160)){
53 | return false;
54 | }
55 |
56 | reply.push_back(C);
57 | reply.push_back(H);
58 |
59 | return true;
60 | }
61 |
62 | bool verify_fakes(Signer &signer, std::vector& requests, std::vector& reply, std::vector& R){
63 |
64 | if (requests.size() != 5){
65 | return false;
66 | }
67 |
68 | // Deserialize to int vectors
69 | std::vector F;
70 |
71 | if(!deserialize_int_vector(requests.at(1), F, N)){
72 | return false;
73 | }
74 |
75 | if(!deserialize_int_vector(requests.at(2), R, M)){
76 | return false;
77 | }
78 |
79 | std::vector fake_blinds;
80 | if (!deserialize_vector(requests.at(3), fake_blinds, N, signer.rsa_len)){
81 | return false;
82 | }
83 |
84 | signer.set_preimage_P2SH(requests.at(4));
85 | requests.pop_back();
86 |
87 | // Verify
88 | if (!signer.verify_fakes(fake_blinds, F)){
89 | return false;
90 | }
91 |
92 | // Serialize
93 | Bin* fake_keys = new Bin();
94 | if (!serialize_vector(fake_keys, *signer.get_fake_keys(), N, KEY_LEN)){
95 | return false;
96 | }
97 |
98 | reply.push_back(fake_keys);
99 | reply.push_back(signer.get_escrow_preimage_signature());
100 |
101 | free_Bins(fake_blinds);
102 | return true;
103 | }
104 |
105 | bool verify_reals(Signer &signer, std::vector& requests, std::vector& reply, std::vector& R){
106 |
107 | if (requests.size() != 5){
108 | return false;
109 | }
110 |
111 | signer.set_preimage_redeem_script(requests.at(1));
112 | signer.set_preimage_signature(requests.at(2));
113 | Bin* y = requests.at(3);
114 |
115 | std::vector real_blinds;
116 | if (!deserialize_vector(requests.at(4), real_blinds, M, signer.rsa_len)){
117 | return false;
118 | }
119 |
120 | delete requests.at(4);
121 |
122 |
123 | if(!signer.verify_reals(y, real_blinds, R)){
124 | printf("Failed in verify\n");
125 | return false;
126 | }
127 |
128 | Bin* real_keys = new Bin();
129 | if (!serialize_vector(real_keys, *signer.get_real_keys(), M, KEY_LEN)){
130 | return false;
131 | }
132 |
133 | reply.push_back(real_keys);
134 |
135 | // Cleanup
136 | free_Bins(real_blinds);
137 |
138 | return true;
139 | }
140 |
141 | //============================================================================
142 | //======= MAIN
143 | //============================================================================
144 |
145 | int main () {
146 |
147 | // Prepare our context and socket
148 | zmq::context_t context(1);
149 | zmq::socket_t socket(context, ZMQ_REP);
150 | socket.bind("tcp://*:5558");
151 |
152 | zmq::message_t fail_msg;
153 | fail_msg.rebuild(26);
154 | memcpy(fail_msg.data(), "Failed to process request.", 26);
155 |
156 | // Handle interrupt
157 | s_catch_signals();
158 |
159 | std::vector requests; // Received
160 | std::vector reply; // Sent
161 |
162 | Signer* signer;
163 | std::vector blinded_set;
164 | std::vector R;
165 |
166 |
167 | /*
168 | * Not a multithreaded server.
169 | * Will definitly not work correctly
170 | * if multiple clients try to connect
171 | * during a run of the Protocol
172 | * TODO: Turn into multithreaded socket server
173 | * or multithreaded http server after getting
174 | * 1000 tx's through.
175 | */
176 | while(true) {
177 |
178 | try{
179 |
180 | receive(socket, requests);
181 | if(memcmp(requests.at(0)->data, "exchange_public_key", 19) == 0){
182 |
183 | signer = new Signer();
184 |
185 | if(!exchange_public_key(*signer, requests, reply)){
186 | printf("Exchange failed\n");
187 | socket.send(fail_msg);
188 | }else{
189 | send(socket, reply);
190 | }
191 |
192 | free_Bins(requests);
193 |
194 | } else if(memcmp(requests.at(0)->data, "commitment", 10) == 0){
195 |
196 | if(signer == NULL || !commitment(*signer, requests, reply, blinded_set)){
197 | printf("Commitment failed\n");
198 | socket.send(fail_msg);
199 | free_Bins(blinded_set);
200 | R.clear();
201 | blinded_set.clear();
202 | delete signer;
203 | free_Bins(requests);
204 | }else{
205 | send(socket, reply);
206 | free_Bins(reply);
207 | }
208 |
209 | } else if(memcmp(requests.at(0)->data, "verify_fakes", 12) == 0){
210 |
211 | if(signer == NULL || !verify_fakes(*signer, requests, reply, R)){
212 | printf("verify_fakes failed\n");
213 | delete signer;
214 | socket.send(fail_msg);
215 |
216 | free_Bins(blinded_set);
217 | R.clear();
218 | blinded_set.clear();
219 | }else{
220 | send(socket, reply);
221 | delete reply.at(0);
222 | }
223 |
224 | free_Bins(requests);
225 |
226 | } else if(memcmp(requests.at(0)->data, "verify_reals", 12) == 0){
227 |
228 | if(signer == NULL || !verify_reals(*signer, requests, reply, R)){
229 | printf("verify_reals failed\n");
230 | socket.send(fail_msg);
231 |
232 | free_Bins(blinded_set);
233 | R.clear();
234 | blinded_set.clear();
235 | }else{
236 | send(socket, reply);
237 | free_Bins(reply);
238 | }
239 |
240 | } else if(memcmp(requests.at(0)->data, "escrow_signature", 16) == 0){
241 |
242 | if(signer == NULL){
243 | printf("escrow_signature failed\n");
244 | socket.send(fail_msg);
245 | }else{
246 | signer->set_escrow_signature(requests.at(1));
247 | socket.send(fail_msg);
248 | }
249 |
250 | delete signer;
251 | free_Bins(blinded_set);
252 | R.clear();
253 | blinded_set.clear();
254 | }
255 |
256 | reply.clear();
257 | requests.clear();
258 | } catch(zmq::error_t& e) {
259 | printf("\nZMQ Error: %s\n", e.what());
260 | free_Bins(requests);
261 | break;
262 | }
263 |
264 |
265 | }
266 |
267 | free_Bins(requests);
268 |
269 | return 0;
270 | }
271 |
--------------------------------------------------------------------------------
/POC_code/src/test/bin_test.cpp:
--------------------------------------------------------------------------------
1 | #define BOOST_TEST_DYN_LINK
2 | #define BOOST_TEST_MODULE bin
3 |
4 | #include "bin.h"
5 | #include "utility.h"
6 |
7 | #include
8 |
9 | BOOST_AUTO_TEST_CASE(test_empty_constructor){
10 |
11 | Bin b = Bin();
12 |
13 | // Define
14 | int msg_len = 13;
15 | unsigned char *msg = (unsigned char *) malloc(msg_len - 1);
16 |
17 | memcpy(msg, "Test Message", msg_len - 1);
18 |
19 | b.data = msg;
20 | b.len = msg_len - 1;
21 |
22 | BOOST_REQUIRE_MESSAGE(memcmp(msg, b.data, b.len) == 0, "test_empty_constructor: Doesn't point to same memory");
23 | }
24 |
25 | BOOST_AUTO_TEST_CASE(test_int_constructor){
26 |
27 | // Define
28 | int msg_len = 13;
29 | Bin b = Bin(msg_len - 1);
30 | memcpy(b.data, "Test Message", b.len);
31 |
32 |
33 | BOOST_REQUIRE_MESSAGE(memcmp("Test Message", b.data, b.len) == 0, "test_int_constructor: Doesn't point to same memory");
34 | }
35 |
36 | BOOST_AUTO_TEST_CASE(test_full_constructor){
37 |
38 | // Define
39 | int msg_len = 13;
40 | unsigned char *msg = (unsigned char *) malloc(msg_len - 1);
41 | memcpy(msg, "Test Message", msg_len - 1);
42 |
43 | Bin b = Bin(msg_len - 1, msg);
44 |
45 | BOOST_REQUIRE_MESSAGE(memcmp(msg, b.data, b.len) == 0, "test_full_constructor: Doesn't point to same memory");
46 | }
47 |
48 | BOOST_AUTO_TEST_CASE(test_serialize){
49 |
50 | unsigned char expected[] = {0x0c, 0x00, 0x00, 0x00, 0x54, 0x65, 0x73, 0x74, 0x20, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65};
51 |
52 | // Define
53 | int msg_len = 13;
54 | Bin b = Bin(msg_len - 1);
55 | memcpy(b.data, "Test Message", b.len);
56 |
57 |
58 | unsigned char *serial = b.serialize();
59 |
60 | BOOST_REQUIRE_MESSAGE(memcmp(expected, serial, b.len + sizeof(int)) == 0, "test_serialize: Doesn't point to same memory");
61 |
62 | free(serial);
63 | }
64 |
65 | BOOST_AUTO_TEST_CASE(test_equality){
66 |
67 | Bin b = Bin();
68 | Bin b1 = Bin();
69 | Bin b2 = Bin();
70 |
71 | // Define
72 | int msg_len = 13;
73 | unsigned char *msg = (unsigned char *) malloc(msg_len - 1);
74 | unsigned char *msg1 = (unsigned char *) malloc(msg_len - 1);
75 | unsigned char *msg2 = (unsigned char *) malloc(msg_len - 1);
76 |
77 | memcpy(msg, "Test Message", msg_len - 1);
78 | memcpy(msg1, "Test Message", msg_len - 1);
79 | memcpy(msg2, "TEST MESSAGE", msg_len - 1);
80 |
81 | b.len = msg_len - 1;
82 | b.data = msg;
83 |
84 | b1.len = b.len;
85 | b1.data = msg1;
86 |
87 | b2.len = b.len;
88 | b2.data = msg2;
89 |
90 |
91 | BOOST_REQUIRE_MESSAGE( b == b1, "test_equality: b1 & b should be equal");
92 | BOOST_REQUIRE_MESSAGE( b != b2, "test_equality: b2 & b shouldn't be equal");
93 | }
94 |
--------------------------------------------------------------------------------
/POC_code/src/test/ec_test.cpp:
--------------------------------------------------------------------------------
1 | #define BOOST_TEST_DYN_LINK
2 | #define BOOST_TEST_MODULE EC_Test
3 |
4 | #include "ec.h"
5 | #include
6 |
7 | BOOST_AUTO_TEST_CASE(test_key_generation){
8 |
9 | bool status;
10 |
11 | // Generate new ec key
12 | const char *suffix = "test";
13 | status = generate_EC_key(suffix, suffix);
14 |
15 | BOOST_REQUIRE_MESSAGE(status == true, "test_key_generation: Failed to generate EC key");
16 |
17 | // Try to read key
18 | EC_KEY *key = get_ec_key_by_suffix(suffix, true);
19 |
20 | BOOST_REQUIRE_MESSAGE(key != NULL, "test_key_generation: Failed to get private EC key");
21 |
22 | EC_KEY_free(key);
23 | }
24 |
25 | BOOST_AUTO_TEST_CASE(test_sign_verify)
26 | {
27 | // Get private key
28 | const char *suffix = "test";
29 | EC_KEY * key = get_ec_key_by_suffix(suffix, true);
30 |
31 | BOOST_REQUIRE_MESSAGE(key != NULL, "test_sign_verify: Failed to get private EC key");
32 |
33 | // Sign
34 | Bin hash = Bin(32);
35 | memcpy(hash.data, "c7fbca202a95a570285e3d700eb04ca2", hash.len);
36 |
37 | ECDSA_SIG * signature = EC_sign(key, &hash);
38 |
39 | BOOST_REQUIRE_MESSAGE(signature != NULL, "test_sign_verify: Failed to sign message");
40 |
41 | // Cleanup
42 | EC_KEY_free(key);
43 |
44 | // Get key
45 | key = get_ec_key_by_suffix(suffix, false);
46 |
47 | BOOST_REQUIRE_MESSAGE(key != NULL, "test_sign_verify: Failed get public EC key");
48 |
49 | // Verify
50 | bool s = EC_verify(key, &hash, signature);
51 |
52 | BOOST_REQUIRE_MESSAGE(s == true, "test_sign_verify: Failed to verify signature");
53 |
54 | // Serialize + deserialize
55 | Bin serial = Bin();
56 |
57 | s = serialize_ec_signature(signature, &serial);
58 | BOOST_REQUIRE_MESSAGE(s == true, "test_sign_verify: Failed serialize signature");
59 |
60 | // printf("serial signature is:\n");
61 | // serial.print();
62 |
63 | ECDSA_SIG *sig2;
64 | sig2 = deserialize_ec_signature(&serial);
65 | BOOST_REQUIRE_MESSAGE(sig2 != NULL, "test_sign_verify: Failed to deserialize signature");
66 |
67 | // Verify
68 | s = EC_verify(key, &hash, sig2);
69 |
70 | BOOST_REQUIRE_MESSAGE(s == true, "test_sign_verify: Failed to verify signature after serialization");
71 |
72 | // Cleanup
73 | ECDSA_SIG_free(signature);
74 | ECDSA_SIG_free(sig2);
75 | EC_KEY_free(key);
76 |
77 | }
78 |
79 | BOOST_AUTO_TEST_CASE(test_sig_convert)
80 | {
81 | // Get private key
82 | const char *suffix = "test";
83 | EC_KEY * key = get_ec_key_by_suffix(suffix, true);
84 |
85 | BOOST_REQUIRE_MESSAGE(key != NULL, "test_sign_verify: Failed to get private EC key");
86 |
87 | // Sign
88 | Bin hash = Bin(32);
89 | memcpy(hash.data, "c7fbca202a95a570285e3d700eb04ca2", hash.len);
90 |
91 | // printf("Hash is:\n");
92 | // hash.print();
93 |
94 | ECDSA_SIG * signature = EC_sign(key, &hash);
95 |
96 | BOOST_REQUIRE_MESSAGE(signature != NULL, "test_sign_verify: Failed to sign message");
97 |
98 | // Convert sig to standard format
99 | convert_sig_to_standard_der(signature, key);
100 |
101 |
102 | // Cleanup
103 | EC_KEY_free(key);
104 |
105 | // Get key
106 | key = get_ec_key_by_suffix(suffix, false);
107 |
108 | BOOST_REQUIRE_MESSAGE(key != NULL, "test_sign_verify: Failed get public EC key");
109 |
110 | // Verify
111 | bool s = EC_verify(key, &hash, signature);
112 |
113 | BOOST_REQUIRE_MESSAGE(s == true, "test_sign_verify: Failed to verify signature");
114 |
115 | // Cleanup
116 | ECDSA_SIG_free(signature);
117 | EC_KEY_free(key);
118 |
119 | }
120 |
121 |
122 | BOOST_AUTO_TEST_CASE(test_sig_serialize)
123 | {
124 | // Get private key
125 | const char *suffix = "test";
126 | EC_KEY * key = get_ec_key_by_suffix(suffix, true);
127 |
128 | BOOST_REQUIRE_MESSAGE(key != NULL, "test_sig_serialize: Failed to get private EC key");
129 |
130 | // Sign
131 | Bin hash = Bin(32);
132 | memcpy(hash.data, "c7fbca202a95a570285e3d700eb04ca2", hash.len);
133 |
134 | // printf("Hash is:\n");
135 | // hash.print();
136 |
137 | ECDSA_SIG * signature = EC_sign(key, &hash);
138 |
139 | BOOST_REQUIRE_MESSAGE(signature != NULL, "test_sig_serialize: Failed to sign message");
140 |
141 | // Cleanup
142 | EC_KEY_free(key);
143 |
144 | // Get key
145 | key = get_ec_key_by_suffix(suffix, false);
146 |
147 | BOOST_REQUIRE_MESSAGE(key != NULL, "test_sig_serialize: Failed get public EC key");
148 |
149 | // Verify
150 | bool s = EC_verify(key, &hash, signature);
151 |
152 | BOOST_REQUIRE_MESSAGE(s == true, "test_sig_serialize: Failed to verify signature");
153 |
154 | // Serialize + deserialize
155 | Bin serial = Bin();
156 |
157 | s = serialize_ec_signature(signature,& serial);
158 | BOOST_REQUIRE_MESSAGE(s == true, "test_sig_serialize: Failed serialize signature");
159 |
160 | ECDSA_SIG *sig2;
161 | sig2 = deserialize_ec_signature(&serial);
162 | BOOST_REQUIRE_MESSAGE(sig2 != NULL, "test_sig_serialize: Failed to deserialize signature");
163 |
164 | // Verify
165 | s = EC_verify(key, &hash, sig2);
166 |
167 | BOOST_REQUIRE_MESSAGE(s == true, "test_sig_serialize: Failed to verify signature after serialization");
168 |
169 | // Cleanup
170 | ECDSA_SIG_free(signature);
171 | ECDSA_SIG_free(sig2);
172 | EC_KEY_free(key);
173 | }
174 |
175 | BOOST_AUTO_TEST_CASE(test_no_nonce_reuse)
176 | {
177 |
178 | const char *suffix = "test";
179 | EC_KEY * key = get_ec_key_by_suffix(suffix, true);
180 |
181 | // Sign
182 | Bin hash1 = Bin(32);
183 | memcpy(hash1.data, "19ebca000095a201285e3d7002204edf", hash1.len);
184 |
185 | Bin hash2 = Bin(32);
186 | memcpy(hash2.data, "19ebca000095a201285e3d7002204edf", hash2.len);
187 |
188 | ECDSA_SIG * signature1 = EC_sign(key, &hash1);
189 | ECDSA_SIG * signature2 = EC_sign(key, &hash2);
190 |
191 | Bin serial1 = Bin();
192 | Bin serial2 = Bin();
193 |
194 | serialize_ec_signature(signature1, &serial1);
195 | serialize_ec_signature(signature2, &serial2);
196 |
197 | BOOST_CHECK_MESSAGE(memcmp(serial1.data, serial2.data, 32)!=0, "ECDSA nonces should not be the same");
198 |
199 |
200 | // Cleanup
201 | ECDSA_SIG_free(signature1);
202 | ECDSA_SIG_free(signature2);
203 | EC_KEY_free(key);
204 | }
205 |
206 | BOOST_AUTO_TEST_CASE(test_key_from_secret)
207 | {
208 |
209 | Bin* secret = new Bin(20);
210 | memcpy(secret->data, "TumbleBit_4241304455", secret->len);
211 | EC_KEY * key = get_key_from_secret(secret);
212 |
213 | Bin* pubkey = new Bin();
214 | bool status = serialize_ec_publickey(key, pubkey);
215 | BOOST_CHECK_MESSAGE(status, "test_key_from_secret: Failed to serialize public key");
216 |
217 |
218 | char* pubkey_str = get_hex_str(pubkey);
219 | char* expected = (char *) "046ee5d82c7fece37c8f98f36bc619d2484e643ac10cb59df4ae9d4ae76816105ce2c85f960ad2726e058be242bc3b94e12c8ad033b9432ccb98fa61433557d933";
220 |
221 |
222 | BOOST_CHECK_MESSAGE(strcmp(pubkey_str, expected) == 0, "test_key_from_secret: Public keys don't match");
223 |
224 | delete pubkey;
225 | delete secret;
226 | free(pubkey_str);
227 | EC_KEY_free(key);
228 | }
229 |
--------------------------------------------------------------------------------
/POC_code/src/test/encrypt_test.cpp:
--------------------------------------------------------------------------------
1 | #define BOOST_TEST_DYN_LINK
2 | #define BOOST_TEST_MODULE encrypt_test
3 |
4 | #include "encrypt.h"
5 | #include
6 |
7 | BOOST_AUTO_TEST_CASE(test_encrypt_xor){
8 |
9 | bool status;
10 |
11 | Bin *message = new Bin();
12 | Bin *key = new Bin();
13 | Bin *cipher = new Bin();
14 | Bin *decrypted = new Bin();
15 |
16 | key->len = 2048/8;
17 | key->data = get_random(2048);
18 |
19 | message->len = 64;
20 | message->data = get_random(512);
21 |
22 | // Encrypt
23 | status = encrypt(message, key, cipher);
24 | BOOST_REQUIRE_MESSAGE(status == true, "test_encrypt: Failed to encrypt message");
25 | BOOST_REQUIRE_MESSAGE(cipher != NULL, "test_encrypt: Cipher shouldn't be null");
26 |
27 | // Decrypt
28 | status = decrypt(cipher, key, decrypted);
29 | BOOST_REQUIRE_MESSAGE(status == true, "test_encrypt: Failed to decrypt message");
30 |
31 |
32 | // Verify
33 | BOOST_REQUIRE_MESSAGE(*message == *decrypted, "test_encrypt: Failed to decrypt message");
34 |
35 | // Cleanup
36 | delete message;
37 | delete key;
38 | delete cipher;
39 | delete decrypted;
40 | }
41 |
42 | BOOST_AUTO_TEST_CASE(test_encrypt_chacha){
43 |
44 | bool status;
45 |
46 | Bin *message = NULL;
47 | Bin *key = new Bin();
48 | Bin *cipher = new Bin();
49 | Bin *decrypted = new Bin();
50 |
51 | int len = 5;
52 | message = new Bin(len);
53 | memcpy(message->data, "test1", len);
54 |
55 | // printf("Message is:\n");
56 | // message->print();
57 |
58 | // Encrypt
59 | status = encrypt_chacha(message, key, cipher);
60 | BOOST_REQUIRE_MESSAGE(status == true, "test_encrypt: Failed to encrypt message");
61 | BOOST_REQUIRE_MESSAGE(cipher != NULL, "test_encrypt: Cipher shouldn't be null");
62 |
63 | // printf("Cipher is %d:\n", cipher->len);
64 | // cipher->print();
65 | //
66 | // printf("Key is %d:\n", key->len);
67 | // key->print();
68 |
69 | // Decrypt
70 | status = decrypt_chacha(cipher, key, decrypted);
71 | BOOST_REQUIRE_MESSAGE(status == true, "test_encrypt: Failed to decrypt message");
72 |
73 | // printf("Plain_text is:\n");
74 | // decrypted->print();
75 |
76 | // Verify
77 | BOOST_REQUIRE_MESSAGE(*message == *decrypted, "test_encrypt: Failed to decrypt message");
78 |
79 | // Cleanup
80 | delete message;
81 | delete key;
82 | delete cipher;
83 | delete decrypted;
84 | }
85 |
86 | BOOST_AUTO_TEST_CASE(test_xor){
87 |
88 | int len = 12;
89 | int bits = len * 8;
90 |
91 | Bin* key = new Bin();
92 | Bin* enc = new Bin();
93 | Bin* dec = new Bin();
94 | Bin* message = new Bin(len);
95 | memcpy(message->data, "TESTMESSAGE", len);
96 |
97 |
98 | key->len = len;
99 | key->data = get_random(bits);
100 |
101 | enc->len = len;
102 | enc->data = XOR_enc_dec(message, key, len);
103 |
104 | dec->len = len;
105 | dec->data = XOR_enc_dec(enc, key, len);
106 |
107 |
108 | BOOST_REQUIRE_MESSAGE(*dec == *message, "test_xor_encrypt: Failed to decrypt message");
109 |
110 | // Cleanup
111 | delete key;
112 | delete enc;
113 | delete dec;
114 | delete message;
115 | }
116 |
--------------------------------------------------------------------------------
/POC_code/src/test/hash_test.cpp:
--------------------------------------------------------------------------------
1 | #define BOOST_TEST_DYN_LINK
2 | #define BOOST_TEST_MODULE hash_test
3 |
4 | #include "hash.h"
5 | #include "utility.h"
6 | #include
7 | BOOST_AUTO_TEST_CASE(test_hash256){
8 | unsigned char raw_tx[371] = {0x01, 0x00, 0x00, 0x00, 0x01, 0x04, 0x25, 0x3a,
9 | 0x70, 0x28, 0x74, 0xff, 0xd4, 0xd6, 0x1f, 0x07,
10 | 0x5e, 0x88, 0x23, 0x21, 0x54, 0x64, 0x3a, 0x7e,
11 | 0x1e, 0x85, 0x5f, 0x5b, 0x1a, 0xa5, 0x81, 0x95,
12 | 0xa0, 0x5e, 0x04, 0x1b, 0xdb, 0x01, 0x00, 0x00,
13 | 0x00, 0xfd, 0x1c, 0x01, 0x48, 0x30, 0x45, 0x02,
14 | 0x21, 0x00, 0x94, 0xf2, 0xbc, 0x26, 0xcc, 0x69,
15 | 0x6f, 0x0e, 0xa2, 0xb7, 0xf0, 0xe1, 0xe2, 0x90,
16 | 0x15, 0xe6, 0xa6, 0x51, 0x3a, 0xe5, 0x56, 0x9d,
17 | 0x1c, 0x6f, 0x5e, 0x5f, 0x06, 0xf6, 0xd2, 0x13,
18 | 0x7f, 0x1f, 0x02, 0x20, 0x30, 0x9e, 0x1f, 0xa6,
19 | 0x36, 0xf5, 0xce, 0x91, 0xd1, 0xf3, 0x8a, 0xf7,
20 | 0x15, 0xae, 0xbe, 0xfc, 0x32, 0x4f, 0xf2, 0xc0,
21 | 0x49, 0xce, 0x62, 0xd2, 0x1e, 0xcd, 0xb2, 0x08,
22 | 0xa1, 0xa4, 0x4f, 0x9d, 0x01, 0x00, 0x4c, 0xd0,
23 | 0x63, 0x52, 0x41, 0x04, 0x35, 0xfd, 0x62, 0x87,
24 | 0x13, 0x5f, 0x10, 0x70, 0x1b, 0x72, 0xc3, 0xd6,
25 | 0x17, 0xe4, 0xad, 0xe6, 0x38, 0x69, 0x1e, 0x59,
26 | 0x67, 0x31, 0xe7, 0x9f, 0x64, 0xda, 0x64, 0x90,
27 | 0xbb, 0x42, 0xb3, 0xa8, 0xe8, 0xe6, 0xf9, 0x01,
28 | 0xaf, 0x05, 0xbe, 0xb1, 0x6a, 0xe9, 0x7d, 0x6e,
29 | 0xac, 0xa0, 0x6c, 0x2f, 0xc0, 0x0b, 0x8c, 0xba,
30 | 0x65, 0xf6, 0x3e, 0xf2, 0x28, 0xdd, 0xb3, 0x80,
31 | 0x36, 0x75, 0x34, 0x7e, 0x41, 0x04, 0xc5, 0xa8,
32 | 0xdd, 0x46, 0xdb, 0x19, 0x75, 0xc4, 0x86, 0xe6,
33 | 0xfc, 0xab, 0x75, 0x44, 0x91, 0x73, 0xb8, 0x21,
34 | 0x7c, 0x93, 0x85, 0xea, 0xe3, 0x90, 0xff, 0xa1,
35 | 0xa9, 0x0b, 0x65, 0xd6, 0xcc, 0x1d, 0x9f, 0x8b,
36 | 0xa8, 0x74, 0x0d, 0x76, 0x42, 0x91, 0x82, 0xc8,
37 | 0xf9, 0x83, 0xc0, 0xad, 0x90, 0xc4, 0xe9, 0xed,
38 | 0x64, 0xe4, 0x4d, 0xc6, 0x46, 0xd5, 0xd2, 0x29,
39 | 0x3f, 0x92, 0x41, 0x31, 0x5c, 0x05, 0x52, 0xae,
40 | 0x67, 0x5a, 0xb1, 0x75, 0x41, 0x04, 0x35, 0xfd,
41 | 0x62, 0x87, 0x13, 0x5f, 0x10, 0x70, 0x1b, 0x72,
42 | 0xc3, 0xd6, 0x17, 0xe4, 0xad, 0xe6, 0x38, 0x69,
43 | 0x1e, 0x59, 0x67, 0x31, 0xe7, 0x9f, 0x64, 0xda,
44 | 0x64, 0x90, 0xbb, 0x42, 0xb3, 0xa8, 0xe8, 0xe6,
45 | 0xf9, 0x01, 0xaf, 0x05, 0xbe, 0xb1, 0x6a, 0xe9,
46 | 0x7d, 0x6e, 0xac, 0xa0, 0x6c, 0x2f, 0xc0, 0x0b,
47 | 0x8c, 0xba, 0x65, 0xf6, 0x3e, 0xf2, 0x28, 0xdd,
48 | 0xb3, 0x80, 0x36, 0x75, 0x34, 0x7e, 0xac, 0x68,
49 | 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x38, 0x01,
50 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x76, 0xa9,
51 | 0x14, 0xb0, 0xf2, 0x8c, 0x75, 0x33, 0x3e, 0x6f,
52 | 0x7a, 0x65, 0xc9, 0x9e, 0x7e, 0xb1, 0xaa, 0x5c,
53 | 0x9d, 0x6b, 0x98, 0xdb, 0x5a, 0x88, 0xac, 0x1e,
54 | 0x00, 0x00, 0x00};
55 |
56 | Bin* tx = new Bin();
57 | tx->len = 371;
58 | tx->data = raw_tx;
59 |
60 | Bin* tx_id = hash256(tx);
61 |
62 | unsigned char * tx_id_str = (unsigned char *) get_hex_str_rev(tx_id);
63 |
64 | BOOST_CHECK_MESSAGE(memcmp(tx_id_str, "23daa9d3868255bab14d5dfe46f7fb787aaef49b17d0014902e36e4491440311", HASH_256 * 2) == 0 , "test_txid: TX ID's don't match");
65 | delete tx_id;
66 |
67 | tx->len = 0;
68 | delete tx;
69 | free(tx_id_str);
70 | }
71 |
72 | BOOST_AUTO_TEST_CASE(test_hmac){
73 |
74 | // From https://tools.ietf.org/html/rfc4231
75 | unsigned char key[20] = {0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
76 | 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
77 | 0xaa, 0xaa, 0xaa, 0xaa};
78 |
79 | unsigned char data[50] = {0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
80 | 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
81 | 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
82 | 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
83 | 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
84 | 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
85 | 0xdd, 0xdd};
86 |
87 | unsigned char e[32] = {0x77, 0x3e, 0xa9, 0x1e, 0x36, 0x80, 0x0e, 0x46,
88 | 0x85, 0x4d, 0xb8, 0xeb, 0xd0, 0x91, 0x81, 0xa7,
89 | 0x29, 0x59, 0x09, 0x8b, 0x3e, 0xf8, 0xc1, 0x22,
90 | 0xd9, 0x63, 0x55, 0x14, 0xce, 0xd5, 0x65, 0xfe};
91 |
92 |
93 | Bin* bkey = new Bin();
94 | bkey->len = 20;
95 | bkey->data = key;
96 |
97 | Bin* msg = new Bin();
98 | msg->len = 50;
99 | msg->data = data;
100 |
101 | Bin* output = hmac256(msg, bkey);
102 |
103 | BOOST_CHECK_MESSAGE(memcmp(e, output->data, 32) == 0 , "test_hmac: Not expected");
104 |
105 | // Cleanup
106 | msg->data = NULL;
107 | bkey->data = NULL;
108 | delete msg;
109 | delete bkey;
110 | delete output;
111 | }
112 |
--------------------------------------------------------------------------------
/POC_code/src/test/scc_test.cpp:
--------------------------------------------------------------------------------
1 | #define BOOST_TEST_DYN_LINK
2 | #define BOOST_TEST_MODULE scc
3 |
4 | #include
5 | #include "hash.h"
6 | #include "scc.h"
7 |
8 | #include
9 |
10 | int myrandom (int i) { return rand()%i;}
11 |
12 | BOOST_AUTO_TEST_CASE(test_find_indices){
13 |
14 | int len = 5;
15 |
16 | Bin* temp;
17 |
18 | std::vector v1;
19 | std::vector v2;
20 | std::vector v3;
21 |
22 | // Vector 1
23 | temp = new Bin(len);
24 | memcpy(temp->data, "test1", len);
25 | v1.push_back(temp);
26 |
27 | temp = new Bin(len);
28 | memcpy(temp->data, "test2", len);
29 | v1.push_back(temp);
30 |
31 | temp = new Bin(len);
32 | memcpy(temp->data, "test3", len);
33 | v1.push_back(temp);
34 |
35 | // Vector 2
36 | temp = new Bin(len);
37 | memcpy(temp->data, "test4", len);
38 | v2.push_back(temp);
39 |
40 | temp = new Bin(len);
41 | memcpy(temp->data, "test5", len);
42 | v2.push_back(temp);
43 |
44 | temp = new Bin(len);
45 | memcpy(temp->data, "test6", len);
46 | v2.push_back(temp);
47 |
48 |
49 | // Combine v1 & v2
50 | v3.insert(v3.end(), v1.begin(), v1.end());
51 | v3.insert(v3.end(), v2.begin(), v2.end());
52 |
53 | // Permute
54 | random_shuffle(v3.begin(),v3.end(), myrandom);
55 |
56 |
57 | std::vector i1;
58 | std::vector i2;
59 | int j = 0;
60 |
61 | find_indices(v3, v1, i1);
62 | find_indices(v3, v2, i2);
63 |
64 | for (unsigned int i = 0; i < v1.size(); i++){
65 | j = i1[i];
66 | BOOST_REQUIRE_MESSAGE(memcmp(v1[i]->data, v3[j]->data, len) == 0, "test_find_indices: Indices don't match");
67 | }
68 |
69 | for (unsigned int i = 0; i < v2.size(); i++){
70 | j = i2[i];
71 | BOOST_REQUIRE_MESSAGE(memcmp(v2[i]->data, v3[j]->data, len) == 0, "test_find_indices: Indices don't match");
72 | }
73 |
74 | free_Bins(v1);
75 | free_Bins(v2);
76 | }
77 |
78 |
79 | BOOST_AUTO_TEST_CASE(test_blind_vectors){
80 |
81 | Bin* message;
82 | Bin* hash;
83 | int len = 5;
84 | bool status;
85 |
86 | std::vector blinded;
87 | std::vector sigs;
88 | std::vector unblinded;
89 | std::vector blinds;
90 |
91 | // Setup RSA
92 | RSA * rsa = get_private_rsa(2048, (char *)"test");
93 | BOOST_REQUIRE_MESSAGE(rsa != NULL, "test_blind_vectors: Failed load RSA key");
94 |
95 | // Setup vector
96 | message = new Bin(len);
97 | memcpy(message->data, "test1", len);
98 |
99 | // Hash message
100 | int rsa_len = RSA_size(rsa);
101 | hash = full_domain_hash(rsa, message, EVP_sha512());
102 | BOOST_REQUIRE_MESSAGE(hash->data != NULL, "test_blind_vectors: Failed to hash message");
103 |
104 |
105 | // Setup blinds
106 | status = create_blinds(rsa, 3, blinds);
107 | BOOST_REQUIRE_MESSAGE(status == true, "test_blind_vectors: Failed to create blinds");
108 |
109 | // Apply blinds
110 | status = apply_blinds(hash, blinds, blinded);
111 | BOOST_REQUIRE_MESSAGE(status == true, "test_blind_vectors: Failed to apply blinds");
112 |
113 |
114 | // Sign blinded messages
115 | Bin* temp;
116 | for(unsigned int i=0; i < blinds.size(); i++){
117 | temp = new Bin(rsa_len);
118 | status = sign(rsa, blinded.at(i), temp);
119 | BOOST_REQUIRE_MESSAGE(status == true, "test_blind_vectors: Failed to sign blinds");
120 | sigs.push_back(temp);
121 | }
122 |
123 | // Remove blinds
124 | status = remove_blinds(sigs, rsa_len, blinds, unblinded);
125 | BOOST_REQUIRE_MESSAGE(status == true, "test_blind_vectors: Failed to remove blinds");
126 |
127 | // Verify unblinded message
128 | for(unsigned int i=0; i < unblinded.size(); i++){
129 | BOOST_REQUIRE_MESSAGE(memcmp(unblinded.at(i)->data, hash->data, len) == true, "test_blind_vectors: Unblinded != message");
130 | }
131 |
132 | // Cleanup
133 | delete message;
134 | delete hash;
135 | free_Bins(unblinded);
136 | free_Bins(blinded);
137 | free_Bins(sigs);
138 | free_blinds(blinds);
139 | RSA_free(rsa);
140 |
141 | }
142 |
143 | BOOST_AUTO_TEST_CASE(test_key_deserialization){
144 |
145 | // Setup
146 | bool status;
147 | int n_keys = 15;
148 | int key_len = 32; // 256 bits
149 | Bin *serial_keys = new Bin(key_len * n_keys);
150 |
151 | std::vector keys;
152 | std::vector expected_keys;
153 |
154 | // Expected keys
155 | char *temp_str = NULL;
156 | Bin *temp_h = NULL;
157 | for(int i=1; i <= n_keys; i++){
158 |
159 | // Create
160 | asprintf (&temp_str, "test%d", i);
161 |
162 | // Hash
163 | temp_h = new Bin(SHA256_DIGEST_LENGTH);
164 | SHA256((unsigned char *)temp_str, strlen(temp_str), temp_h->data);
165 |
166 | // Add
167 | expected_keys.push_back(temp_h);
168 |
169 | free(temp_str);
170 | }
171 |
172 | // Get key from file
173 | FILE *file;
174 | file = fopen("./keys/keys.bin","rb");
175 | fread(serial_keys->data, serial_keys->len, 1, file);
176 | fclose(file);
177 |
178 | // Deserialize
179 | status = deserialize_vector(serial_keys, keys, n_keys, key_len);
180 | BOOST_REQUIRE_MESSAGE(status == true, "test_key_deserialization: Failed to deserialize keys");
181 |
182 | // Check
183 | for(int i=0; i < n_keys; i++){
184 | status = (*expected_keys.at(i) == *keys.at(i));
185 | BOOST_REQUIRE_MESSAGE(status == true, "test_key_deserialization: key doesn't match expected key");
186 | }
187 |
188 | // Cleanup
189 | delete serial_keys;
190 | free_Bins(expected_keys);
191 | free_Bins(keys);
192 |
193 | }
194 |
195 | BOOST_AUTO_TEST_CASE(test_serialization){
196 |
197 | int n = 10;
198 | int len = 5;
199 | bool status;
200 |
201 | std::vector vec;
202 | std::vector vec_d;
203 | Bin *serial = new Bin();
204 |
205 | // Setup vector
206 | char *temp_str = NULL;
207 | Bin *temp_bin = NULL;
208 | for (int i = 0; i < n; i++){
209 |
210 | asprintf (&temp_str, "test%d", i);
211 | temp_bin = new Bin(len, (unsigned char *) temp_str);
212 |
213 | vec.push_back(temp_bin);
214 | }
215 |
216 | // Serialize
217 | status = serialize_vector(serial, vec, n, len);
218 | BOOST_REQUIRE_MESSAGE(status == true, "test_serialization: Failed to serialize vector");
219 |
220 | // Deserialize
221 | status = deserialize_vector(serial, vec_d, n, len);
222 | BOOST_REQUIRE_MESSAGE(status == true, "test_serialization: Failed to deserialize vector");
223 |
224 | // Compare vectors
225 | for (int i = 0; i < n; i++){
226 | BOOST_REQUIRE_MESSAGE(*vec.at(i) == *vec_d.at(i), "test_serialization: vectors don't match");
227 | }
228 |
229 |
230 | // Cleanup
231 | delete serial;
232 | free_Bins(vec);
233 | free_Bins(vec_d);
234 | }
235 |
236 | BOOST_AUTO_TEST_CASE(test_int_serialization){
237 |
238 | int n = 10;
239 | bool status;
240 |
241 | std::vector vec;
242 | std::vector vec_d;
243 | Bin *serial = new Bin();
244 |
245 | // Setup vector
246 | for (int i = 0; i < n; i++){
247 | vec.push_back(i);
248 | }
249 |
250 | // Serialize
251 | status = serialize_int_vector(serial, vec, n);
252 | BOOST_REQUIRE_MESSAGE(status == true, "test_int_serialization: Failed to serialize vector");
253 |
254 | // Deserialize
255 | status = deserialize_int_vector(serial, vec_d, n);
256 | BOOST_REQUIRE_MESSAGE(status == true, "test_int_serialization: Failed to deserialize vector");
257 |
258 | // Compare vectors
259 | for (int i = 0; i < n; i++){
260 | BOOST_REQUIRE_MESSAGE(vec.at(i) == vec_d.at(i), "test_int_serialization: vectors don't match");
261 | }
262 |
263 |
264 | // Cleanup
265 | delete serial;
266 | }
267 |
--------------------------------------------------------------------------------
/POC_code/src/test/utility_test.cpp:
--------------------------------------------------------------------------------
1 | #define BOOST_TEST_DYN_LINK
2 | #define BOOST_TEST_MODULE utility_test
3 |
4 | #include
5 | #include "utility.h"
6 |
7 | BOOST_AUTO_TEST_CASE(test_BNToBin){
8 |
9 | BN_CTX* ctx = BN_CTX_new();
10 | BN_CTX_start(ctx);
11 | BIGNUM* bn1 = BN_CTX_get(ctx);
12 | BIGNUM* bn2 = BN_CTX_get(ctx);
13 | BIGNUM* bn3 = BN_CTX_get(ctx);
14 |
15 | char *temp;
16 |
17 | BOOST_REQUIRE_MESSAGE(ctx != NULL , "test_BNToBin: Failed to setup context");
18 | BOOST_REQUIRE_MESSAGE(bn1 != NULL && bn2 != NULL && bn3 != NULL , "test_BNToBin: Failed to setup bignums");
19 |
20 |
21 | BN_zero(bn1);
22 | BN_ULONG longword = 0x0301FF00;
23 | BN_add_word(bn1, longword);
24 |
25 | //print_BN(bn1);
26 |
27 | int data_len = 256;
28 | unsigned char data1[data_len];
29 | unsigned char data2[data_len];
30 |
31 | memset(data1, 0xFF, data_len);
32 | memset(data2, 0xFF, data_len);
33 |
34 | int data1_len = BNToBin(bn1, data1, data_len);
35 | int data2_len = BN_bn2bin(bn1, data2);
36 |
37 | if (data1_len != data_len){
38 | printf("Unexpected write BNToBin length actual: %d expected: %d \n", data1_len, data_len);
39 | }
40 | BOOST_CHECK(data1_len == data_len);
41 |
42 | int bn1_len = BN_num_bytes(bn1);
43 | if (data2_len != bn1_len){
44 | printf("Unexpected write BN_bn2bin length actual: %d expected: %d \n", data2_len, bn1_len);
45 | }
46 | BOOST_CHECK(data2_len == bn1_len);
47 |
48 |
49 | BN_bin2bn(data2, data_len, bn2);
50 | temp = BN_bn2hex(bn2);
51 | char* expected_bn2_str = (char*) "0301FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF";
52 | BOOST_CHECK_MESSAGE(memcmp(temp, expected_bn2_str, data_len) == 0 , "test_BNToBin: BN_bin2bn produced an unexpected input");
53 | free(temp);
54 |
55 | BN_bin2bn(data1, data_len, bn3);
56 | temp = BN_bn2hex(bn3);
57 | char* expected_bn3_str = (char*) "0301FF00";
58 | BOOST_CHECK_MESSAGE(memcmp(temp, expected_bn3_str, bn1_len) == 0 , "test_BNToBin: BNToBin serialization failure");
59 | free(temp);
60 |
61 | // Cleanup
62 | BN_CTX_end(ctx);
63 | BN_CTX_free(ctx);
64 |
65 | }
66 |
--------------------------------------------------------------------------------
/POC_code/src/tumbler.cpp:
--------------------------------------------------------------------------------
1 | #include "tumbler.h"
2 | #include "timer.h"
3 |
4 | //============================================================================
5 | //======= Constructors
6 | //============================================================================
7 |
8 | Tumbler::Tumbler(){
9 | verified = false;
10 | const char* suffix = (const char*)"tumbler";
11 |
12 | // RSA
13 | rsa = get_private_rsa(2048, (char *)suffix);
14 | assert(rsa != NULL);
15 | rsa_len = RSA_size(rsa);
16 |
17 | int len = i2d_RSAPublicKey(rsa, NULL);
18 | rsa_pub = new Bin(len);
19 | unsigned char *p;
20 | p = rsa_pub->data;
21 | i2d_RSAPublicKey(rsa, &p);
22 |
23 | // EC
24 | if(!generate_EC_key(suffix, suffix)){
25 | exit(-1);
26 | }
27 | ec = get_ec_key_by_suffix(suffix, true);
28 | assert(ec!=NULL);
29 |
30 | ec_pubkey = new Bin();
31 | bool status = serialize_ec_publickey(ec, ec_pubkey);
32 | assert(status != false);
33 |
34 | address = new Bin(strlen(TUMBLER_ADDRESS));
35 | memcpy(address->data, TUMBLER_ADDRESS, address->len);
36 |
37 | p2sh_address = NULL;
38 | redeem_script = NULL;
39 | funding_tx_id = NULL;
40 | lock_time = NULL;
41 |
42 | }
43 |
44 | Tumbler::~Tumbler(){
45 | RSA_free(rsa);
46 | EC_KEY_free(ec);
47 |
48 | delete_bin(rsa_pub);
49 | delete_bin(ec_pubkey);
50 | delete_bin(address);
51 |
52 | delete_bin(redeem_script);
53 | delete_bin(funding_tx_id);
54 | delete_bin(p2sh_address);
55 | delete_bin(lock_time);
56 |
57 | delete_bin(h_r);
58 | delete_bin(h_f);
59 |
60 | free_Bins(epsilon);
61 | free_Bins(quotients);
62 | free_Bins(C);
63 | free_Bins(Z);
64 |
65 | }
66 |
67 | //============================================================================
68 | //======= Private Functions
69 | //============================================================================
70 |
71 | bool Tumbler::create_quotients(){
72 |
73 | Timer timer = Timer((char *) "wrapper_create_quotients\0");
74 | timer.start();
75 |
76 | int j, j2, s;
77 |
78 | BN_CTX *ctx;
79 | BIGNUM *q1;
80 | BIGNUM *q2;
81 |
82 | Bin* q_str;
83 |
84 | // Create context
85 | if ((ctx = BN_CTX_new()) == NULL){
86 | return false;
87 | }
88 |
89 | BN_CTX_start(ctx);
90 |
91 | q1 = BN_CTX_get(ctx);
92 | q2 = BN_CTX_get(ctx);
93 |
94 | if(q1 == NULL || q2 == NULL){
95 | return false;
96 | }
97 |
98 |
99 | for (unsigned int i=0; i < R.size() - 1; i++){
100 | j = R.at(i);
101 | j2 = R.at(i + 1);
102 |
103 | // Convert to BN
104 | if (BN_bin2bn(epsilon.at(j)->data, rsa_len, q1) == NULL){
105 | return false;
106 | }
107 |
108 | if (BN_bin2bn(epsilon.at(j2)->data, rsa_len, q2) == NULL){
109 | return false;
110 | }
111 |
112 | // Invert q1
113 | BN_mod_inverse(q1, q1, rsa->n, ctx);
114 |
115 | // Multiplty q2 * (q1)^-1
116 | s = BN_mod_mul(q1, q1, q2,rsa->n, ctx);
117 | if (s != 1){
118 | printf("create_quotients: couldn't multiply q1 & q2.\n");
119 | return false;
120 | }
121 |
122 | // Convert result
123 | q_str = new Bin(rsa_len);
124 | BNToBin(q1, q_str->data, rsa_len);
125 |
126 |
127 | // Save result
128 | quotients.push_back(q_str);
129 | }
130 |
131 | BN_free(q1);
132 | BN_free(q2);
133 |
134 | BN_CTX_end(ctx);
135 | BN_CTX_free(ctx);
136 |
137 | timer.end();
138 |
139 | return true;
140 | }
141 |
142 | bool Tumbler::create_refund_tx(){
143 | Bin* temp_sighash = new Bin();
144 | Bin* temp_raw_tx = new Bin();
145 |
146 | if (!get_refund_tx(redeem_script, address, funding_tx_id, lock_time, temp_raw_tx, temp_sighash)){
147 | return false;
148 | }
149 |
150 | // Sign
151 | Bin* serial_sig = new Bin();
152 | ECDSA_SIG * sig = NULL;
153 |
154 | sig = EC_sign(ec, temp_sighash);
155 | if (sig == NULL){
156 | return false;
157 | }
158 |
159 | convert_sig_to_standard_der(sig, ec);
160 |
161 | // Serialize EC signature
162 | if (!serialize_ec_signature_der(sig, serial_sig)){
163 | return false;
164 | }
165 | ECDSA_SIG_free(sig);
166 |
167 |
168 | Bin* refund_tx_fulfill = new Bin();
169 | if (!send_refund_tx(serial_sig, temp_raw_tx, redeem_script, refund_tx_fulfill)){
170 | return false;
171 | }
172 |
173 | printf("puzzle_promise: Escrow Refund TX:\n");
174 | refund_tx_fulfill->print();
175 |
176 | delete temp_raw_tx;
177 | delete temp_sighash;
178 | delete refund_tx_fulfill;
179 | delete serial_sig;
180 |
181 | return true;
182 | }
183 | //============================================================================
184 | //======= Public Functions
185 | //============================================================================
186 |
187 | bool Tumbler::sign_transactions(std::vector& tx_set){
188 |
189 | Timer timer = Timer((char *) "wrapper_sign\0");
190 | timer.start();
191 |
192 | bool status;
193 | int s;
194 |
195 | // Save Transactions
196 | tx = tx_set;
197 |
198 |
199 | ECDSA_SIG * sig = NULL;
200 | Bin* serial_sig = NULL;
201 |
202 | Bin* temp_epsilon = NULL;
203 | Bin* temp_enc = NULL;
204 | Bin* temp_commitment = NULL;
205 |
206 | int n = 2 * K;
207 | for (int i = 0; i < n; i++){
208 |
209 | //=========================
210 | //======= ECDSA sign TX
211 | //=========================
212 |
213 | sig = EC_sign(ec, tx_set.at(i));
214 | if (sig == NULL){
215 | return false;
216 | }
217 |
218 | convert_sig_to_standard_der(sig, ec);
219 |
220 | // Serialize EC signature
221 | serial_sig = new Bin();
222 | status = serialize_ec_signature(sig, serial_sig);
223 | if (!status){
224 | return false;
225 | }
226 |
227 | //=========================
228 | //======= Commit
229 | //=========================
230 |
231 | temp_epsilon = new Bin();
232 | temp_epsilon->len = rsa_len;
233 | temp_epsilon->data = get_random(rsa_len * 8, rsa->n);
234 |
235 | temp_commitment = new Bin();
236 | status = encrypt(serial_sig, temp_epsilon, temp_commitment);
237 | if(!status){
238 | return false;
239 | }
240 |
241 | epsilon.push_back(temp_epsilon);
242 | C.push_back(temp_commitment);
243 |
244 | //=========================
245 | //======= Encrypt epsiolon
246 | //=========================
247 |
248 | temp_enc = new Bin(rsa_len);
249 | s = RSA_public_encrypt(rsa_len, temp_epsilon->data, temp_enc->data, rsa, RSA_NO_PADDING);
250 | if (s == -1){
251 | return false;
252 | }
253 | Z.push_back(temp_enc);
254 |
255 | // Cleanup
256 | ECDSA_SIG_free(sig);
257 | delete serial_sig;
258 |
259 | }
260 |
261 | timer.end();
262 |
263 | return true;
264 | }
265 |
266 | bool Tumbler::verify_fake_tx(std::vector& r){
267 |
268 | Timer timer = Timer((char *) "wrapper_verify_fakes\0");
269 | timer.start();
270 |
271 | // Check R & F hashes
272 | Bin* temp_h_r;
273 | Bin* temp_h_f;
274 |
275 | Bin *r2 = new Bin();
276 | Bin *f = new Bin();
277 |
278 | serialize_int_vector(r2, R, K);
279 | serialize_int_vector(f, F, K);
280 |
281 | temp_h_r = hmac256(r2, salt);
282 | temp_h_f = hmac256(f, salt);
283 |
284 | if (*h_r != *temp_h_r || *h_f != *temp_h_f){
285 | printf("HMAC doesn't match\n");
286 | return false;
287 | }
288 |
289 | delete temp_h_r;
290 | delete temp_h_f;
291 | delete r2;
292 | delete f;
293 |
294 | int j = 0;
295 | Bin *fake;
296 | Bin *hash;
297 |
298 | fake = new Bin(64);
299 | memset(fake->data, 0x00, 32);
300 | for (int i = 0; i < K; i++){
301 | j = F.at(i);
302 |
303 | // Hash fake tx
304 | memcpy(fake->data + 32, r.at(i)->data, 32);
305 | hash = hash256(fake);
306 |
307 | if (*tx.at(j) != *hash){
308 | printf("verify_fake_tx: Hashes don't match.");
309 | return false;
310 | }
311 |
312 | delete hash;
313 | }
314 |
315 | delete fake;
316 | timer.end();
317 |
318 |
319 | verified = true;
320 | create_quotients();
321 |
322 | for (unsigned int i=0; i < F.size(); i++){
323 | j = F.at(i);
324 | epsilon_f.push_back(epsilon.at(j));
325 | }
326 |
327 | return true;
328 | }
329 |
330 | bool Tumbler::create_offer_tx(){
331 |
332 | funding_tx_id = new Bin();
333 | redeem_script = new Bin();
334 | p2sh_address = new Bin();
335 | lock_time = new Bin();
336 |
337 | if(!setup_escrow(ec_pubkey, bob_ec_pubkey, redeem_script, funding_tx_id, p2sh_address, lock_time)){
338 | return false;
339 | }
340 |
341 | if(!create_refund_tx()){
342 | return false;
343 | }
344 |
345 | return true;
346 | }
347 |
348 | //============================================================================
349 | //======= GETS
350 | //============================================================================
351 |
352 | std::vector* Tumbler::get_Z(){
353 | return &Z;
354 | }
355 |
356 | std::vector* Tumbler::get_commitment(){
357 | return &C;
358 | }
359 |
360 | std::vector* Tumbler::get_epsilons(){
361 | if (verified == true){
362 | return &epsilon_f;
363 | }
364 | return NULL;
365 | }
366 |
367 | std::vector* Tumbler::get_quotients(){
368 | if (verified == true) {
369 | return "ients;
370 | }
371 | return NULL;
372 | }
373 |
374 | Bin* Tumbler::get_redeem_script(){
375 | return redeem_script;
376 | }
377 |
378 | Bin* Tumbler::get_funding_tx_id(){
379 | return funding_tx_id;
380 | }
381 |
382 | Bin* Tumbler::get_pubkey(){
383 | return ec_pubkey;
384 | }
385 |
386 | Bin* Tumbler::get_rsa(){
387 | return rsa_pub;
388 | }
389 |
390 | //============================================================================
391 | //======= SETS
392 | //============================================================================
393 |
394 | void Tumbler::set_R(std::vector r){
395 | R = r;
396 | }
397 |
398 | void Tumbler::set_F(std::vector f){
399 | F = f;
400 | }
401 |
402 | void Tumbler::set_h_r(Bin* h){
403 | h_r = h;
404 | }
405 |
406 | void Tumbler::set_h_f(Bin* h){
407 | h_f = h;
408 | }
409 |
410 | void Tumbler::set_salt(Bin* s){
411 | salt = s;
412 | }
413 |
414 | void Tumbler::set_party_pubkey(Bin* public_key){
415 | bob_ec_pubkey = public_key;
416 | }
417 |
418 | //============================================================================
419 |
--------------------------------------------------------------------------------
/POC_code/src/tumbler_server.cpp:
--------------------------------------------------------------------------------
1 | #include "tumbler.h"
2 | #include "strings.h"
3 | #include "network.h"
4 |
5 | //============================================================================
6 | //======= PROTOCOL
7 | //============================================================================
8 |
9 | bool exchange(Tumbler &tumbler, std::vector& requests, std::vector& reply){
10 |
11 | if (requests.size() != 2){
12 | return false;
13 | }
14 |
15 | tumbler.set_party_pubkey(requests.at(1));
16 |
17 | // Create TX Offer
18 | if(!tumbler.create_offer_tx()){
19 | return false;
20 | }
21 |
22 | reply.push_back(tumbler.get_pubkey());
23 | reply.push_back(tumbler.get_rsa());
24 | reply.push_back(tumbler.get_redeem_script());
25 | reply.push_back(tumbler.get_funding_tx_id());
26 |
27 | return true;
28 | }
29 |
30 | bool commitment(Tumbler &tumbler, std::vector& requests, std::vector& reply, std::vector& tx_set){
31 |
32 | if (requests.size() != 4){
33 | return false;
34 | }
35 |
36 | // Deserialize
37 | if (!deserialize_vector(requests.at(1), tx_set, 2 * K, HASH_256)){
38 | return false;
39 | }
40 |
41 | tumbler.set_h_r(requests.at(2));
42 | tumbler.set_h_f(requests.at(3));
43 |
44 | // Sign
45 | if (!tumbler.sign_transactions(tx_set)){
46 | return false;
47 | }
48 |
49 | // Serialize
50 | Bin* C = new Bin();
51 | if (!serialize_vector(C, *tumbler.get_commitment(), 2 * K, HASH_512)){
52 | return false;
53 | }
54 |
55 | Bin* Z = new Bin();
56 | std::vector Z_vec = *tumbler.get_Z();
57 | if (!serialize_vector(Z, Z_vec, 2 * K, Z_vec.at(0)->len)){
58 | return false;
59 | }
60 |
61 | reply.push_back(C);
62 | reply.push_back(Z);
63 |
64 | return true;
65 | }
66 |
67 | bool verify(Tumbler &tumbler, std::vector& requests, std::vector& reply){
68 | if (requests.size() != 5){
69 | return false;
70 | }
71 |
72 | // Deserialize to int vectors
73 | std::vector R;
74 | std::vector F;
75 |
76 | if(!deserialize_int_vector(requests.at(1), R, K)){
77 | return false;
78 | }
79 |
80 | if(!deserialize_int_vector(requests.at(2), F, K)){
81 | return false;
82 | }
83 |
84 | std::vector fake_txs;
85 | if (!deserialize_vector(requests.at(3), fake_txs, K, HASH_256)){
86 | return false;
87 | }
88 |
89 | tumbler.set_R(R);
90 | tumbler.set_F(F);
91 | tumbler.set_salt(requests.at(4));
92 |
93 | // Verify fake tx's
94 | if (!tumbler.verify_fake_tx(fake_txs)){
95 | return false;
96 | }
97 |
98 | // Serialize
99 | Bin* quotients = new Bin();
100 | std::vector quot_vec =*tumbler.get_quotients();
101 | if (!serialize_vector(quotients, quot_vec, K - 1, quot_vec.at(0)->len)){
102 | return false;
103 | }
104 |
105 | Bin* fake_epsilons = new Bin();
106 | std::vector ep_vec = *tumbler.get_epsilons();
107 | if (!serialize_vector(fake_epsilons, ep_vec, K, ep_vec.at(0)->len)){
108 | return false;
109 | }
110 |
111 | reply.push_back(quotients);
112 | reply.push_back(fake_epsilons);
113 |
114 | free_Bins(fake_txs);
115 | return true;
116 | }
117 |
118 | //============================================================================
119 | //======= MAIN
120 | //============================================================================
121 |
122 | int main () {
123 |
124 | // Prepare our context and socket
125 | zmq::context_t context(1);
126 | zmq::socket_t socket(context, ZMQ_REP);
127 | socket.bind("tcp://*:5557");
128 |
129 | zmq::message_t fail_msg;
130 | fail_msg.rebuild(26);
131 | memcpy(fail_msg.data(), "Failed to process request.", 26);
132 |
133 | // Handle interrupt
134 | s_catch_signals();
135 |
136 | std::vector requests; // Received
137 | std::vector