├── FixMe.md ├── LICENSE ├── POSEHost ├── Csrc │ ├── POSEHostTests.c │ ├── POSEManager.c │ ├── POSEManager.h │ ├── PythonWrapper.c │ └── PythonWrapper.h ├── fullManagerTest.py ├── manager.py └── manager_mockup.py ├── ReadMe.md └── SmartContract ├── attestations ├── AboutSignatures.md ├── attestationPrivateKey.pem ├── printAllSignatures.sh ├── public.pem ├── signAllPreimages.sh ├── signatures │ ├── signature0.sign │ ├── signature1.sign │ ├── signature2.sign │ ├── signature3.sign │ ├── signature4.sign │ ├── signature5.sign │ ├── signature6.sign │ ├── signature7.sign │ ├── signature8.sign │ └── signature9.sign ├── toBeSignedTxt │ ├── attestationStringParty0.txt │ ├── attestationStringParty1.txt │ ├── attestationStringParty2.txt │ ├── attestationStringParty3.txt │ ├── attestationStringParty4.txt │ ├── attestationStringParty5.txt │ ├── attestationStringParty6.txt │ ├── attestationStringParty7.txt │ ├── attestationStringParty8.txt │ └── attestationStringParty9.txt └── writeAllPreimagesToFile.sh ├── build └── contracts │ ├── FuriousManagingOtter.json │ ├── FuriousManagingOtter_RSA.json │ ├── FuriousManagingOtter_v1.json │ ├── FuriousManagingOtter_v2.json │ ├── HelloWorld.json │ ├── Migrations.json │ ├── SolRsaVerify.json │ └── Test.json ├── contracts ├── Migrations.sol ├── PoseManager_ECDSA.sol ├── PoseManager_RSA.sol └── RSALibrary.sol ├── measurements ├── RSARegistration.json └── interpretRSAResults.js ├── migrations ├── 1_initial_migration.js └── 2_updateManager.js ├── test ├── .gitkeep ├── ECDSASignatureTest.js └── RSASignatureTest.js └── truffle-config.js /FixMe.md: -------------------------------------------------------------------------------- 1 | # Fix Me 2 | 3 | One of our smart contracts, ./SmartContract/contracts/PoseManager_RSA, needs to be fixed before being executed and compiled. The fix can be made as follows: 4 | - Copy the contents from [this contract](https://github.com/adria0/SolRsaVerify/blob/5746d395d782ebb7f1bf599c510c4942c9f18e25/contracts/SolRsaVerify.sol) to ./SmartContract/contracts/RSALibrary.sol 5 | - Replace `library SolRsaVerify {` (Line 25) in file ./SmartContract/contracts/RSALibrary.sol with `contract SolRsaVerify {` 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | , 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | 341 | -------------------------------------------------------------------------------- /POSEHost/Csrc/POSEHostTests.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "POSEManager.h" 5 | #include "PythonWrapper.h" 6 | 7 | int main(void) { 8 | // manager tests 9 | PyObject* pModule = initPyModule("manager"); 10 | init(pModule); 11 | 12 | // EXPECTED DATA FOR TEST: 13 | private_key = 0xb0057716d5917badaf911b193b12b910811c1497b5bada8d7711f758981c3773 14 | att_hash = keccak(encode_abi(['string', 'bytes32', 'address', 'bytes'], 15 | ['Furious-Attest', 16 | Web3.toBytes(hexstr='0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563'), 17 | Web3.toChecksumAddress("0x90F8bf6A479f320ead074411a4B0e7944Ea8c9C1"), 18 | Web3.toBytes(hexstr='0x00')])) 19 | registered operator: 0x90F8bf6A47 9f320ead07 4411a4B0e7 944Ea8c9C1 20 | 21 | EthAddr addr = {0x90, 0xf8, 0xbf, 0x6a, 0x47, 0x9f, 0x32, 0x0e, 0xad, 0x07, 22 | 0x44, 0x11, 0xa4, 0xb0, 0xe7, 0x94, 0x4e, 0xa8, 0xc9, 0xc1}; 23 | Hash hash = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 24 | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 25 | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 26 | 0x00, 0x01}; 27 | EnclavePK epk = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 28 | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 29 | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 30 | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 31 | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 32 | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 33 | 0x00, 0x01, 0x02, 0x03}; 34 | EnclaveSig esig = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 35 | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 36 | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 37 | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 38 | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 39 | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 40 | 0x00, 0x01, 0x02, 0x03, 0x04}; 41 | EthAddr poolOps[POOL_SIZE] = {addr, addr, addr}; 42 | int contractId = 1; 43 | 44 | // MAIN CONTRACT CALLS: all calls return nothing on success 45 | // may return operator already registered error: 46 | int result1 = registerEnclave(pModule, addr, epk, esig); 47 | printf("registerEnclave: %d", result1); 48 | // may return contract already exists error: 49 | int result2 = initContractCreation(pModule, addr, hash, contractId); 50 | printf("initContractCreation: %d", result2); 51 | // requires encoded sig to function! 52 | int result3 = finalizeCreation(pModule, contractId, addr, poolOps, esig); 53 | printf("finalizeCreation: %d", result3); 54 | 55 | // GETTER CALLS: return values 56 | struct addrList result4 = getOperatorList(pModule); 57 | for(int i = 0; i < result4.len_list; i++) { 58 | printf("op %d: ", i+1); 59 | printBytesAsHex(ADDR_SIZE, result4.list[i]); 60 | printf("\n"); 61 | } 62 | 63 | // ENCODED VERSION 64 | struct eventDataEncoded result6 = getEventTxsSinceEncoded(pModule, contractId, 0); 65 | for(int i = 0; i < result6.len_list; i++) { 66 | printf("event %d: encoded_data: ", i+1); 67 | printBytesAsHex(result6.len[i], *result6.bytesData[i]); 68 | } 69 | 70 | // END 71 | destroyPyModule(pModule); 72 | return EXIT_SUCCESS; 73 | } 74 | -------------------------------------------------------------------------------- /POSEHost/Csrc/POSEManager.c: -------------------------------------------------------------------------------- 1 | #include "POSEManager.h" 2 | 3 | #include 4 | 5 | int init(PyObject* pModule) { 6 | callMethod(pModule, "init", NULL); 7 | return 0; 8 | } 9 | 10 | int registerEnclave(PyObject* pModule, EthAddr addr, EnclavePK epk, EnclaveSig esig) { 11 | // construct args 12 | PyObject* pArgs = PyTuple_New(3); 13 | PyObject* pvAddr = Py_BuildValue("y#", addr, ADDR_SIZE); 14 | PyObject* pvEpk = Py_BuildValue("y#", epk, PK_SIZE); 15 | PyObject* pvEsig = Py_BuildValue("y#", esig, SIG_SIZE); 16 | //printf(PyUnicode_AsUTF8(PyObject_Str(pvAddr))); // mimics python's str(obj) 17 | PyObject* pRetValue; 18 | if (!pvAddr || !pvEpk || !pvEsig) { 19 | fprintf(stderr, "Cannot convert argument\n"); 20 | } else { 21 | PyTuple_SetItem(pArgs, 0, pvAddr); 22 | PyTuple_SetItem(pArgs, 1, pvEpk); 23 | PyTuple_SetItem(pArgs, 2, pvEsig); 24 | // execute call 25 | pRetValue = callMethod(pModule, "register_enclave", pArgs); 26 | if (pRetValue != NULL) { 27 | // process return value 28 | return (int) PyLong_AsLong(pRetValue); 29 | } 30 | else { 31 | PyErr_Print(); 32 | fprintf(stderr,"Call failed\n"); 33 | } 34 | } 35 | Py_DECREF(pArgs); 36 | Py_DECREF(pvAddr); 37 | Py_DECREF(pvEpk); 38 | Py_DECREF(pvEsig); 39 | Py_XDECREF(pRetValue); 40 | return -1; 41 | } 42 | 43 | int initContractCreation(PyObject* pModule, EthAddr creator, Hash codeHash, int contractId) { 44 | // construct args 45 | PyObject* pArgs = PyTuple_New(3); 46 | PyObject* pvCreator = Py_BuildValue("y#", creator, ADDR_SIZE); 47 | PyObject* pvHash = Py_BuildValue("y#", codeHash, HASH_SIZE); 48 | PyObject* pvContractId = PyLong_FromLong(contractId); 49 | //printf(PyUnicode_AsUTF8(PyObject_Str(pvAddr))); // mimics python's str(obj) 50 | PyObject* pRetValue; 51 | if (!pvCreator || !pvHash || !pvContractId) { 52 | fprintf(stderr, "Cannot convert argument\n"); 53 | } else { 54 | PyTuple_SetItem(pArgs, 0, pvCreator); 55 | PyTuple_SetItem(pArgs, 1, pvHash); 56 | PyTuple_SetItem(pArgs, 2, pvContractId); 57 | // execute call 58 | pRetValue = callMethod(pModule, "init_creation", pArgs); 59 | if (pRetValue != NULL) { 60 | // process return value 61 | return (int) PyLong_AsLong(pRetValue); 62 | } 63 | else { 64 | PyErr_Print(); 65 | fprintf(stderr,"Call failed\n"); 66 | } 67 | } 68 | Py_DECREF(pArgs); 69 | Py_DECREF(pvCreator); 70 | Py_DECREF(pvHash); 71 | Py_DECREF(pvContractId); 72 | Py_XDECREF(pRetValue); 73 | return -1; 74 | } 75 | 76 | int finalizeCreation(PyObject* pModule, int contractId, EthAddr poolAddr, EthAddr poolOps[POOL_SIZE], EnclaveSig esig) { 77 | // construct args 78 | PyObject* pArgs = PyTuple_New(4); 79 | PyObject* pvContractId = PyLong_FromLong(contractId); 80 | PyObject* pvPoolAddr = Py_BuildValue("y#", poolAddr, ADDR_SIZE); 81 | PyObject* pvPoolOps = PyList_New(POOL_SIZE); 82 | for(int i = 0; i < POOL_SIZE; i++) { 83 | PyList_SetItem(pvPoolOps, i, Py_BuildValue("y#", poolOps[i], ADDR_SIZE)); 84 | } 85 | PyObject* pvEsig = Py_BuildValue("y#", esig, SIG_SIZE); 86 | //printf(PyUnicode_AsUTF8(PyObject_Str(pvAddr))); // mimics python's str(obj) 87 | PyObject* pRetValue; 88 | if (!pvContractId || !pvPoolAddr || !pvPoolOps || !pvEsig) { 89 | fprintf(stderr, "Cannot convert argument\n"); 90 | } else { 91 | PyTuple_SetItem(pArgs, 0, pvContractId); 92 | PyTuple_SetItem(pArgs, 1, pvPoolAddr); 93 | PyTuple_SetItem(pArgs, 2, pvPoolOps); 94 | PyTuple_SetItem(pArgs, 3, pvEsig); 95 | // execute call 96 | pRetValue = callMethod(pModule, "finalize_creation", pArgs); 97 | if (pRetValue != NULL) { 98 | // process return value 99 | return (int) PyLong_AsLong(pRetValue); 100 | } 101 | else { 102 | PyErr_Print(); 103 | fprintf(stderr,"Call failed\n"); 104 | } 105 | } 106 | Py_DECREF(pArgs); 107 | Py_DECREF(pvContractId); 108 | Py_DECREF(pvPoolAddr); 109 | Py_DECREF(pvPoolOps); 110 | Py_DECREF(pvEsig); 111 | Py_XDECREF(pRetValue); 112 | return -1; 113 | } 114 | 115 | struct addrList getOperatorList(PyObject* pModule) { 116 | struct addrList result; 117 | // construct args 118 | PyObject* pArgs = PyTuple_New(0); 119 | PyObject* pRetValue; 120 | // execute call 121 | pRetValue = callMethod(pModule, "get_operator_list", pArgs); 122 | if (pRetValue != NULL) { 123 | // process return value 124 | result.len_list = PyList_Size(pRetValue); 125 | EthAddr *temp1 = (EthAddr*) malloc(sizeof(EthAddr) * result.len_list); 126 | EthAddr **temp = &temp1; 127 | for(int i = 0; i < result.len_list; i++) { 128 | PyObject* pAddr = PyList_GetItem(pRetValue, i); 129 | char *sAddr = PyBytes_AsString(pAddr); 130 | EthAddr *addr = (EthAddr*) malloc(sizeof(EthAddr)); 131 | memcpy(addr, (EthAddr*) sAddr, sizeof(EthAddr)); 132 | temp[i] = addr; 133 | Py_DECREF(pAddr); 134 | } 135 | result.list = temp; 136 | return result; 137 | } 138 | else { 139 | PyErr_Print(); 140 | fprintf(stderr,"Call failed\n"); 141 | } 142 | Py_DECREF(pArgs); 143 | Py_XDECREF(pRetValue); 144 | return result; 145 | } 146 | 147 | struct eventData getEventTxsSince(PyObject* pModule, int contractId, int blockNo) { 148 | struct eventData result; 149 | // construct args 150 | PyObject* pArgs = PyTuple_New(2); 151 | PyObject* pContractId = PyLong_FromLong(contractId); 152 | PyObject* pBlockNo = PyLong_FromLong(blockNo); 153 | PyObject* pRetValue; 154 | if (!pContractId || !pBlockNo) { 155 | fprintf(stderr, "Cannot convert argument\n"); 156 | } else { 157 | PyTuple_SetItem(pArgs, 0, pContractId); 158 | PyTuple_SetItem(pArgs, 1, pBlockNo); 159 | // execute call 160 | pRetValue = callMethod(pModule, "get_event_txs_since", pArgs); 161 | if (pRetValue != NULL) { 162 | // process return value 163 | PyObject* pHashes = PyList_GetItem(pRetValue, 0); 164 | PyObject* pInputs = PyList_GetItem(pRetValue, 1); 165 | PyObject* pFroms = PyList_GetItem(pRetValue, 2); 166 | PyObject* pValues = PyList_GetItem(pRetValue, 3); 167 | result.len_list = PyList_Size(pHashes); 168 | 169 | // prepare result 170 | Hash *tmpHash1 = (Hash*) malloc(sizeof(Hash) * result.len_list); 171 | Hash **tmpHash = &tmpHash1; 172 | int *tmpLenInputs = (int*) malloc(sizeof(int) * result.len_list); 173 | // int **tmpLenInputs = &tmpLenInputs1; 174 | unsigned char *tmpInputs1 = (unsigned char*) malloc(sizeof(unsigned char) * result.len_list); 175 | unsigned char **tmpInputs = &tmpInputs1; 176 | EthAddr *tmpFroms1 = (EthAddr*) malloc(sizeof(EthAddr) * result.len_list); 177 | EthAddr **tmpFroms = &tmpFroms1; 178 | int *tmpValues = (int*) malloc(sizeof(int) * result.len_list); 179 | //int **tmpValues = &tmpValues1; 180 | 181 | for(int i = 0; i < result.len_list; i++) { 182 | // hashes 183 | PyObject* pHash = PyList_GetItem(pHashes, i); 184 | char *sHash = PyBytes_AsString(pHash); 185 | Hash *hash = (Hash*) malloc(sizeof(Hash)); 186 | memcpy(hash, (Hash*) sHash, sizeof(Hash)); 187 | tmpHash[i] = hash; 188 | 189 | // inputs 190 | PyObject* pInput = PyList_GetItem(pInputs, i); 191 | // -> length 192 | int sLenInput = PyBytes_Size(pInput); 193 | tmpLenInputs[i] = sLenInput; 194 | // -> bytes 195 | char *sInput = PyBytes_AsString(pInput); 196 | unsigned char *input = (unsigned char*) malloc(sizeof(unsigned char) * sLenInput); 197 | memcpy(input, (unsigned char*) sInput, sizeof(unsigned char) * sLenInput); 198 | tmpInputs[i] = &input; 199 | 200 | // printf("entry %d: ", i); 201 | // printBytesAsHex(sLenInput, input); 202 | // printf("\n"); 203 | 204 | // froms 205 | PyObject* pFrom = PyList_GetItem(pFroms, i); 206 | char *sFrom = PyBytes_AsString(pFrom); 207 | EthAddr *from = (EthAddr*) malloc(sizeof(EthAddr)); 208 | memcpy(from, (EthAddr*) sFrom, sizeof(EthAddr)); 209 | tmpFroms[i] = from; 210 | 211 | // printf("entry %d: ", i); 212 | // printBytesAsHex(ADDR_SIZE, from); 213 | // printf("\n"); 214 | 215 | // values 216 | PyObject* pValue = PyList_GetItem(pValues, i); 217 | int sValue = (int) PyLong_AsLong(pValue); 218 | tmpValues[i] = sValue; 219 | 220 | Py_DECREF(pHash); 221 | Py_DECREF(pInput); 222 | Py_DECREF(pFrom); 223 | Py_DECREF(pValue); 224 | } 225 | result.txhashes = tmpHash; 226 | result.len_inputs = tmpLenInputs; 227 | result.inputs = tmpInputs; 228 | result.froms = tmpFroms; 229 | result.values = tmpValues; 230 | return result; 231 | } 232 | else { 233 | PyErr_Print(); 234 | fprintf(stderr,"Call failed\n"); 235 | } 236 | } 237 | Py_DECREF(pArgs); 238 | Py_DECREF(pContractId); 239 | Py_DECREF(pBlockNo); 240 | Py_XDECREF(pRetValue); 241 | return result; 242 | } 243 | 244 | struct eventDataEncoded getEventTxsSinceEncoded(PyObject* pModule, int contractId, int blockNo) { 245 | struct eventDataEncoded result; 246 | // construct args 247 | PyObject* pArgs = PyTuple_New(2); 248 | PyObject* pContractId = PyLong_FromLong(contractId); 249 | PyObject* pBlockNo = PyLong_FromLong(blockNo); 250 | PyObject* pRetValue; 251 | if (!pContractId || !pBlockNo) { 252 | fprintf(stderr, "Cannot convert argument\n"); 253 | } else { 254 | PyTuple_SetItem(pArgs, 0, pContractId); 255 | PyTuple_SetItem(pArgs, 1, pBlockNo); 256 | // execute call 257 | pRetValue = callMethod(pModule, "get_event_txs_since_encoded", pArgs); 258 | if (pRetValue != NULL) { 259 | // process return value 260 | result.len_list = PyList_Size(pRetValue); 261 | 262 | // prepare result 263 | int *tmpLen = (int*) malloc(sizeof(int) * result.len_list); 264 | unsigned char *tmpBytesData1 = (unsigned char*) malloc(sizeof(unsigned char) * result.len_list); 265 | unsigned char **tmpBytesData = &tmpBytesData1; 266 | 267 | for(int i = 0; i < result.len_list; i++) { 268 | // inputs 269 | PyObject* pBytesData = PyList_GetItem(pRetValue, i); 270 | // -> length 271 | int sLenInput = PyBytes_Size(pBytesData); 272 | tmpLen[i] = sLenInput; 273 | // -> bytes 274 | char *sInput = PyBytes_AsString(pBytesData); 275 | unsigned char *bytesData = (unsigned char*) malloc(sizeof(unsigned char) * sLenInput); 276 | memcpy(bytesData, (unsigned char*) sInput, sizeof(unsigned char) * sLenInput); 277 | tmpBytesData[i] = &bytesData; 278 | 279 | // printf("entry %d: ", i); 280 | // printBytesAsHex(sLenInput, bytesData); 281 | // printf("\n"); 282 | 283 | Py_DECREF(pBytesData); 284 | } 285 | result.len = tmpLen; 286 | result.bytesData = tmpBytesData; 287 | return result; 288 | } 289 | else { 290 | PyErr_Print(); 291 | fprintf(stderr,"Call failed\n"); 292 | } 293 | } 294 | Py_DECREF(pArgs); 295 | Py_DECREF(pContractId); 296 | Py_DECREF(pBlockNo); 297 | Py_XDECREF(pRetValue); 298 | return result; 299 | } 300 | 301 | void printBytesAsHex(int len, unsigned char* bytes) { 302 | for(int i = 0; i < len; i++){ 303 | printf("%02X", bytes[i]); 304 | } 305 | } 306 | 307 | char* testSimpleIntReturn() { 308 | PyObject* pModule = initPyModule("ctest"); 309 | PyObject* pArgs = PyTuple_New(1); 310 | PyObject* pValue = PyLong_FromLong(123); 311 | PyTuple_SetItem(pArgs, 0, pValue); 312 | PyObject* pRetValue = callMethod(pModule, "test_int", pArgs); 313 | long longResult = PyLong_AsLong(pRetValue); 314 | char result[20]; 315 | sprintf(result, "%ld", longResult); 316 | Py_DECREF(pArgs); 317 | Py_DECREF(pValue); 318 | Py_DECREF(pRetValue); 319 | //destroyPyModule(pModule); // cannot destroy & re-setup python environment... 320 | return strdup(result); 321 | } 322 | 323 | char* testContractReturn() { 324 | PyObject* pModule = initPyModule("ctest"); 325 | PyObject* pRetValue = callMethod(pModule, "get_contractreturn", NULL); 326 | char* result = PyUnicode_AsUTF8(pRetValue); 327 | Py_DECREF(pRetValue); 328 | destroyPyModule(pModule); 329 | return strdup(result); 330 | } 331 | -------------------------------------------------------------------------------- /POSEHost/Csrc/POSEManager.h: -------------------------------------------------------------------------------- 1 | #ifndef POSEMANAGER_H_ 2 | #define POSEMANAGER_H_ 3 | 4 | #include "PythonWrapper.h" 5 | 6 | #define POOL_SIZE 3 7 | #define ADDR_SIZE 20 8 | #define HASH_SIZE 32 9 | #define PK_SIZE 64 10 | #define SIG_SIZE 65 11 | 12 | typedef unsigned char EthAddr[ADDR_SIZE]; 13 | typedef unsigned char Hash[HASH_SIZE]; 14 | typedef unsigned char EnclavePK[PK_SIZE]; 15 | typedef unsigned char EnclaveSig[SIG_SIZE]; 16 | 17 | struct addrList { 18 | int len_list; 19 | EthAddr **list; 20 | }; 21 | 22 | struct eventData { 23 | int len_list; 24 | Hash **txhashes; 25 | EthAddr **froms; 26 | int *values; // actually an uint256 -> important for encoding 27 | int *len_inputs; 28 | unsigned char ***inputs; 29 | }; 30 | 31 | struct eventDataEncoded { 32 | int len_list; 33 | int *len; 34 | unsigned char **bytesData; 35 | }; 36 | 37 | int init(PyObject* pModule); 38 | 39 | // MAIN CONTRACT CALLS: 40 | int registerEnclave(PyObject* pModule, EthAddr addr, EnclavePK epk, EnclaveSig esig); 41 | int initContractCreation(PyObject* pModule, EthAddr creator, Hash codeHash, int contractId); 42 | int finalizeCreation(PyObject* pModule, int contractId, EthAddr poolAddr, EthAddr poolOps[POOL_SIZE], EnclaveSig esig); 43 | 44 | // GETTER CALLS: 45 | struct addrList getOperatorList(PyObject* pModule); 46 | struct eventData getEventTxsSince(PyObject* pModule, int contractId, int blockNo); 47 | struct eventDataEncoded getEventTxsSinceEncoded(PyObject* pModule, int contractId, int blockNo); 48 | 49 | // simple python tests 50 | char* testSimpleIntReturn(); 51 | char* testContractReturn(); 52 | 53 | void printBytesAsHex(int len, unsigned char* bytes); 54 | 55 | #endif /* POSEMANAGER_H_ */ 56 | -------------------------------------------------------------------------------- /POSEHost/Csrc/PythonWrapper.c: -------------------------------------------------------------------------------- 1 | #include "PythonWrapper.h" 2 | 3 | PyObject* initPyModule(char* moduleName) { 4 | Py_Initialize(); 5 | // set paths so python knows where to look for *.py files 6 | PyObject *sys = PyImport_ImportModule("sys"); 7 | PyObject *path = PyObject_GetAttrString(sys, "path"); 8 | PyList_Append(path, PyUnicode_FromString(".")); 9 | Py_DECREF(sys); 10 | Py_DECREF(path); 11 | 12 | PyObject *pName = PyUnicode_FromString(moduleName); 13 | PyObject *pModule = PyImport_Import(pName); 14 | Py_DECREF(pName); 15 | 16 | if (pModule == NULL) { 17 | PyErr_Print(); 18 | fprintf(stderr, "Failed to load module \n"); 19 | return NULL; 20 | } 21 | return pModule; 22 | } 23 | 24 | int destroyPyModule(PyObject* pModule) { 25 | Py_DECREF(pModule); 26 | if (Py_FinalizeEx() < 0) { 27 | return 120; 28 | } 29 | return 0; 30 | } 31 | 32 | PyObject* callMethod(PyObject* pModule, char* methodName, PyObject* pArgs) { 33 | PyObject* pFunc = PyObject_GetAttrString(pModule, methodName); 34 | if (pFunc && PyCallable_Check(pFunc)) { 35 | PyObject* pValue = PyObject_CallObject(pFunc, pArgs); 36 | if (pValue != NULL) { 37 | Py_DECREF(pFunc); 38 | return pValue; 39 | } 40 | else { 41 | Py_DECREF(pFunc); 42 | PyErr_Print(); 43 | fprintf(stderr,"Call failed\n"); 44 | return 1; 45 | } 46 | } else { 47 | if (PyErr_Occurred()) 48 | PyErr_Print(); 49 | fprintf(stderr, "Cannot find function \n"); 50 | return NULL; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /POSEHost/Csrc/PythonWrapper.h: -------------------------------------------------------------------------------- 1 | #ifndef PYTHONWRAPPER_H_ 2 | #define PYTHONWRAPPER_H_ 3 | 4 | #include 5 | 6 | PyObject* initPyModule(char* moduleName); 7 | int destroyPyModule(PyObject* pModule); 8 | PyObject* callMethod(PyObject* pModule, char* methodName, PyObject* pArgs); 9 | 10 | #endif /* PYTHONWRAPPER_H_ */ 11 | -------------------------------------------------------------------------------- /POSEHost/fullManagerTest.py: -------------------------------------------------------------------------------- 1 | import time 2 | import sys 3 | from web3 import Web3 4 | from solcx import compile_source, set_solc_version_pragma 5 | from eth_abi import encode_abi 6 | from eth_account import messages 7 | 8 | set_solc_version_pragma('0.6.1') 9 | 10 | contract_address = '0x27d160115a1E2aA7C4F709dDEB9dABbA82Ba5188' # fill in actual contract address (is printed after truffle migration) 11 | sol_file = 'PoseManager_ECDSA.sol' 12 | w3_address = 'http://0.0.0.0:0000' 13 | 14 | w3 = Web3(Web3.HTTPProvider(w3_address)) 15 | 16 | with open(sol_file, 'r') as f: 17 | source = f.read() 18 | compiled_sol = compile_source(source) 19 | contract_id_sol, contract_interface = compiled_sol.popitem() 20 | contract = w3.eth.contract(address=contract_address, abi=contract_interface["abi"]) 21 | 22 | # attestation authority 23 | priv_key = Web3.toBytes(hexstr='0xb0057716d5917badaf911b193b12b910811c1497b5bada8d7711f758981c3773') 24 | # operator pool 25 | tee1_addr = Web3.toChecksumAddress('0x90F8bf6A479f320ead074411a4B0e7944Ea8c9C1') 26 | tee2_addr = Web3.toChecksumAddress('0xFFcf8FDEE72ac11b5c542428B35EEF5769C409f0') 27 | tee3_addr = Web3.toChecksumAddress('0x22d491Bde2303f2f43325b2108D26f1eAbA1e32b') 28 | tee1_priv_key = Web3.toBytes(hexstr='0x4f3edf983ac636a65a842ce7c78d9aa706d3b113bce9c46f30d7d21715b23b1d') 29 | tee2_priv_key = Web3.toBytes(hexstr='0x6cbed15c793ce57650b9877cf6fa156fbef513c4e6134f022a85b1ffdd59b2a1') 30 | tee3_priv_key = Web3.toBytes(hexstr='0x6370fd033278c143179d81c5526140625662b8daa446c22ee2d73db3707e620c') 31 | 32 | 33 | 34 | ##### register TEEs 35 | print('##### register(address teeSignatureAddress, bytes memory teeEncryptionKey, bytes memory attestationSignature)') 36 | ### TEE 1 37 | # calc attestation hash 38 | att_hash = Web3.keccak(encode_abi(['string', 'bytes32', 'address', 'bytes'], 39 | ['Furious-Attest', 40 | Web3.toBytes(hexstr='0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563'), 41 | tee1_addr, 42 | Web3.toBytes(hexstr='0x00')])) 43 | print(f'TEE 1 att_hash: {att_hash.hex()}') 44 | 45 | # sign by authority 46 | message = messages.encode_defunct(att_hash) 47 | sig = w3.eth.account.sign_message(message, priv_key) 48 | encoded_sig = encode_abi(["uint8","bytes32","bytes32"], 49 | [sig.v, Web3.toBytes(sig.r), Web3.toBytes(sig.s)]) 50 | print(f'TEE 1 encoded_sig: {encoded_sig.hex()}') 51 | 52 | # send out registration tx to solidity contract 53 | tx_hash = contract.functions.register(tee1_addr, "0x00", encoded_sig).transact({'from': tee1_addr}) 54 | receipt = w3.eth.waitForTransactionReceipt(tx_hash) 55 | print(f'TEE 1 tx receipt: {dict(receipt)}') 56 | print(f'TEE 1 tx success: {receipt["status"]}') 57 | print(f'tx gas used: {receipt["gasUsed"]}') 58 | 59 | ### TEE 2 60 | # calc attestation hash 61 | att_hash = Web3.keccak(encode_abi(['string', 'bytes32', 'address', 'bytes'], 62 | ['Furious-Attest', 63 | Web3.toBytes(hexstr='0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563'), 64 | tee2_addr, 65 | Web3.toBytes(hexstr='0x00')])) 66 | print(f'TEE 2 att_hash: {att_hash.hex()}') 67 | 68 | # sign by authority 69 | message = messages.encode_defunct(att_hash) 70 | sig = w3.eth.account.sign_message(message, priv_key) 71 | encoded_sig = encode_abi(["uint8","bytes32","bytes32"], 72 | [sig.v, Web3.toBytes(sig.r), Web3.toBytes(sig.s)]) 73 | print(f'TEE 2 encoded_sig: {encoded_sig.hex()}') 74 | 75 | # send out registration tx to solidity contract 76 | tx_hash = contract.functions.register(tee2_addr, "0x00", encoded_sig).transact({'from': tee2_addr}) 77 | receipt = w3.eth.waitForTransactionReceipt(tx_hash) 78 | print(f'TEE 2 tx receipt: {dict(receipt)}') 79 | print(f'TEE 2 tx success: {receipt["status"]}') 80 | print(f'tx gas used: {receipt["gasUsed"]}') 81 | 82 | ### TEE 3 83 | # calc attestation hash 84 | att_hash = Web3.keccak(encode_abi(['string', 'bytes32', 'address', 'bytes'], 85 | ['Furious-Attest', 86 | Web3.toBytes(hexstr='0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563'), 87 | tee3_addr, 88 | Web3.toBytes(hexstr='0x00')])) 89 | print(f'TEE 3 att_hash: {att_hash.hex()}') 90 | 91 | # sign by authority 92 | message = messages.encode_defunct(att_hash) 93 | sig = w3.eth.account.sign_message(message, priv_key) 94 | encoded_sig = encode_abi(["uint8","bytes32","bytes32"], 95 | [sig.v, Web3.toBytes(sig.r), Web3.toBytes(sig.s)]) 96 | print(f'TEE 3 encoded_sig: {encoded_sig.hex()}') 97 | 98 | # send out registration tx to solidity contract 99 | tx_hash = contract.functions.register(tee3_addr, "0x00", encoded_sig).transact({'from': tee3_addr}) 100 | receipt = w3.eth.waitForTransactionReceipt(tx_hash) 101 | print(f'TEE 3 tx receipt: {dict(receipt)}') 102 | print(f'TEE 3 tx success: {receipt["status"]}') 103 | print(f'tx gas used: {receipt["gasUsed"]}') 104 | 105 | 106 | 107 | ##### create contract 108 | contract_id = 123 109 | creator_addr = Web3.toChecksumAddress('0x90F8bf6A479f320ead074411a4B0e7944Ea8c9C1') 110 | creator_privkey = Web3.toBytes(hexstr='0x4f3edf983ac636a65a842ce7c78d9aa706d3b113bce9c46f30d7d21715b23b1d') 111 | code_hash = Web3.toBytes(hexstr='0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563') 112 | pool_addr = Web3.toChecksumAddress('0xE11BA2b4D45Eaed5996Cd0823791E0C93114882d') 113 | pool_ops = [tee1_addr, tee2_addr, tee3_addr] 114 | 115 | print('##### initCreation(address creationOperator, bytes32 codeHash, uint freeId)') 116 | tx_hash = contract.functions.initCreation(creator_addr, code_hash, contract_id).transact({'from': creator_addr}) 117 | receipt = w3.eth.waitForTransactionReceipt(tx_hash) 118 | print(f'tx receipt: {dict(receipt)}') 119 | print(f'tx success: {receipt["status"]}') 120 | print(f'tx gas used: {receipt["gasUsed"]}') 121 | result = contract.functions.contracts(contract_id).call() 122 | print(f'contract phase: {result[0]}') 123 | 124 | ### challenge watchdog 125 | print('##### challangeWatchdogsDuringCreation(uint id, address[POOL_SIZE] memory pool_operators, bytes memory message, ' 126 | 'uint[POOL_SIZE] memory challangedOperators)') 127 | challenge_msg = Web3.toBytes(hexstr='0x0102030405060708') 128 | challenged = [0, 0, 1] # challenge TEE 3 129 | tx_hash = contract.functions.challengeWatchdogsDuringCreation(contract_id, pool_ops, challenge_msg, challenged)\ 130 | .transact({'from': creator_addr}) 131 | receipt = w3.eth.waitForTransactionReceipt(tx_hash) 132 | print(f'tx receipt: {dict(receipt)}') 133 | print(f'tx success: {receipt["status"]}') 134 | print(f'tx gas used: {receipt["gasUsed"]}') 135 | result = contract.functions.contracts(contract_id).call() 136 | print(f'contract phase: {result[0]}') 137 | 138 | print('##### watchdogResponse(uint id, uint index, bytes memory response, bytes memory signature)') 139 | # watchdogResponse works for both challenges; message is arbitrary 140 | response_msg = Web3.toBytes(hexstr='0x0a0b0c0d0e0f') 141 | result = contract.functions.contracts(contract_id).call() 142 | cp_hash = result[1] # get incrementalTxHash 143 | # signature 144 | resp_hash = Web3.keccak(encode_abi(['string', 'uint', 'bytes32', 'bytes'], 145 | ['Watchdog-challenge-Response', contract_id, cp_hash, response_msg])) 146 | resp_msg = messages.encode_defunct(resp_hash) 147 | sig = w3.eth.account.sign_message(resp_msg, tee3_priv_key) 148 | encoded_sig = encode_abi(['uint8', 'bytes32', 'bytes32'], [sig.v, Web3.toBytes(sig.r), Web3.toBytes(sig.s)]) 149 | # execute call 150 | tx_hash = contract.functions.watchdogResponse(contract_id, 2, response_msg, encoded_sig).transact({'from': tee3_addr}) 151 | receipt = w3.eth.waitForTransactionReceipt(tx_hash) 152 | print(f'tx receipt: {dict(receipt)}') 153 | print(f'tx success: {receipt["status"]}') 154 | print(f'tx gas used: {receipt["gasUsed"]}') 155 | result = contract.functions.contracts(contract_id).call() 156 | print(f'contract phase: {result[0]}') 157 | 158 | # wait for timeout (>15s) 159 | time.sleep(16) 160 | 161 | print('##### watchdogFinalization(uint id)') 162 | tx_hash = contract.functions.watchdogFinalization(contract_id).transact({'from': tee1_addr}) 163 | receipt = w3.eth.waitForTransactionReceipt(tx_hash) 164 | print(f'tx receipt: {dict(receipt)}') 165 | print(f'tx success: {receipt["status"]}') 166 | print(f'tx gas used: {receipt["gasUsed"]}') 167 | result = contract.functions.contracts(contract_id).call() 168 | print(f'contract phase: {result[0]}') 169 | 170 | print('##### finalizeCreation(uint id, address payable pool_address, address[POOL_SIZE] memory pool_operators, ' 171 | 'bytes memory signature)') 172 | # get current incrementalHash 173 | result = contract.functions.contracts(contract_id).call() 174 | cp_hash = result[1] 175 | # create finalization signature 176 | finalization_hash = Web3.keccak(encode_abi(['string', 'uint', 'bytes32', 'address', 'bytes32', 'address[3]'], 177 | ['Creation-Attest', contract_id, cp_hash, pool_addr, code_hash, pool_ops])) 178 | challenge_msg = messages.encode_defunct(finalization_hash) 179 | sig = w3.eth.account.sign_message(challenge_msg, creator_privkey) 180 | encoded_sig = encode_abi(['uint8', 'bytes32', 'bytes32'], [sig.v, Web3.toBytes(sig.r), Web3.toBytes(sig.s)]) 181 | # execute call 182 | tx_hash = contract.functions.finalizeCreation(contract_id, pool_addr, pool_ops, encoded_sig)\ 183 | .transact({'from': creator_addr}) 184 | receipt = w3.eth.waitForTransactionReceipt(tx_hash) 185 | print(f'tx receipt: {dict(receipt)}') 186 | print(f'tx success: {receipt["status"]}') 187 | print(f'tx gas used: {receipt["gasUsed"]}') 188 | result = contract.functions.contracts(contract_id).call() 189 | print(f'contract phase: {result[0]}') 190 | 191 | 192 | 193 | ##### deposit 194 | client_addr = Web3.toChecksumAddress('0xd03ea8624C8C5987235048901fB614fDcA89b117') 195 | challenge_msg = Web3.toBytes(hexstr='0x0102030405060708') 196 | response_msg = Web3.toBytes(hexstr='0x0a0b0c0d0e0f') 197 | 198 | print('##### depositToContract(uint id)') 199 | tx_hash = contract.functions.depositToContract(contract_id).transact({'from': client_addr, 'value': 10000000000000000}) 200 | receipt = w3.eth.waitForTransactionReceipt(tx_hash) 201 | print(f'tx receipt: {dict(receipt)}') 202 | print(f'tx success: {receipt["status"]}') 203 | print(f'tx gas used: {receipt["gasUsed"]}') 204 | 205 | print('##### withdraw(uint id, uint blocknumber, address payable receiver)') 206 | tx_hash = contract.functions.withdraw(contract_id, 0, client_addr)\ 207 | .transact({'from': pool_addr, 'value': 10000000000000000}) 208 | receipt = w3.eth.waitForTransactionReceipt(tx_hash) 209 | print(f'tx receipt: {dict(receipt)}') 210 | print(f'tx success: {receipt["status"]}') 211 | print(f'tx gas used: {receipt["gasUsed"]}') 212 | 213 | ### challenge executor 214 | print('##### challengeExecutor(uint id, bytes memory message)') 215 | tx_hash = contract.functions.challengeExecutor(contract_id, challenge_msg).transact({'from': client_addr}) 216 | receipt = w3.eth.waitForTransactionReceipt(tx_hash) 217 | print(f'tx receipt: {dict(receipt)}') 218 | print(f'tx success: {receipt["status"]}') 219 | print(f'tx gas used: {receipt["gasUsed"]}') 220 | result = contract.functions.contracts(contract_id).call() 221 | print(f'contract phase: {result[0]}') 222 | 223 | print('##### executorResponse(uint id, bytes memory response, bytes memory signature)') 224 | # get current incrementalHash 225 | result = contract.functions.contracts(contract_id).call() 226 | cp_hash = result[1] 227 | print(f'CP: {cp_hash.hex()}') 228 | sig_hash = Web3.keccak(encode_abi(['string', 'uint', 'bytes32', 'bytes'], 229 | ['Challenge-Response', contract_id, cp_hash, response_msg])) 230 | sig_msg = messages.encode_defunct(sig_hash) 231 | sig = w3.eth.account.sign_message(sig_msg, tee1_priv_key) 232 | encoded_sig = encode_abi(['uint8', 'bytes32', 'bytes32'], [sig.v, Web3.toBytes(sig.r), Web3.toBytes(sig.s)]) 233 | tx_hash = contract.functions.executorResponse(contract_id, response_msg, encoded_sig).transact({'from': tee1_addr}) 234 | receipt = w3.eth.waitForTransactionReceipt(tx_hash) 235 | print(f'tx receipt: {dict(receipt)}') 236 | print(f'tx success: {receipt["status"]}') 237 | print(f'tx gas used: {receipt["gasUsed"]}') 238 | result = contract.functions.contracts(contract_id).call() 239 | print(f'contract phase: {result[0]}') 240 | 241 | ### challenge watchdog 242 | print('##### challengeWatchdog(uint id, bytes memory message, uint8[POOL_SIZE] memory challangedOperators)') 243 | challenged = [0, 0, 1] # challenge TEE 3 244 | tx_hash = contract.functions.challengeWatchdog(contract_id, challenge_msg, challenged).transact({'from': tee1_addr}) 245 | receipt = w3.eth.waitForTransactionReceipt(tx_hash) 246 | print(f'tx receipt: {dict(receipt)}') 247 | print(f'tx success: {receipt["status"]}') 248 | print(f'tx gas used: {receipt["gasUsed"]}') 249 | result = contract.functions.contracts(contract_id).call() 250 | print(f'contract phase: {result[0]}') 251 | 252 | print('##### watchdogResponse(uint id, uint index, bytes memory response, bytes memory signature)') 253 | # get current incrementalHash 254 | result = contract.functions.contracts(contract_id).call() 255 | cp_hash = result[1] 256 | print(f'CP: {cp_hash.hex()}') 257 | sig_hash = Web3.keccak(encode_abi(['string', 'uint', 'bytes32', 'bytes'], 258 | ['Watchdog-challenge-Response', contract_id, cp_hash, response_msg])) 259 | sig_msg = messages.encode_defunct(sig_hash) 260 | sig = w3.eth.account.sign_message(sig_msg, tee3_priv_key) 261 | encoded_sig = encode_abi(['uint8', 'bytes32', 'bytes32'], [sig.v, Web3.toBytes(sig.r), Web3.toBytes(sig.s)]) 262 | tx_hash = contract.functions.watchdogResponse(contract_id, 2, response_msg, encoded_sig).transact({'from': tee3_addr}) 263 | receipt = w3.eth.waitForTransactionReceipt(tx_hash) 264 | print(f'tx receipt: {dict(receipt)}') 265 | print(f'tx success: {receipt["status"]}') 266 | print(f'tx gas used: {receipt["gasUsed"]}') 267 | result = contract.functions.contracts(contract_id).call() 268 | print(f'contract phase: {result[0]}') 269 | 270 | # wait for timeout (>15s) 271 | time.sleep(16) 272 | 273 | print('##### watchdogFinalization(uint id)') 274 | tx_hash = contract.functions.watchdogFinalization(contract_id).transact({'from': tee1_addr}) 275 | receipt = w3.eth.waitForTransactionReceipt(tx_hash) 276 | print(f'tx receipt: {dict(receipt)}') 277 | print(f'tx success: {receipt["status"]}') 278 | print(f'tx gas used: {receipt["gasUsed"]}') 279 | result = contract.functions.contracts(contract_id).call() 280 | print(f'contract phase: {result[0]}') 281 | 282 | 283 | 284 | ##### challenge timeouts 285 | challenge_msg = Web3.toBytes(hexstr='0xff02030405060708') 286 | ### watchdog 287 | print('##### PREPARE: challengeWatchdog(uint id, bytes memory message, uint8[POOL_SIZE] memory challangedOperators)') 288 | challenged = [0, 0, 1] # challenge TEE 3 289 | tx_hash = contract.functions.challengeWatchdog(contract_id, challenge_msg, challenged).transact({'from': tee1_addr}) 290 | receipt = w3.eth.waitForTransactionReceipt(tx_hash) 291 | print(f'tx receipt: {dict(receipt)}') 292 | print(f'tx success: {receipt["status"]}') 293 | print(f'tx gas used: {receipt["gasUsed"]}') 294 | result = contract.functions.contracts(contract_id).call() 295 | print(f'contract phase: {result[0]}') 296 | 297 | # wait for timeout (>15s) 298 | time.sleep(16) 299 | 300 | print('##### watchdogFinalization(uint id)') 301 | tx_hash = contract.functions.watchdogFinalization(contract_id).transact({'from': tee1_addr}) 302 | receipt = w3.eth.waitForTransactionReceipt(tx_hash) 303 | print(f'tx receipt: {dict(receipt)}') 304 | print(f'tx success: {receipt["status"]}') 305 | print(f'tx gas used: {receipt["gasUsed"]}') 306 | result = contract.functions.contracts(contract_id).call() 307 | print(f'contract phase: {result[0]}') 308 | 309 | ### executor 310 | print('##### PREPARE: challengeExecutor(uint id, bytes memory message)') 311 | tx_hash = contract.functions.challengeExecutor(contract_id, challenge_msg).transact({'from': client_addr}) 312 | receipt = w3.eth.waitForTransactionReceipt(tx_hash) 313 | print(f'tx receipt: {dict(receipt)}') 314 | print(f'tx success: {receipt["status"]}') 315 | print(f'tx gas used: {receipt["gasUsed"]}') 316 | result = contract.functions.contracts(contract_id).call() 317 | print(f'contract phase: {result[0]}') 318 | 319 | # wait for timeout (>15s) 320 | time.sleep(16) 321 | 322 | print('##### executorTimeout(uint id)') 323 | tx_hash = contract.functions.executorTimeout(contract_id).transact({'from': client_addr}) 324 | receipt = w3.eth.waitForTransactionReceipt(tx_hash) 325 | print(f'tx receipt: {dict(receipt)}') 326 | print(f'tx success: {receipt["status"]}') 327 | print(f'tx gas used: {receipt["gasUsed"]}') 328 | result = contract.functions.contracts(contract_id).call() 329 | print(f'contract phase: {result[0]}') 330 | -------------------------------------------------------------------------------- /POSEHost/manager.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | import traceback 3 | 4 | from web3 import Web3 5 | from solcx import compile_source, set_solc_version_pragma 6 | from eth_abi import encode_abi 7 | from eth_account import messages 8 | 9 | # Class abstracting Manager calls 10 | 11 | set_solc_version_pragma('0.6.1') 12 | 13 | # config 14 | contract_address = '0x27d160115a1E2aA7C4F709dDEB9dABbA82Ba5188' # fill in actual contract address (is printed after truffle migration) 15 | account_address = '0x90F8bf6A479f320ead074411a4B0e7944Ea8c9C1' # take valid account with funds 16 | creator_privkey = Web3.toBytes(hexstr='0x4f3edf983ac636a65a842ce7c78d9aa706d3b113bce9c46f30d7d21715b23b1d') # above account's private key 17 | sol_file = 'PoseManager_ECDSA.sol' 18 | w3_address = 'http://0.0.0.0:0000' 19 | 20 | 21 | # init 22 | w3 = None 23 | manager = None 24 | def init(): 25 | global w3 26 | global manager 27 | w3 = Web3(Web3.HTTPProvider(w3_address)) 28 | with open(sol_file, 'r') as f: 29 | source = f.read() 30 | 31 | compiled_sol = compile_source(source) 32 | contract_id, contract_interface = compiled_sol.popitem() 33 | manager = w3.eth.contract(address=contract_address, abi=contract_interface["abi"]) 34 | 35 | 36 | def register_enclave(addr: bytes, epk: bytes, esig: bytes): 37 | print('register_enclave called') 38 | try: 39 | # convert to ethereum readable hex 40 | ex_addr = Web3.toChecksumAddress(addr) 41 | print(f'addr: {ex_addr}') 42 | ex_epk = Web3.toHex(epk) 43 | print(f'epk: {ex_epk}') 44 | ex_esig = Web3.toHex(esig) 45 | print(f'esig: {ex_esig}') 46 | 47 | # WITHOUT gas (only simulates if successful): 48 | # result = manager.functions.register(ex_addr, ex_epk, ex_esig).call() 49 | # print(result) 50 | # WITH gas (actual execution): 51 | tx_hash = manager.functions.register(ex_addr, ex_epk, ex_esig).transact({'from': account_address}) 52 | receipt = w3.eth.waitForTransactionReceipt(tx_hash) 53 | print(f'tx receipt: {dict(receipt)}') 54 | print(f'tx success: {receipt["status"]}') 55 | except: 56 | traceback.print_exc() 57 | return -1 58 | return 0 59 | 60 | 61 | def init_creation(addr: bytes, code_hash: bytes, contract_id: int): 62 | print('init_creation called') 63 | try: 64 | ex_addr = Web3.toChecksumAddress(addr) 65 | print(f'addr: {ex_addr}') 66 | ex_code_hash = Web3.toHex(code_hash) 67 | print(f'code_hash: {ex_code_hash}') 68 | 69 | # WITHOUT gas (only simulates if successful): 70 | # result = manager.functions.initCreation(ex_addr, ex_code_hash, contract_id).call() 71 | # print(result) 72 | # WITH gas (actual execution): 73 | tx_hash = manager.functions.initCreation(ex_addr, ex_code_hash, contract_id).transact({'from': account_address}) 74 | receipt = w3.eth.waitForTransactionReceipt(tx_hash) 75 | print(f'tx receipt: {dict(receipt)}') 76 | print(f'tx success: {receipt["status"]}') 77 | except: 78 | traceback.print_exc() 79 | return -1 80 | return 0 81 | 82 | 83 | def finalize_creation(contract_id: int, pool_addr: bytes, pool_ops: List[bytes], esig: bytes): 84 | print('finalize_creation called') 85 | try: 86 | ex_pool_addr = Web3.toChecksumAddress(pool_addr) 87 | print(f'pool_addr: {ex_pool_addr}') 88 | ex_pool_ops = [] 89 | for o in pool_ops: 90 | ex_pool_ops.append(Web3.toChecksumAddress(o)) 91 | print(f'pool_ops: {ex_pool_ops}') 92 | ex_esig = Web3.toHex(esig) 93 | print(f'esig: {ex_esig}') 94 | 95 | # WITHOUT gas (only simulates if successful): 96 | # result = manager.functions.finalizeCreation(contract_id, ex_pool_addr, ex_pool_ops, ex_esig).call() 97 | # print(result) 98 | # WITH gas (actual execution): 99 | tx_hash = manager.functions.finalizeCreation(contract_id, ex_pool_addr, ex_pool_ops, ex_esig).transact({'from': account_address}) 100 | receipt = w3.eth.waitForTransactionReceipt(tx_hash) 101 | print(f'tx receipt: {dict(receipt)}') 102 | print(f'tx success: {receipt["status"]}') 103 | except: 104 | traceback.print_exc() 105 | return -1 106 | return 0 107 | 108 | 109 | def finalize_creation_encoding(contract_id: int, pool_addr: bytes, pool_ops: List[bytes], cp_hash:bytes, code_hash: bytes): 110 | print('finalize_creation called') 111 | try: 112 | ex_pool_addr = Web3.toChecksumAddress(pool_addr) 113 | print(f'pool_addr: {ex_pool_addr}') 114 | ex_pool_ops = [] 115 | for o in pool_ops: 116 | ex_pool_ops.append(Web3.toChecksumAddress(o)) 117 | print(f'pool_ops: {ex_pool_ops}') 118 | 119 | # create finalization signature 120 | finalization_hash = Web3.keccak(encode_abi(['string', 'uint', 'bytes32', 'address', 'bytes32', 'address[3]'], 121 | ['Creation-Attest', contract_id, cp_hash, pool_addr, code_hash, 122 | pool_ops])) 123 | challenge_msg = messages.encode_defunct(finalization_hash) 124 | sig = w3.eth.account.sign_message(challenge_msg, creator_privkey) 125 | encoded_sig = encode_abi(['uint8', 'bytes32', 'bytes32'], [sig.v, Web3.toBytes(sig.r), Web3.toBytes(sig.s)]) 126 | print(f'encoded_sig: {encoded_sig}') 127 | 128 | tx_hash = manager.functions.finalizeCreation(contract_id, ex_pool_addr, ex_pool_ops, encoded_sig).transact( 129 | {'from': account_address}) 130 | receipt = w3.eth.waitForTransactionReceipt(tx_hash) 131 | print(f'tx receipt: {dict(receipt)}') 132 | print(f'tx success: {receipt["status"]}') 133 | except: 134 | traceback.print_exc() 135 | return -1 136 | return 0 137 | 138 | 139 | def get_operator_list(): 140 | print('get_operator_list called') 141 | result = [] 142 | i = 0 143 | try: # when operator list has ended, will get exception (LOL) 144 | while True: 145 | result.append(Web3.toBytes(hexstr=manager.functions.operatorList(i).call())) 146 | i += 1 147 | finally: 148 | return result 149 | 150 | 151 | def get_event_txs_since(contract_id: int, block_no: int): 152 | print('get_event_txs_since called') 153 | print(f'contract_id: {contract_id}') 154 | try: 155 | from_block = Web3.toHex(block_no) 156 | print(f'block_no: {from_block}') 157 | 158 | # get all events 159 | events = [] 160 | transfer_filter = manager.events.NewOperator.createFilter(fromBlock=from_block) 161 | events.append(transfer_filter.get_all_entries()) 162 | transfer_filter = manager.events.CreationInitialized.createFilter(fromBlock=from_block) 163 | events.append(transfer_filter.get_all_entries()) 164 | transfer_filter = manager.events.ContractCreated.createFilter(fromBlock=from_block) 165 | events.append(transfer_filter.get_all_entries()) 166 | 167 | # filter by contract and order events 168 | filtered_events = [] 169 | for e in events: 170 | if not e: # empty? 171 | continue 172 | e = e[0] # ugly, but works ¯\_(ツ)_/¯ 173 | if e['event'] == 'NewOperator' or int(e['args']['id']) == contract_id: 174 | index = 0 175 | for i in range(len(filtered_events)): 176 | if int(e['blockNumber']) == int(filtered_events[i]['blockNumber']): 177 | if int(e['transactionIndex']) > int(filtered_events[i]['transactionIndex']): 178 | index = i 179 | elif int(e['blockNumber']) > int(filtered_events[i]['blockNumber']): 180 | index = i 181 | break 182 | filtered_events = filtered_events[:index] + [e] + filtered_events[index:] 183 | 184 | # get tx data fields: txhash, input, from, value 185 | # bytes32, bytes, address, uint256 186 | hashes = [] 187 | inputs = [] 188 | froms = [] 189 | values = [] 190 | for e in filtered_events: 191 | txhash = e['transactionHash'] 192 | txdata = w3.eth.getTransaction(txhash) 193 | hashes.append(Web3.toBytes(hexstr=txhash.hex())) 194 | inputs.append(Web3.toBytes(hexstr=txdata['input'])) 195 | froms.append(Web3.toBytes(hexstr=txdata['from'])) 196 | values.append(int(txdata['value'])) 197 | 198 | print(f'txhash: {txhash.hex()}') 199 | print(f'input (len: {len(txdata["input"])}): {txdata["input"]}') 200 | print(f'from: {txdata["from"]}') 201 | print(f'value: {int(txdata["value"])}') 202 | result = [] 203 | result.append(hashes) 204 | result.append(inputs) 205 | result.append(froms) 206 | result.append(values) 207 | # return [hashes, inputs, froms, values] # returns array of arrays 208 | return result 209 | except: 210 | traceback.print_exc() 211 | return [[], [], [], []] 212 | 213 | 214 | # same as above, but returns already encoded data (missing old incr hash!) 215 | def get_event_txs_since_encoded(contract_id: int, block_no: int): 216 | print('get_event_txs_since_encoded called') 217 | print(f'contract_id: {contract_id}') 218 | try: 219 | from_block = Web3.toHex(block_no) 220 | print(f'block_no: {from_block}') 221 | 222 | # get all events 223 | events = [] 224 | transfer_filter = manager.events.NewOperator.createFilter(fromBlock=from_block) 225 | events.append(transfer_filter.get_all_entries()) 226 | transfer_filter = manager.events.CreationInitialized.createFilter(fromBlock=from_block) 227 | events.append(transfer_filter.get_all_entries()) 228 | transfer_filter = manager.events.ContractCreated.createFilter(fromBlock=from_block) 229 | events.append(transfer_filter.get_all_entries()) 230 | 231 | # filter by contract and order events 232 | filtered_events = [] 233 | for e in events: 234 | if not e: # empty? 235 | continue 236 | # UPDATED as not limited to contract id! 237 | e = e[0] # ugly, but works ¯\_(ツ)_/¯ 238 | index = 0 239 | for i in range(len(filtered_events)): 240 | if int(e['blockNumber']) == int(filtered_events[i]['blockNumber']): 241 | if int(e['transactionIndex']) > int(filtered_events[i]['transactionIndex']): 242 | index = i 243 | elif int(e['blockNumber']) > int(filtered_events[i]['blockNumber']): 244 | index = i 245 | break 246 | filtered_events = filtered_events[:index] + [e] + filtered_events[index:] 247 | 248 | # get tx data fields: input, from, value 249 | # bytes, address, uint256 250 | encoded_result = [] 251 | for e in filtered_events: 252 | txhash = e['transactionHash'] 253 | txdata = w3.eth.getTransaction(txhash) 254 | input = Web3.toBytes(hexstr=txdata['input']) 255 | from_addr = Web3.toBytes(hexstr=txdata['from']) 256 | value = int(txdata['value']) 257 | 258 | rest = encode_abi(['bytes', 'address', 'uint256'], [input, from_addr, value]) 259 | rest_ba = bytearray(rest) 260 | rest_ba[31] = 128 # mega cheat 261 | rest = bytes(rest_ba) 262 | print(f'encoded_rest: {rest.hex()}') 263 | encoded_result.append(rest) 264 | return encoded_result 265 | except: 266 | traceback.print_exc() 267 | return [] 268 | 269 | -------------------------------------------------------------------------------- /POSEHost/manager_mockup.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | import traceback 3 | 4 | from web3 import Web3 5 | from solcx import compile_source, set_solc_version_pragma 6 | from eth_abi import encode_abi 7 | from eth_account import messages 8 | 9 | # Mockup class for local testing of POSE enclaves 10 | 11 | set_solc_version_pragma('0.6.1') 12 | 13 | # config 14 | contract_address = '0x27d160115a1E2aA7C4F709dDEB9dABbA82Ba5188' 15 | account_address = '0x90F8bf6A479f320ead074411a4B0e7944Ea8c9C1' 16 | sol_file = 'PoseManager_ECDSA.sol' 17 | w3_address = 'http://0.0.0.0:0000' 18 | 19 | # init 20 | w3 = None 21 | manager = None 22 | def init(): 23 | tmp = 123 24 | 25 | 26 | def register_enclave(addr: bytes, epk: bytes, esig: bytes): 27 | print('register_enclave called') 28 | return 0 29 | 30 | 31 | def init_creation(addr: bytes, code_hash: bytes, contract_id: int): 32 | print('init_creation called') 33 | return 0 34 | 35 | 36 | def finalize_creation(contract_id: int, pool_addr: bytes, pool_ops: List[bytes], esig: bytes): 37 | print('finalize_creation called') 38 | return 0 39 | 40 | 41 | def finalize_creation_encoding(contract_id: int, pool_addr: bytes, pool_ops: List[bytes], cp_hash:bytes, code_hash: bytes): 42 | print('finalize_creation called') 43 | return 0 44 | 45 | 46 | def get_operator_list(): 47 | print('get_operator_list called') 48 | result = [Web3.toBytes(hexstr='0x90F8bf6A479f320ead074411a4B0e7944Ea8c9C1'), 49 | Web3.toBytes(hexstr='0xFFcf8FDEE72ac11b5c542428B35EEF5769C409f0'), 50 | Web3.toBytes(hexstr='0x22d491Bde2303f2f43325b2108D26f1eAbA1e32b')] 51 | return result 52 | 53 | 54 | def get_event_txs_since(contract_id: int, block_no: int): 55 | print('get_event_txs_since called') 56 | print(f'contract_id: {contract_id}') 57 | return [[], [], [], []] # not relevant anymore, see encoded version 58 | 59 | 60 | # same as above, but returns already encoded data 61 | def get_event_txs_since_encoded(contract_id: int, block_no: int): 62 | print('get_event_txs_since_encoded called') 63 | print(f'contract_id: {contract_id}') 64 | print(f'resulting CP should be: 0x0ef813c8fe6c25ee77cd4ac10b4928151695a894121ee3ddbee692891d4a2cd6') 65 | result = [Web3.toBytes(hexstr='000000000000000000000000000000000000000000000000000000000000008000000000000000000000000090f8bf6a479f320ead074411a4b0e7944ea8c9c10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006453c81db600000000000000000000000090f8bf6a479f320ead074411a4b0e7944ea8c9c1290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563000000000000000000000000000000000000000000000000000000000000007b00000000000000000000000000000000000000000000000000000000'), 66 | Web3.toBytes(hexstr='000000000000000000000000000000000000000000000000000000000000008000000000000000000000000090f8bf6a479f320ead074411a4b0e7944ea8c9c100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000124786cd4d700000000000000000000000090f8bf6a479f320ead074411a4b0e7944ea8c9c1000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000001bfc6070de4a0753cff0f2d7736e367f8726fddb1307f8be1845f5d90228dcaca947dec8d9208ad6acfa1afe92f56bc65636a862cc1183233070f1626d412587d200000000000000000000000000000000000000000000000000000000')] 67 | return result 68 | 69 | -------------------------------------------------------------------------------- /ReadMe.md: -------------------------------------------------------------------------------- 1 | # POSE: *P*ractical *O*ff-chain *S*mart Contract *E*xecution 2 | This repository contains the prototype for the paper of the same name. Note that this implementation is a research prototype and not ready for production. 3 | 4 | ## Overview 5 | - `SmartContract` contains the Solidity-based *Manager* contract. 6 | - `POSEHost` contains the Python code to call the *Manager* contract as well as the C code to access the Python functionality on an enclave. 7 | - The enclave code running Lua scripts will be included soon. 8 | 9 | ## Prerequisites for Ubuntu 10 | - Ethereum testchain deployed, which can be on an external machine. We will refer to its IP and Port by <0.0.0.0:0000> 11 | - Truffle installation: 12 | - Dependencies: 13 | ``` 14 | sudo apt-get -y install curl git vim build-essential 15 | ``` 16 | - NodeJS: 17 | ``` 18 | curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash - 19 | sudo apt-get install -y nodejs 20 | ``` 21 | - Truffle: 22 | ``` 23 | sudo npm install -g truffle 24 | ``` 25 | - For `POSEhost` execute: 26 | - Have at least Python version 3.7 installed 27 | - Install dependency packages: 28 | ``` 29 | pip install web3 py-solc py-solc-x eth-abi 30 | ``` 31 | - Install local solidity compiler version 0.6.1 by excuting in Python: 32 | ``` 33 | from solcx import install_solc 34 | install_solc('v0.6.1') 35 | ``` 36 | - Compile the C code in folder `POSEHost/Csrc` with the compiler flags provided by the commands: 37 | ``` 38 | python3-config --cflags 39 | python3-config --ldflags 40 | ``` 41 | - The Python files as well as the Solidity *Manager* file need to be placed in the execution directory of the binaries of the C-code 42 | 43 | ## Deploy 44 | - Make sure the testchain is running 45 | - If you want to deploy a new version just execute the command from the shell in the folder "SmartContract": 46 | ``` 47 | truffle migrate --reset 48 | ``` 49 | - The last command will output the *Manager* contract address, which needs to be set in `POSEHost/manager.py` 50 | - `POSEHost/fullManagerTest.py` tests all functionalities of the *Manager* 51 | - If there are problems with re-deploying the contract, you may want to restart the testchain. 52 | - If the testchain crashes execute and check: 53 | ``` 54 | nohup ganache-cli -d -h 0.0.0.0 > ganache.log & 55 | ``` 56 | - Find some test accounts with funds, available after testchain setup are: 57 | ``` 58 | Public Accounts: 59 | 60 | (0) 0x90F8bf6A479f320ead074411a4B0e7944Ea8c9C1 (100 ETH) 61 | (1) 0xFFcf8FDEE72ac11b5c542428B35EEF5769C409f0 (100 ETH) 62 | (2) 0x22d491Bde2303f2f43325b2108D26f1eAbA1e32b (100 ETH) 63 | (3) 0xE11BA2b4D45Eaed5996Cd0823791E0C93114882d (100 ETH) 64 | (4) 0xd03ea8624C8C5987235048901fB614fDcA89b117 (100 ETH) 65 | (5) 0x95cED938F7991cd0dFcb48F0a06a40FA1aF46EBC (100 ETH) 66 | (6) 0x3E5e9111Ae8eB78Fe1CC3bb8915d5D461F3Ef9A9 (100 ETH) 67 | (7) 0x28a8746e75304c0780E011BEd21C72cD78cd535E (100 ETH) 68 | (8) 0xACa94ef8bD5ffEE41947b4585a84BdA5a3d3DA6E (100 ETH) 69 | (9) 0x1dF62f291b2E969fB0849d99D9Ce41e2F137006e (100 ETH) 70 | 71 | Respective Private Keys: 72 | 73 | (0) 0x4f3edf983ac636a65a842ce7c78d9aa706d3b113bce9c46f30d7d21715b23b1d 74 | (1) 0x6cbed15c793ce57650b9877cf6fa156fbef513c4e6134f022a85b1ffdd59b2a1 75 | (2) 0x6370fd033278c143179d81c5526140625662b8daa446c22ee2d73db3707e620c 76 | (3) 0x646f1ce2fdad0e6deeeb5c7e8e5543bdde65e86029e2fd9fc169899c440a7913 77 | (4) 0xadd53f9a7e588d003326d1cbf9e4a43c061aadd9bc938c843a79e7b4fd2ad743 78 | (5) 0x395df67f0c2d2d9fe1ad08d1bc8b6627011959b79c53d7dd6a3536a33ab8a4fd 79 | (6) 0xe485d098507f54e7733a205420dfddbe58db035fa577fc294ebd14db90767a52 80 | (7) 0xa453611d9419d0e56f499079478fd72c37b251a94bfde4d19872c44cf65386e3 81 | (8) 0x829e924fdf021ba3dbbc4225edfece9aca04b929d6e75613329ca6f1d31c0bb4 82 | ``` 83 | -------------------------------------------------------------------------------- /SmartContract/attestations/AboutSignatures.md: -------------------------------------------------------------------------------- 1 | # About Signatures 2 | 3 | ## The Attestation key 4 | 5 | - Bit length: 2048 6 | - e: 0x03 (3) 7 | - N: 0xBF0C3A0DF9551E2CCE270FF8AF13E6FCC879B4FB2910FA40283C8E075F1B3E61D8EDC99EEED97131B2CBBA8C4A77682FE1B1D12BE775EB7C8D59F59B69606D7DF18ED93F635875530D7DFC182010A31BB447DDB8519852DE08919A51675A548BBE5DD4EA0B97138EFBF74E5ED133AD4DB512C152910DF0F4090CEB05A98009C9E6C3D27B7D2A39DD265DFEB1AE764ECF7126048F5D263B2C17734B750D0FC158FD2D8429D20D0CF96B79DF481317427017854FAD52FFAEFB784757796FDA0F218AAF9F4F44F0D316EC3824FE887C3A8556AE18495D17548B63D7224E7A37A22BB5BBE09C36CDBC87761909A46E646215CBA0B7C36E798671D1B0C5C98A900459 (24117545496340649927160431213498661691771364139834839428733707095593599644269466331547978263330941166329352721509418302973129038365431840333677670769432236444768352867286642841992037157861464652609753885825811094109841377998917688379897577242911170588007227707906810003870336984283759189632253207352889139263954308374993473079714822098356023037734483690585337570187689695780484394328168954310518502244966501808527267401118729612250553397397885946542304597589714282915242899389344541501615593263934736678475627263067601620451005142783889141628013848330491856105196735234871975435397931841859914029031628518902050325593) 8 | - d: 0x7f5d7c0950e36973341a0aa5ca0d44a885a678a770b5fc2ac57db404ea122996909e8669f490f62121dd270831a4f01febcbe0c7efa3f25308e6a3bcf0eaf3a94bb490d4ece5a38cb3a952bac00b1767cd853e7ae110373eb061118b9a3c385d2993e346b264b7b4a7fa343f362273892361d6370b5ea0a2b0b347591baab1301da3d27156b1508d31052152d5fcc8f177ed8b33cd9fedb4bef256b3164526f5dccf6fa24a009e5e791e645baa303890318c48d8dfaab812bc1d4669638973ffe86e0ac481665dc7142c36ae8234514dfe7f31cef85b3fd5ca870b79e69530a3ed94f5534ec0eeb69b58b7bf2757a44e7e637a194f7e0121ce33c037aa8fc8ab (16078363664227099951440287475665774461180909426556559619155804730395733096179644221031985508887294110886235147672945535315419358910287893555785113846288157629845568578191095227994691438574309768406502590550540729406560918665945125586598384828607447058671485138604540002580224656189172793088168804901926092842429140810892553713083655364174671969718108625053866573766352806115648489602398871601233602354253136552279209763139475294319312347938091226098381463798404706988169375075869747874601480560909125578790088970821558025091155337834652118801518209568193848950937024271079854065695801298709517482202546012437420689579) 9 | - Prime1: 00dd9c2ec64640c94113e26eac9b4863462fc7e692408533aba7c1121c92990db6c2b5151a6f070924f7784a0f48013885edbe997fdbbd2eb74b8c64c1f46407013ee4a33393a2622c990dcd2c07fd017c72b9244434dc82d9fa26e97657cacc75dba5d89e83eb9f37e152c0325fc18adbc75031d121a936e11c7d47266bda80f9 10 | - Prime2: 00dcb1e80b34df77c848f3de08d232be1f0d79cd2f683122f15146b74bd90ef9316f41479bf4051646be53feaf4bcdb511df7448e827c26c28128f09196627da206f25ebf4ef34e43fb4e805ccbd30bf13e636294eb3b1f1f0b9e5a7a1488d0cbff5b69800bcc0b73dabc135d3539f60c446bb4ecc55934dddffe5de4f9eddd661 11 | 12 | ## Useful links and tools 13 | 14 | - Manually check keys and do RSA operations: https://www.mobilefish.com/services/rsa_key_generation/rsa_key_generation.php 15 | - Solidity Library for RSA Verification (might be outdated): https://github.com/adria0/SolRsaVerify 16 | - Explains steps done by openssl sign: https://medium.com/@bn121rajesh/rsa-sign-and-verify-using-openssl-behind-the-scene-bf3cac0aade2 17 | 18 | ## Useful commands 19 | 20 | - Generate private key: openssl genrsa -3 -out attestationPrivateKey.pem 2048 21 | - Derive public key: openssl rsa -in attestationPrivateKey.pem -outform PEM -pubout -out public.pem 22 | - Display key information: openssl rsa -in attestationPrivateKey.pem -text 23 | - Write hex to be encoded into .tex-file (Cannot be displayed as it is no ASCII encoding): perl -e 'print pack "H*", ""' > toBeSignedTxt/attestationStringPartyX.txt 24 | - Sign .tex-file and write it to signature file: openssl dgst -sha256 -sign attestationPrivateKey.pem -out signatures/signatureX.sign toBeSignedTxt/attestationStringPartyX.txt 25 | - Display signature as hex string: xxd -p signatures/signatureX.sign | tr -d \\n 26 | 27 | ## Useful scripts 28 | 29 | - Write the byte arrays that are to be signed to files toBeSignedTxt/attestationStringParty.txt 30 | - The byte arrays are hard coded 31 | - Sign the byte arrays that are written to to files toBeSignedTxt/attestationStringParty.txt and write the result to toBeSignedTxt/attestationStringParty.txt (For i in [0,9]) 32 | - Print the signatures of files toBeSignedTxt/attestationStringParty.txt (For i in [0,9]) to console 33 | 34 | ## Some addresses and signatures 35 | 36 | Available Accounts 37 | ================== 38 | (0) 0x90F8bf6A479f320ead074411a4B0e7944Ea8c9C1 (100 ETH) 39 | (1) 0xFFcf8FDEE72ac11b5c542428B35EEF5769C409f0 (100 ETH) 40 | (2) 0x22d491Bde2303f2f43325b2108D26f1eAbA1e32b (100 ETH) 41 | (3) 0xE11BA2b4D45Eaed5996Cd0823791E0C93114882d (100 ETH) 42 | (4) 0xd03ea8624C8C5987235048901fB614fDcA89b117 (100 ETH) 43 | (5) 0x95cED938F7991cd0dFcb48F0a06a40FA1aF46EBC (100 ETH) 44 | (6) 0x3E5e9111Ae8eB78Fe1CC3bb8915d5D461F3Ef9A9 (100 ETH) 45 | (7) 0x28a8746e75304c0780E011BEd21C72cD78cd535E (100 ETH) 46 | (8) 0xACa94ef8bD5ffEE41947b4585a84BdA5a3d3DA6E (100 ETH) 47 | (9) 0x1dF62f291b2E969fB0849d99D9Ce41e2F137006e (100 ETH) 48 | 49 | Private Keys 50 | ================== 51 | (0) 0x4f3edf983ac636a65a842ce7c78d9aa706d3b113bce9c46f30d7d21715b23b1d 52 | (1) 0x6cbed15c793ce57650b9877cf6fa156fbef513c4e6134f022a85b1ffdd59b2a1 53 | (2) 0x6370fd033278c143179d81c5526140625662b8daa446c22ee2d73db3707e620c 54 | (3) 0x646f1ce2fdad0e6deeeb5c7e8e5543bdde65e86029e2fd9fc169899c440a7913 55 | (4) 0xadd53f9a7e588d003326d1cbf9e4a43c061aadd9bc938c843a79e7b4fd2ad743 56 | (5) 0x395df67f0c2d2d9fe1ad08d1bc8b6627011959b79c53d7dd6a3536a33ab8a4fd 57 | (6) 0xe485d098507f54e7733a205420dfddbe58db035fa577fc294ebd14db90767a52 58 | (7) 0xa453611d9419d0e56f499079478fd72c37b251a94bfde4d19872c44cf65386e3 59 | (8) 0x829e924fdf021ba3dbbc4225edfece9aca04b929d6e75613329ca6f1d31c0bb4 60 | (9) 0xb0057716d5917badaf911b193b12b910811c1497b5bada8d7711f758981c3773 61 | 62 | Encoded Messages 63 | ================== 64 | 65 | - = abi.encodePacked("Pose-Attest" || hash(Enclave-Program) || Enclave Ethereum Address || Enclave Encryption Key) 66 | - with hash(Enclave-Program) = 0x0a28e9ffef0073f9a6a674cf57ee77307f38f0f1bebb087888d9011ed0eeefdf 67 | - and Enclave Encryption Key = 0x4242424242424242424242424242424242424242424242424242424242424242 68 | 69 | (0) 0x506f73652d4174746573740a28e9ffef0073f9a6a674cf57ee77307f38f0f1bebb087888d9011ed0eeefdf90f8bf6a479f320ead074411a4b0e7944ea8c9c14242424242424242424242424242424242424242424242424242424242424242 70 | (1) 0x506f73652d4174746573740a28e9ffef0073f9a6a674cf57ee77307f38f0f1bebb087888d9011ed0eeefdfffcf8fdee72ac11b5c542428b35eef5769c409f04242424242424242424242424242424242424242424242424242424242424242 71 | (2) 0x506f73652d4174746573740a28e9ffef0073f9a6a674cf57ee77307f38f0f1bebb087888d9011ed0eeefdf22d491bde2303f2f43325b2108d26f1eaba1e32b4242424242424242424242424242424242424242424242424242424242424242 72 | (3) 0x506f73652d4174746573740a28e9ffef0073f9a6a674cf57ee77307f38f0f1bebb087888d9011ed0eeefdfe11ba2b4d45eaed5996cd0823791e0c93114882d4242424242424242424242424242424242424242424242424242424242424242 73 | (4) 0x506f73652d4174746573740a28e9ffef0073f9a6a674cf57ee77307f38f0f1bebb087888d9011ed0eeefdfd03ea8624c8c5987235048901fb614fdca89b1174242424242424242424242424242424242424242424242424242424242424242 74 | (5) 0x506f73652d4174746573740a28e9ffef0073f9a6a674cf57ee77307f38f0f1bebb087888d9011ed0eeefdf95ced938f7991cd0dfcb48f0a06a40fa1af46ebc4242424242424242424242424242424242424242424242424242424242424242 75 | (6) 0x506f73652d4174746573740a28e9ffef0073f9a6a674cf57ee77307f38f0f1bebb087888d9011ed0eeefdf3e5e9111ae8eb78fe1cc3bb8915d5d461f3ef9a94242424242424242424242424242424242424242424242424242424242424242 76 | (7) 0x506f73652d4174746573740a28e9ffef0073f9a6a674cf57ee77307f38f0f1bebb087888d9011ed0eeefdf28a8746e75304c0780e011bed21c72cd78cd535e4242424242424242424242424242424242424242424242424242424242424242 77 | (8) 0x506f73652d4174746573740a28e9ffef0073f9a6a674cf57ee77307f38f0f1bebb087888d9011ed0eeefdfaca94ef8bd5ffee41947b4585a84bda5a3d3da6e4242424242424242424242424242424242424242424242424242424242424242 78 | (9) 0x506f73652d4174746573740a28e9ffef0073f9a6a674cf57ee77307f38f0f1bebb087888d9011ed0eeefdf1df62f291b2e969fb0849d99d9ce41e2f137006e4242424242424242424242424242424242424242424242424242424242424242 79 | 80 | Signatures 81 | ================== 82 | (0) 0x583a1d6ae990a637b70903ec743c5f85e8f952310807305380714a9af54b9ec08e7923356645bf9be2c45bb02b10f8db769e901d45ceaaee95acc905d1da5fe3fc8da3d1ff2ad04e98838220259cecda1f2f660b40b013632a8ca43101cf87109f1027f30bfd53e274dcc38675254ad6b43452b70832c193aac3daba9e9cea09e3cc888cde6970a804517bca3cc2705ce8e1cff3709f0e67d867b370c0d1caf05ec99237f5f4d2d530d219e37737d75a390c4bda6a2716f7c3d9ea29f7a2dd9bdc246f44aea0d07fb2e25c3546e4f805f93fd5c7d578725ee07c317c4d3c3f00d61ae81a1e2853d767443417201d96cec6dd180ba24175d63322b16248e1633f 83 | (1) 0x451d69cac2fb1f608ee880dea4bf08fa9ab6064a168483c3a0150ed76dbb224565f509f74d806f7771513e8b91adda560074150585e1603d2a867c07f8655284892c3c9808adedbda5a6c70cc0395d4eff331ce48180d55b34ca07c30602ea156d4287ddfdab1424547b80d39056dc0b6f6e0851ddcd8e2d27c13aca096156292fb40ec87da27d89ea12319fd1fb3e63637d19c273ce80805426fad1e55415fe76b9faeb9227e7a3370469d4376cce86178561c9c8295f4f9eb3844a210a9db8d8c37e230b491a0d3225f5f559fbf8ec7416cefbc53dadf830944c171063288940b2ecf5f53685ff4ff00f0b590a4c197f543a1edac3ba5feebca9a7f54af04c 84 | (2) 0x0dbc2fdde23e716ae469b34eb6b724e003ebe4d6c993a934156a33fcece9fd772bde6531a71cc1616c62dcd1ec81f90b543b81a935ce950ee215cb5b410d8b0dff6d82c8bb1bd3d5440ed7aeb755ac3688d224d74004ed86dafacb852e3a788cfbc4c073767d69cb9df4850f47d808769acf895b528db7970cf3a763b5df1c7120f362afc2ba498731427f03f56cb1264d39fcc3d083f2a99c3d12f278e432a868f38eb79f2bf5527663596dcdbaf1eb7934ae794ab2617f9140103fee3905b60d1ae13626b8d757aff2f06de8a3639433ad63604d542fa94b52b2547d28e64c82b08ea0f8bb9059b28abe803c89376ecfad9f90b486eb68d259958fd2774b12 85 | (3) 0x74c321cd6e32ab7bd6a9b783453e5091a6624ca86adcfd64046ce4681aaf03c4f1bc0d941cadf27962f9c1a43ffc92a54cfcdf4541e69d3e8c40f54985125fc5761f25f73bc244e589e9304a0a58c1275ec80d48e848e9a613f4159be00c5617da288b5813835ba329ec81e0f14157c9b890cdc80d53609e76c3f4037e58a0ed3631b4d93980a7c51a3bd5b474149876d18b016e2eb7e8403fd952492bdeb544a10e2ff1c2b094803ac6816e644575fb0810d6a3d267c3d84d4fca65c22b5bbcc564c60db21adbe308d9fb59b2bd13d33067105b52fdaf8007a230e75d8c2212088d88eb33dff685b68705f256bb6d57b568165443e64bc7f6c71b7650efaa53 86 | (4) 0xa9dbaea7dead39f262993d46f2673389deedb0cb2779d191340ced38921ca731d527f60814305c555bf5e21619765ccd4c1c0a5fea73de96d3b471ca62e993f9544fe3a12bc4f5419940f1a5f0acdc7d402c071e48028d4648cd867d5d10b0b2bc6480827978ec89d454018df69ff3ebd240cbf356fcef697813ff2ee4dde46cdd5a29d2cbeaa8d54396332fc1c1586f262d1558396eab5b2b9ff877b76ee7250b634fc8fcb4be41ec4d2cc6c4e8ddecee2c499e8d4bdd0552bba1dba044f7fbe001b73b32933e709fd252263ced81a7d1fcb1abd89176c782898b414c891b5fe979cec66580c43613f5845713281e50c38dc0b1d96f58143f0ed3532a95ddb5 87 | (5) 0x4944b696203e8c161e5031007ffc075b5a7a7829f87b1118e6375d449ed6c6387112f786061dfad142807c7e2e1f7b08cc0a3199c4c0709647c3a3f46cc96927d4f2168e812d30fef3541feda0f71d171e037976e8631c0a5b83464a9a2d05336942ed99d55cf1459ca78a5f236a8f4c1680505d8699aa9189ded17394aca51ec5d1de02706b5340c0070491e8dc5de7cfe7fa3e57af4165ceb865ccddd1ae453382bce290c89fe664807e28105f736525707d1fc54244bc3b80414290a4cfc37761cc8583fce9a813906ed28669ecca7975d4450f40c5ed50ff2e70a4106cc8ea0131944ac33f9bc07a22550e01f90318d8411e45fe6d4b9ff25b33c3050a9c 88 | (6) 0xbeaef148f554f98d1ed4606d7f87d77d69c9d986ef984a3fb3179aa569c98214e24c6b86b419a9459c8ed093a42d25c7f3fcf1202b8c8c9d50faa17afa4e6ede2d87ea8cae180bf02309c8255cbaf709c0af3f087efd1fbbd099a6ce6b71b0b6ed47a0cb7d8feac0b31bc6fd2627b895b155b78747bed4509a92df592a228224c02ad63ceb391d270fcf1a8ee65ef7d7f1aaf943fb6285a8e68d53eed3233931d4be12ed51a8b0a43bf5680131752b3d7bb31c819d2f2d86e6693fd533969b4963c5456a605bc1bb9c3920679616d1bbb0d45c75d7ca5eaee310159ea87316315b71e20a93ba35e7e9dba83246cf4a6c588f4c6810dd8d2274ea37437eaa5cde 89 | (7) 0x83fc3e404fcfcface817ff888597b2a573c02acc2e26ca79a6fcb857e0d0fa3cc78e5eacbc0375b6476b76f1fa3a708f9fa2941212025b6e14effec82e97c00b810a8905e55bed1ffd81d783e23d397bb906094a43684f387a51b6c0873650091a1de0a9a38a7c357389b6249e1cd556a91d65acfaa9743a491a6f765c10f553bc6b72a06af5ce7a2e7434bf882b3e4ec451329440cda60551f7c005f2249be5ebf1997eb0ac36cca1965cd580f6c31419b819ed807f34ec0de31048fb3ae1159afb29c4ef0dc359fc7b227467db1243788e88ef212035d00f0e0f0ea5e231ae440358e2c9a1ecb763c6ccc04dd823220344e3102279fd0ce1c3c51dbd3f40b3 90 | (8) 0x5e75d6420d3702799710a096f37406493e5f637d1dae7986e79dee9eca9f3fdac9ef22b0e7a7e3809348e3709cc9c1d1746306108e9cf8e7be392049c10ff9c1a188d1bd14b75802b890c467c202cac71026d814f238fe2676dcda818a27b547cbc3b80fc09a577fd43d95e5d404b4cd362bf30d2a39ad059b623398c65bededdb63522c791d100a4408c898cd9fcbe32e7fe6c36c743d8e48b2548e1c00e4670ade6f82dcea9f9a3cf15e68b54b1c4c4ac43643fb276af10c817959e4e0d5b78469e4cd01faabb15368ec73332089a4abcdc0779e130468322d99426b9a2cc49eeaa8833227283a38863f2d7f83741b7f72db4cd40f5687360e8cb9478f57ea 91 | (9) 0x6cfa24b0bd34ae8ec7138bc076dacb4701f6d4e2ad74a4f9b659e3939a35cfb42508b505975139a4732ef45ae5782a9bc7678c79ca38a66eb6fe3aa472e0ac2ff30345b4a7a9e07a3f4ff9d311bd5732940ecc02d6825bddbedbf00a8f00523fed363f0512716c41a55e82496feb3195c60fc61cb315ecd6b06b2125f50939c7db44d8619a768c5bd0747e43f3cf1563533382812eb24df0af2a75cb9a93f6856f0569830457e651b0b1b52056c34c6793d9dab3556281848d75a7bb8a38186df31fece3b6129ced92f63fde4a43e29c2a691ae37599b5f72096666edf991273fdc316cad846ddede5b2bf7eba6ac9d9d15b1424404f27949e48b8591d814d74] 92 | -------------------------------------------------------------------------------- /SmartContract/attestations/attestationPrivateKey.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIEowIBAAKCAQEAvww6DflVHizOJw/4rxPm/Mh5tPspEPpAKDyOB18bPmHY7cme 3 | 7tlxMbLLuoxKd2gv4bHRK+d163yNWfWbaWBtffGO2T9jWHVTDX38GCAQoxu0R924 4 | UZhS3giRmlFnWlSLvl3U6guXE477905e0TOtTbUSwVKRDfD0CQzrBamACcnmw9J7 5 | fSo53SZd/rGudk7PcSYEj10mOywXc0t1DQ/BWP0thCnSDQz5a3nfSBMXQnAXhU+t 6 | Uv+u+3hHV3lv2g8hiq+fT0Tw0xbsOCT+iHw6hVauGEldF1SLY9ciTno3oiu1u+Cc 7 | Ns28h3YZCaRuZGIVy6C3w255hnHRsMXJipAEWQIBAwKCAQB/XXwJUONpczQaCqXK 8 | DUSohaZ4p3C1/CrFfbQE6hIplpCehmn0kPYhId0nCDGk8B/ry+DH76PyUwjmo7zw 9 | 6vOpS7SQ1Ozlo4yzqVK6wAsXZ82FPnrhEDc+sGERi5o8OF0pk+NGsmS3tKf6ND82 10 | InOJI2HWNwteoKKws0dZG6qxMB2j0nFWsVCNMQUhUtX8yPF37YszzZ/ttL7yVrMW 11 | RSb13M9vokoAnl55HmRbqjA4kDGMSNjfqrgSvB1GaWOJc//obgrEgWZdxxQsNq6C 12 | NFFN/n8xzvhbP9XKhwt55pUwo+2U9VNOwO62m1i3vydXpE5+Y3oZT34BIc4zwDeq 13 | j8irAoGBAN2cLsZGQMlBE+JurJtIY0Yvx+aSQIUzq6fBEhySmQ22wrUVGm8HCST3 14 | eEoPSAE4he2+mX/bvS63S4xkwfRkBwE+5KMzk6JiLJkNzSwH/QF8crkkRDTcgtn6 15 | Jul2V8rMddul2J6D65834VLAMl/BitvHUDHRIak24Rx9RyZr2oD5AoGBANyx6As0 16 | 33fISPPeCNIyvh8Nec0vaDEi8VFGt0vZDvkxb0FHm/QFFka+U/6vS821Ed90SOgn 17 | wmwoEo8JGWYn2iBvJev07zTkP7ToBcy9ML8T5jYpTrOx8fC55aehSI0Mv/W2mAC8 18 | wLc9q8E101OfYMRGu07MVZNN3f/l3k+e3dZhAoGBAJO9dIQu1duAt+xJyGeFl4Qf 19 | 2pm21a4icm/WDBMMZgkkgc4OEZ9aBhik+twKMADQWUkpu6qSfh8k3QhDK/hCr1Yp 20 | 7cIiYmxBcxCz3h1aqKuoTHttgs3oVzv8GfD5j9yITpJukGmtR796ljcqzD/WXJKE 21 | 4CE2FnDPQL2o2hmdPFX7AoGBAJMhRVzN6k/a200+sIwh1BSzpojKRXYXS4uEejKQ 22 | tKYg9NYvvU1YuYR+4qnKMokjYT+i20Vv1vLFYbSwu5lv5sBKGUf4n3iYKniaroh+ 23 | IH9imXlw3yJ2oUsmmRprhbNd1U55uqsogHopHSt5N40U6y2EfN8y47eJPqqZPt+/ 24 | Po7rAoGBAKW/90QgdMkN6aOfSLTHt1xleKoBLH2epBBVa88N2haPxFxWzKDp5MN2 25 | +PJ4SJIuTwcLcb7fOSobtwhUshCwYXoS02+yqxQhx3fUdPC9kXXglgRrOnor5Teb 26 | iSzLPNiiYC4m1nNiIcFnWOoJKBFfPvCs4msmJgmJ86Lhh8YPyCB0 27 | -----END RSA PRIVATE KEY----- 28 | -------------------------------------------------------------------------------- /SmartContract/attestations/printAllSignatures.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo '["0x' 4 | xxd -p signatures/signature0.sign | tr -d \\n 5 | echo '","0x' 6 | xxd -p signatures/signature1.sign | tr -d \\n 7 | echo '","0x' 8 | xxd -p signatures/signature2.sign | tr -d \\n 9 | echo '","0x' 10 | xxd -p signatures/signature3.sign | tr -d \\n 11 | echo '","0x' 12 | xxd -p signatures/signature4.sign | tr -d \\n 13 | echo '","0x' 14 | xxd -p signatures/signature5.sign | tr -d \\n 15 | echo '","0x' 16 | xxd -p signatures/signature6.sign | tr -d \\n 17 | echo '","0x' 18 | xxd -p signatures/signature7.sign | tr -d \\n 19 | echo '","0x' 20 | xxd -p signatures/signature8.sign | tr -d \\n 21 | echo '","0x' 22 | xxd -p signatures/signature9.sign | tr -d \\n 23 | echo '"]' 24 | -------------------------------------------------------------------------------- /SmartContract/attestations/public.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MIIBIDANBgkqhkiG9w0BAQEFAAOCAQ0AMIIBCAKCAQEAvww6DflVHizOJw/4rxPm 3 | /Mh5tPspEPpAKDyOB18bPmHY7cme7tlxMbLLuoxKd2gv4bHRK+d163yNWfWbaWBt 4 | ffGO2T9jWHVTDX38GCAQoxu0R924UZhS3giRmlFnWlSLvl3U6guXE477905e0TOt 5 | TbUSwVKRDfD0CQzrBamACcnmw9J7fSo53SZd/rGudk7PcSYEj10mOywXc0t1DQ/B 6 | WP0thCnSDQz5a3nfSBMXQnAXhU+tUv+u+3hHV3lv2g8hiq+fT0Tw0xbsOCT+iHw6 7 | hVauGEldF1SLY9ciTno3oiu1u+CcNs28h3YZCaRuZGIVy6C3w255hnHRsMXJipAE 8 | WQIBAw== 9 | -----END PUBLIC KEY----- 10 | -------------------------------------------------------------------------------- /SmartContract/attestations/signAllPreimages.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | openssl dgst -sha256 -sign attestationPrivateKey.pem -out signatures/signature0.sign toBeSignedTxt/attestationStringParty0.txt 4 | openssl dgst -sha256 -sign attestationPrivateKey.pem -out signatures/signature1.sign toBeSignedTxt/attestationStringParty1.txt 5 | openssl dgst -sha256 -sign attestationPrivateKey.pem -out signatures/signature2.sign toBeSignedTxt/attestationStringParty2.txt 6 | openssl dgst -sha256 -sign attestationPrivateKey.pem -out signatures/signature3.sign toBeSignedTxt/attestationStringParty3.txt 7 | openssl dgst -sha256 -sign attestationPrivateKey.pem -out signatures/signature4.sign toBeSignedTxt/attestationStringParty4.txt 8 | openssl dgst -sha256 -sign attestationPrivateKey.pem -out signatures/signature5.sign toBeSignedTxt/attestationStringParty5.txt 9 | openssl dgst -sha256 -sign attestationPrivateKey.pem -out signatures/signature6.sign toBeSignedTxt/attestationStringParty6.txt 10 | openssl dgst -sha256 -sign attestationPrivateKey.pem -out signatures/signature7.sign toBeSignedTxt/attestationStringParty7.txt 11 | openssl dgst -sha256 -sign attestationPrivateKey.pem -out signatures/signature8.sign toBeSignedTxt/attestationStringParty8.txt 12 | openssl dgst -sha256 -sign attestationPrivateKey.pem -out signatures/signature9.sign toBeSignedTxt/attestationStringParty9.txt 13 | -------------------------------------------------------------------------------- /SmartContract/attestations/signatures/signature0.sign: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AppliedCryptoGroup/PoseCode/2e54471d881bc33c08ed2ec4a417c7d09610cb59/SmartContract/attestations/signatures/signature0.sign -------------------------------------------------------------------------------- /SmartContract/attestations/signatures/signature1.sign: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AppliedCryptoGroup/PoseCode/2e54471d881bc33c08ed2ec4a417c7d09610cb59/SmartContract/attestations/signatures/signature1.sign -------------------------------------------------------------------------------- /SmartContract/attestations/signatures/signature2.sign: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AppliedCryptoGroup/PoseCode/2e54471d881bc33c08ed2ec4a417c7d09610cb59/SmartContract/attestations/signatures/signature2.sign -------------------------------------------------------------------------------- /SmartContract/attestations/signatures/signature3.sign: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AppliedCryptoGroup/PoseCode/2e54471d881bc33c08ed2ec4a417c7d09610cb59/SmartContract/attestations/signatures/signature3.sign -------------------------------------------------------------------------------- /SmartContract/attestations/signatures/signature4.sign: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AppliedCryptoGroup/PoseCode/2e54471d881bc33c08ed2ec4a417c7d09610cb59/SmartContract/attestations/signatures/signature4.sign -------------------------------------------------------------------------------- /SmartContract/attestations/signatures/signature5.sign: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AppliedCryptoGroup/PoseCode/2e54471d881bc33c08ed2ec4a417c7d09610cb59/SmartContract/attestations/signatures/signature5.sign -------------------------------------------------------------------------------- /SmartContract/attestations/signatures/signature6.sign: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AppliedCryptoGroup/PoseCode/2e54471d881bc33c08ed2ec4a417c7d09610cb59/SmartContract/attestations/signatures/signature6.sign -------------------------------------------------------------------------------- /SmartContract/attestations/signatures/signature7.sign: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AppliedCryptoGroup/PoseCode/2e54471d881bc33c08ed2ec4a417c7d09610cb59/SmartContract/attestations/signatures/signature7.sign -------------------------------------------------------------------------------- /SmartContract/attestations/signatures/signature8.sign: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AppliedCryptoGroup/PoseCode/2e54471d881bc33c08ed2ec4a417c7d09610cb59/SmartContract/attestations/signatures/signature8.sign -------------------------------------------------------------------------------- /SmartContract/attestations/signatures/signature9.sign: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AppliedCryptoGroup/PoseCode/2e54471d881bc33c08ed2ec4a417c7d09610cb59/SmartContract/attestations/signatures/signature9.sign -------------------------------------------------------------------------------- /SmartContract/attestations/toBeSignedTxt/attestationStringParty0.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AppliedCryptoGroup/PoseCode/2e54471d881bc33c08ed2ec4a417c7d09610cb59/SmartContract/attestations/toBeSignedTxt/attestationStringParty0.txt -------------------------------------------------------------------------------- /SmartContract/attestations/toBeSignedTxt/attestationStringParty1.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AppliedCryptoGroup/PoseCode/2e54471d881bc33c08ed2ec4a417c7d09610cb59/SmartContract/attestations/toBeSignedTxt/attestationStringParty1.txt -------------------------------------------------------------------------------- /SmartContract/attestations/toBeSignedTxt/attestationStringParty2.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AppliedCryptoGroup/PoseCode/2e54471d881bc33c08ed2ec4a417c7d09610cb59/SmartContract/attestations/toBeSignedTxt/attestationStringParty2.txt -------------------------------------------------------------------------------- /SmartContract/attestations/toBeSignedTxt/attestationStringParty3.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AppliedCryptoGroup/PoseCode/2e54471d881bc33c08ed2ec4a417c7d09610cb59/SmartContract/attestations/toBeSignedTxt/attestationStringParty3.txt -------------------------------------------------------------------------------- /SmartContract/attestations/toBeSignedTxt/attestationStringParty4.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AppliedCryptoGroup/PoseCode/2e54471d881bc33c08ed2ec4a417c7d09610cb59/SmartContract/attestations/toBeSignedTxt/attestationStringParty4.txt -------------------------------------------------------------------------------- /SmartContract/attestations/toBeSignedTxt/attestationStringParty5.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AppliedCryptoGroup/PoseCode/2e54471d881bc33c08ed2ec4a417c7d09610cb59/SmartContract/attestations/toBeSignedTxt/attestationStringParty5.txt -------------------------------------------------------------------------------- /SmartContract/attestations/toBeSignedTxt/attestationStringParty6.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AppliedCryptoGroup/PoseCode/2e54471d881bc33c08ed2ec4a417c7d09610cb59/SmartContract/attestations/toBeSignedTxt/attestationStringParty6.txt -------------------------------------------------------------------------------- /SmartContract/attestations/toBeSignedTxt/attestationStringParty7.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AppliedCryptoGroup/PoseCode/2e54471d881bc33c08ed2ec4a417c7d09610cb59/SmartContract/attestations/toBeSignedTxt/attestationStringParty7.txt -------------------------------------------------------------------------------- /SmartContract/attestations/toBeSignedTxt/attestationStringParty8.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AppliedCryptoGroup/PoseCode/2e54471d881bc33c08ed2ec4a417c7d09610cb59/SmartContract/attestations/toBeSignedTxt/attestationStringParty8.txt -------------------------------------------------------------------------------- /SmartContract/attestations/toBeSignedTxt/attestationStringParty9.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AppliedCryptoGroup/PoseCode/2e54471d881bc33c08ed2ec4a417c7d09610cb59/SmartContract/attestations/toBeSignedTxt/attestationStringParty9.txt -------------------------------------------------------------------------------- /SmartContract/attestations/writeAllPreimagesToFile.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | perl -e 'print pack "H*", "506f73652d4174746573740a28e9ffef0073f9a6a674cf57ee77307f38f0f1bebb087888d9011ed0eeefdf90f8bf6a479f320ead074411a4b0e7944ea8c9c14242424242424242424242424242424242424242424242424242424242424242"' > toBeSignedTxt/attestationStringParty0.txt 4 | perl -e 'print pack "H*", "506f73652d4174746573740a28e9ffef0073f9a6a674cf57ee77307f38f0f1bebb087888d9011ed0eeefdfffcf8fdee72ac11b5c542428b35eef5769c409f04242424242424242424242424242424242424242424242424242424242424242"' > toBeSignedTxt/attestationStringParty1.txt 5 | perl -e 'print pack "H*", "506f73652d4174746573740a28e9ffef0073f9a6a674cf57ee77307f38f0f1bebb087888d9011ed0eeefdf22d491bde2303f2f43325b2108d26f1eaba1e32b4242424242424242424242424242424242424242424242424242424242424242"' > toBeSignedTxt/attestationStringParty2.txt 6 | perl -e 'print pack "H*", "506f73652d4174746573740a28e9ffef0073f9a6a674cf57ee77307f38f0f1bebb087888d9011ed0eeefdfe11ba2b4d45eaed5996cd0823791e0c93114882d4242424242424242424242424242424242424242424242424242424242424242"' > toBeSignedTxt/attestationStringParty3.txt 7 | perl -e 'print pack "H*", "506f73652d4174746573740a28e9ffef0073f9a6a674cf57ee77307f38f0f1bebb087888d9011ed0eeefdfd03ea8624c8c5987235048901fb614fdca89b1174242424242424242424242424242424242424242424242424242424242424242"' > toBeSignedTxt/attestationStringParty4.txt 8 | perl -e 'print pack "H*", "506f73652d4174746573740a28e9ffef0073f9a6a674cf57ee77307f38f0f1bebb087888d9011ed0eeefdf95ced938f7991cd0dfcb48f0a06a40fa1af46ebc4242424242424242424242424242424242424242424242424242424242424242"' > toBeSignedTxt/attestationStringParty5.txt 9 | perl -e 'print pack "H*", "506f73652d4174746573740a28e9ffef0073f9a6a674cf57ee77307f38f0f1bebb087888d9011ed0eeefdf3e5e9111ae8eb78fe1cc3bb8915d5d461f3ef9a94242424242424242424242424242424242424242424242424242424242424242"' > toBeSignedTxt/attestationStringParty6.txt 10 | perl -e 'print pack "H*", "506f73652d4174746573740a28e9ffef0073f9a6a674cf57ee77307f38f0f1bebb087888d9011ed0eeefdf28a8746e75304c0780e011bed21c72cd78cd535e4242424242424242424242424242424242424242424242424242424242424242"' > toBeSignedTxt/attestationStringParty7.txt 11 | perl -e 'print pack "H*", "506f73652d4174746573740a28e9ffef0073f9a6a674cf57ee77307f38f0f1bebb087888d9011ed0eeefdfaca94ef8bd5ffee41947b4585a84bda5a3d3da6e4242424242424242424242424242424242424242424242424242424242424242"' > toBeSignedTxt/attestationStringParty8.txt 12 | perl -e 'print pack "H*", "506f73652d4174746573740a28e9ffef0073f9a6a674cf57ee77307f38f0f1bebb087888d9011ed0eeefdf1df62f291b2e969fb0849d99d9ce41e2f137006e4242424242424242424242424242424242424242424242424242424242424242"' > toBeSignedTxt/attestationStringParty9.txt 13 | -------------------------------------------------------------------------------- /SmartContract/build/contracts/HelloWorld.json: -------------------------------------------------------------------------------- 1 | { 2 | "contractName": "HelloWorld", 3 | "abi": [ 4 | { 5 | "anonymous": false, 6 | "inputs": [ 7 | { 8 | "indexed": false, 9 | "internalType": "uint256", 10 | "name": "id", 11 | "type": "uint256" 12 | } 13 | ], 14 | "name": "HelloWorld", 15 | "type": "event" 16 | }, 17 | { 18 | "inputs": [], 19 | "name": "getMessage", 20 | "outputs": [ 21 | { 22 | "internalType": "string", 23 | "name": "", 24 | "type": "string" 25 | } 26 | ], 27 | "stateMutability": "view", 28 | "type": "function" 29 | }, 30 | { 31 | "inputs": [ 32 | { 33 | "internalType": "string", 34 | "name": "newMessage", 35 | "type": "string" 36 | } 37 | ], 38 | "name": "setMessage", 39 | "outputs": [], 40 | "stateMutability": "nonpayable", 41 | "type": "function" 42 | } 43 | ], 44 | "metadata": "{\"compiler\":{\"version\":\"0.6.1+commit.e6f7d5a4\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"HelloWorld\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"getMessage\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"newMessage\",\"type\":\"string\"}],\"name\":\"setMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"methods\":{}},\"userdoc\":{\"methods\":{}}},\"settings\":{\"compilationTarget\":{\"project:/contracts/HelloWorld.sol\":\"HelloWorld\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":100},\"remappings\":[]},\"sources\":{\"project:/contracts/HelloWorld.sol\":{\"keccak256\":\"0xaa8ac52a03ec3ca3a8521032ff4fa7e7e6a11a30e7b371519e37ecd391d1e36e\",\"urls\":[\"bzz-raw://cb93d92260ddf31ceb29b6146ebc6f808ad02fe2db2bea6bd08b3cf4197993a9\",\"dweb:/ipfs/QmQWGzr3iSEhU3TN9jYJEk1gQSVU38EcybFLpBys1CjPkJ\"]}},\"version\":1}", 45 | "bytecode": "0x60c0604052600b60808190526a12195b1b1bc815dbdc9b1960aa1b60a090815261002c916000919061003f565b5034801561003957600080fd5b506100da565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061008057805160ff19168380011785556100ad565b828001600101855582156100ad579182015b828111156100ad578251825591602001919060010190610092565b506100b99291506100bd565b5090565b6100d791905b808211156100b957600081556001016100c3565b90565b610311806100e96000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063368b87721461003b578063ce6d41de146100e3575b600080fd5b6100e16004803603602081101561005157600080fd5b81019060208101813564010000000081111561006c57600080fd5b82018360208201111561007e57600080fd5b803590602001918460018302840111640100000000831117156100a057600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610160945050505050565b005b6100eb6101ac565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561012557818101518382015260200161010d565b50505050905090810190601f1680156101525780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b8051610173906000906020840190610243565b5060408051610539815290517f6962dda328b40aa9e396feb586f9e63b699249f9801819856afcbb072d95cc649181900360200190a150565b60008054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156102385780601f1061020d57610100808354040283529160200191610238565b820191906000526020600020905b81548152906001019060200180831161021b57829003601f168201915b505050505090505b90565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061028457805160ff19168380011785556102b1565b828001600101855582156102b1579182015b828111156102b1578251825591602001919060010190610296565b506102bd9291506102c1565b5090565b61024091905b808211156102bd57600081556001016102c756fea26469706673582212204ca4fdbbdba9688e7d3b2e4881bc132918d8738c586d9c4e369dd0b465c5563e64736f6c63430006010033", 46 | "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100365760003560e01c8063368b87721461003b578063ce6d41de146100e3575b600080fd5b6100e16004803603602081101561005157600080fd5b81019060208101813564010000000081111561006c57600080fd5b82018360208201111561007e57600080fd5b803590602001918460018302840111640100000000831117156100a057600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610160945050505050565b005b6100eb6101ac565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561012557818101518382015260200161010d565b50505050905090810190601f1680156101525780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b8051610173906000906020840190610243565b5060408051610539815290517f6962dda328b40aa9e396feb586f9e63b699249f9801819856afcbb072d95cc649181900360200190a150565b60008054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156102385780601f1061020d57610100808354040283529160200191610238565b820191906000526020600020905b81548152906001019060200180831161021b57829003601f168201915b505050505090505b90565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061028457805160ff19168380011785556102b1565b828001600101855582156102b1579182015b828111156102b1578251825591602001919060010190610296565b506102bd9291506102c1565b5090565b61024091905b808211156102bd57600081556001016102c756fea26469706673582212204ca4fdbbdba9688e7d3b2e4881bc132918d8738c586d9c4e369dd0b465c5563e64736f6c63430006010033", 47 | "sourceMap": "47:38:4:-:0;25:284;47:38;;25:284;47:38;;;-1:-1:-1;;;47:38:4;;;;;;-1:-1:-1;;47:38:4;;:::i;:::-;;25:284;8:9:-1;5:2;;;30:1;27;20:12;5:2;25:284:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;25:284:4;;;-1:-1:-1;25:284:4;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;", 48 | "deployedSourceMap": "25:284:4:-:0;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;25:284:4;;;;;;;;;;;;;;;;;;;;;;;;200:107;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;200:107:4;;;;;;;;21:11:-1;5:28;;2:2;;;46:1;43;36:12;2:2;200:107:4;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;200:107:4;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;39:11;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;200:107:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;200:107:4;;-1:-1:-1;200:107:4;;-1:-1:-1;;;;;200:107:4:i;:::-;;119:78;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:100:-1;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;119:78:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;200:107;258:20;;;;:7;;:20;;;;;:::i;:::-;-1:-1:-1;287:16:4;;;298:4;287:16;;;;;;;;;;;;;200:107;:::o;119:78::-;186:7;179:14;;;;;;;;-1:-1:-1;;179:14:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;161:13;;179:14;;186:7;;179:14;;186:7;179:14;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;119:78;;:::o;25:284::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;25:284:4;;;-1:-1:-1;25:284:4;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;", 49 | "source": "pragma solidity ^0.6.1;\n\ncontract HelloWorld{\n\tstring private message = \"Hello World\";\n\t\n\tevent HelloWorld(uint id);\n\n\tfunction getMessage() public view returns(string memory){\n\t\treturn message;\n\t}\n\n\tfunction setMessage(string memory newMessage ) public {\n\t\tmessage = newMessage;\n\t\temit HelloWorld(1337);\n\t}\n}", 50 | "sourcePath": "/mnt/103A12BD3A129FB0/CAC/Projekte/2020_FuriousOtter/furious-otter/OSCode/SmartContract/contracts/HelloWorld.sol", 51 | "ast": { 52 | "absolutePath": "project:/contracts/HelloWorld.sol", 53 | "exportedSymbols": { 54 | "HelloWorld": [ 55 | 4822 56 | ] 57 | }, 58 | "id": 4823, 59 | "nodeType": "SourceUnit", 60 | "nodes": [ 61 | { 62 | "id": 4792, 63 | "literals": [ 64 | "solidity", 65 | "^", 66 | "0.6", 67 | ".1" 68 | ], 69 | "nodeType": "PragmaDirective", 70 | "src": "0:23:4" 71 | }, 72 | { 73 | "abstract": false, 74 | "baseContracts": [], 75 | "contractDependencies": [], 76 | "contractKind": "contract", 77 | "documentation": null, 78 | "fullyImplemented": true, 79 | "id": 4822, 80 | "linearizedBaseContracts": [ 81 | 4822 82 | ], 83 | "name": "HelloWorld", 84 | "nodeType": "ContractDefinition", 85 | "nodes": [ 86 | { 87 | "constant": false, 88 | "id": 4795, 89 | "name": "message", 90 | "nodeType": "VariableDeclaration", 91 | "overrides": null, 92 | "scope": 4822, 93 | "src": "47:38:4", 94 | "stateVariable": true, 95 | "storageLocation": "default", 96 | "typeDescriptions": { 97 | "typeIdentifier": "t_string_storage", 98 | "typeString": "string" 99 | }, 100 | "typeName": { 101 | "id": 4793, 102 | "name": "string", 103 | "nodeType": "ElementaryTypeName", 104 | "src": "47:6:4", 105 | "typeDescriptions": { 106 | "typeIdentifier": "t_string_storage_ptr", 107 | "typeString": "string" 108 | } 109 | }, 110 | "value": { 111 | "argumentTypes": null, 112 | "hexValue": "48656c6c6f20576f726c64", 113 | "id": 4794, 114 | "isConstant": false, 115 | "isLValue": false, 116 | "isPure": true, 117 | "kind": "string", 118 | "lValueRequested": false, 119 | "nodeType": "Literal", 120 | "src": "72:13:4", 121 | "subdenomination": null, 122 | "typeDescriptions": { 123 | "typeIdentifier": "t_stringliteral_592fa743889fc7f92ac2a37bb1f5ba1daf2a5c84741ca0e0061d243a2e6707ba", 124 | "typeString": "literal_string \"Hello World\"" 125 | }, 126 | "value": "Hello World" 127 | }, 128 | "visibility": "private" 129 | }, 130 | { 131 | "anonymous": false, 132 | "documentation": null, 133 | "id": 4799, 134 | "name": "HelloWorld", 135 | "nodeType": "EventDefinition", 136 | "parameters": { 137 | "id": 4798, 138 | "nodeType": "ParameterList", 139 | "parameters": [ 140 | { 141 | "constant": false, 142 | "id": 4797, 143 | "indexed": false, 144 | "name": "id", 145 | "nodeType": "VariableDeclaration", 146 | "overrides": null, 147 | "scope": 4799, 148 | "src": "107:7:4", 149 | "stateVariable": false, 150 | "storageLocation": "default", 151 | "typeDescriptions": { 152 | "typeIdentifier": "t_uint256", 153 | "typeString": "uint256" 154 | }, 155 | "typeName": { 156 | "id": 4796, 157 | "name": "uint", 158 | "nodeType": "ElementaryTypeName", 159 | "src": "107:4:4", 160 | "typeDescriptions": { 161 | "typeIdentifier": "t_uint256", 162 | "typeString": "uint256" 163 | } 164 | }, 165 | "value": null, 166 | "visibility": "internal" 167 | } 168 | ], 169 | "src": "106:9:4" 170 | }, 171 | "src": "90:26:4" 172 | }, 173 | { 174 | "body": { 175 | "id": 4806, 176 | "nodeType": "Block", 177 | "src": "175:22:4", 178 | "statements": [ 179 | { 180 | "expression": { 181 | "argumentTypes": null, 182 | "id": 4804, 183 | "name": "message", 184 | "nodeType": "Identifier", 185 | "overloadedDeclarations": [], 186 | "referencedDeclaration": 4795, 187 | "src": "186:7:4", 188 | "typeDescriptions": { 189 | "typeIdentifier": "t_string_storage", 190 | "typeString": "string storage ref" 191 | } 192 | }, 193 | "functionReturnParameters": 4803, 194 | "id": 4805, 195 | "nodeType": "Return", 196 | "src": "179:14:4" 197 | } 198 | ] 199 | }, 200 | "documentation": null, 201 | "functionSelector": "ce6d41de", 202 | "id": 4807, 203 | "implemented": true, 204 | "kind": "function", 205 | "modifiers": [], 206 | "name": "getMessage", 207 | "nodeType": "FunctionDefinition", 208 | "overrides": null, 209 | "parameters": { 210 | "id": 4800, 211 | "nodeType": "ParameterList", 212 | "parameters": [], 213 | "src": "138:2:4" 214 | }, 215 | "returnParameters": { 216 | "id": 4803, 217 | "nodeType": "ParameterList", 218 | "parameters": [ 219 | { 220 | "constant": false, 221 | "id": 4802, 222 | "name": "", 223 | "nodeType": "VariableDeclaration", 224 | "overrides": null, 225 | "scope": 4807, 226 | "src": "161:13:4", 227 | "stateVariable": false, 228 | "storageLocation": "memory", 229 | "typeDescriptions": { 230 | "typeIdentifier": "t_string_memory_ptr", 231 | "typeString": "string" 232 | }, 233 | "typeName": { 234 | "id": 4801, 235 | "name": "string", 236 | "nodeType": "ElementaryTypeName", 237 | "src": "161:6:4", 238 | "typeDescriptions": { 239 | "typeIdentifier": "t_string_storage_ptr", 240 | "typeString": "string" 241 | } 242 | }, 243 | "value": null, 244 | "visibility": "internal" 245 | } 246 | ], 247 | "src": "160:15:4" 248 | }, 249 | "scope": 4822, 250 | "src": "119:78:4", 251 | "stateMutability": "view", 252 | "virtual": false, 253 | "visibility": "public" 254 | }, 255 | { 256 | "body": { 257 | "id": 4820, 258 | "nodeType": "Block", 259 | "src": "254:53:4", 260 | "statements": [ 261 | { 262 | "expression": { 263 | "argumentTypes": null, 264 | "id": 4814, 265 | "isConstant": false, 266 | "isLValue": false, 267 | "isPure": false, 268 | "lValueRequested": false, 269 | "leftHandSide": { 270 | "argumentTypes": null, 271 | "id": 4812, 272 | "name": "message", 273 | "nodeType": "Identifier", 274 | "overloadedDeclarations": [], 275 | "referencedDeclaration": 4795, 276 | "src": "258:7:4", 277 | "typeDescriptions": { 278 | "typeIdentifier": "t_string_storage", 279 | "typeString": "string storage ref" 280 | } 281 | }, 282 | "nodeType": "Assignment", 283 | "operator": "=", 284 | "rightHandSide": { 285 | "argumentTypes": null, 286 | "id": 4813, 287 | "name": "newMessage", 288 | "nodeType": "Identifier", 289 | "overloadedDeclarations": [], 290 | "referencedDeclaration": 4809, 291 | "src": "268:10:4", 292 | "typeDescriptions": { 293 | "typeIdentifier": "t_string_memory_ptr", 294 | "typeString": "string memory" 295 | } 296 | }, 297 | "src": "258:20:4", 298 | "typeDescriptions": { 299 | "typeIdentifier": "t_string_storage", 300 | "typeString": "string storage ref" 301 | } 302 | }, 303 | "id": 4815, 304 | "nodeType": "ExpressionStatement", 305 | "src": "258:20:4" 306 | }, 307 | { 308 | "eventCall": { 309 | "argumentTypes": null, 310 | "arguments": [ 311 | { 312 | "argumentTypes": null, 313 | "hexValue": "31333337", 314 | "id": 4817, 315 | "isConstant": false, 316 | "isLValue": false, 317 | "isPure": true, 318 | "kind": "number", 319 | "lValueRequested": false, 320 | "nodeType": "Literal", 321 | "src": "298:4:4", 322 | "subdenomination": null, 323 | "typeDescriptions": { 324 | "typeIdentifier": "t_rational_1337_by_1", 325 | "typeString": "int_const 1337" 326 | }, 327 | "value": "1337" 328 | } 329 | ], 330 | "expression": { 331 | "argumentTypes": [ 332 | { 333 | "typeIdentifier": "t_rational_1337_by_1", 334 | "typeString": "int_const 1337" 335 | } 336 | ], 337 | "id": 4816, 338 | "name": "HelloWorld", 339 | "nodeType": "Identifier", 340 | "overloadedDeclarations": [], 341 | "referencedDeclaration": 4799, 342 | "src": "287:10:4", 343 | "typeDescriptions": { 344 | "typeIdentifier": "t_function_event_nonpayable$_t_uint256_$returns$__$", 345 | "typeString": "function (uint256)" 346 | } 347 | }, 348 | "id": 4818, 349 | "isConstant": false, 350 | "isLValue": false, 351 | "isPure": false, 352 | "kind": "functionCall", 353 | "lValueRequested": false, 354 | "names": [], 355 | "nodeType": "FunctionCall", 356 | "src": "287:16:4", 357 | "tryCall": false, 358 | "typeDescriptions": { 359 | "typeIdentifier": "t_tuple$__$", 360 | "typeString": "tuple()" 361 | } 362 | }, 363 | "id": 4819, 364 | "nodeType": "EmitStatement", 365 | "src": "282:21:4" 366 | } 367 | ] 368 | }, 369 | "documentation": null, 370 | "functionSelector": "368b8772", 371 | "id": 4821, 372 | "implemented": true, 373 | "kind": "function", 374 | "modifiers": [], 375 | "name": "setMessage", 376 | "nodeType": "FunctionDefinition", 377 | "overrides": null, 378 | "parameters": { 379 | "id": 4810, 380 | "nodeType": "ParameterList", 381 | "parameters": [ 382 | { 383 | "constant": false, 384 | "id": 4809, 385 | "name": "newMessage", 386 | "nodeType": "VariableDeclaration", 387 | "overrides": null, 388 | "scope": 4821, 389 | "src": "220:24:4", 390 | "stateVariable": false, 391 | "storageLocation": "memory", 392 | "typeDescriptions": { 393 | "typeIdentifier": "t_string_memory_ptr", 394 | "typeString": "string" 395 | }, 396 | "typeName": { 397 | "id": 4808, 398 | "name": "string", 399 | "nodeType": "ElementaryTypeName", 400 | "src": "220:6:4", 401 | "typeDescriptions": { 402 | "typeIdentifier": "t_string_storage_ptr", 403 | "typeString": "string" 404 | } 405 | }, 406 | "value": null, 407 | "visibility": "internal" 408 | } 409 | ], 410 | "src": "219:27:4" 411 | }, 412 | "returnParameters": { 413 | "id": 4811, 414 | "nodeType": "ParameterList", 415 | "parameters": [], 416 | "src": "254:0:4" 417 | }, 418 | "scope": 4822, 419 | "src": "200:107:4", 420 | "stateMutability": "nonpayable", 421 | "virtual": false, 422 | "visibility": "public" 423 | } 424 | ], 425 | "scope": 4823, 426 | "src": "25:284:4" 427 | } 428 | ], 429 | "src": "0:309:4" 430 | }, 431 | "legacyAST": { 432 | "attributes": { 433 | "absolutePath": "project:/contracts/HelloWorld.sol", 434 | "exportedSymbols": { 435 | "HelloWorld": [ 436 | 4822 437 | ] 438 | } 439 | }, 440 | "children": [ 441 | { 442 | "attributes": { 443 | "literals": [ 444 | "solidity", 445 | "^", 446 | "0.6", 447 | ".1" 448 | ] 449 | }, 450 | "id": 4792, 451 | "name": "PragmaDirective", 452 | "src": "0:23:4" 453 | }, 454 | { 455 | "attributes": { 456 | "abstract": false, 457 | "baseContracts": [ 458 | null 459 | ], 460 | "contractDependencies": [ 461 | null 462 | ], 463 | "contractKind": "contract", 464 | "documentation": null, 465 | "fullyImplemented": true, 466 | "linearizedBaseContracts": [ 467 | 4822 468 | ], 469 | "name": "HelloWorld", 470 | "scope": 4823 471 | }, 472 | "children": [ 473 | { 474 | "attributes": { 475 | "constant": false, 476 | "name": "message", 477 | "overrides": null, 478 | "scope": 4822, 479 | "stateVariable": true, 480 | "storageLocation": "default", 481 | "type": "string", 482 | "visibility": "private" 483 | }, 484 | "children": [ 485 | { 486 | "attributes": { 487 | "name": "string", 488 | "type": "string" 489 | }, 490 | "id": 4793, 491 | "name": "ElementaryTypeName", 492 | "src": "47:6:4" 493 | }, 494 | { 495 | "attributes": { 496 | "argumentTypes": null, 497 | "hexvalue": "48656c6c6f20576f726c64", 498 | "isConstant": false, 499 | "isLValue": false, 500 | "isPure": true, 501 | "lValueRequested": false, 502 | "subdenomination": null, 503 | "token": "string", 504 | "type": "literal_string \"Hello World\"", 505 | "value": "Hello World" 506 | }, 507 | "id": 4794, 508 | "name": "Literal", 509 | "src": "72:13:4" 510 | } 511 | ], 512 | "id": 4795, 513 | "name": "VariableDeclaration", 514 | "src": "47:38:4" 515 | }, 516 | { 517 | "attributes": { 518 | "anonymous": false, 519 | "documentation": null, 520 | "name": "HelloWorld" 521 | }, 522 | "children": [ 523 | { 524 | "children": [ 525 | { 526 | "attributes": { 527 | "constant": false, 528 | "indexed": false, 529 | "name": "id", 530 | "overrides": null, 531 | "scope": 4799, 532 | "stateVariable": false, 533 | "storageLocation": "default", 534 | "type": "uint256", 535 | "value": null, 536 | "visibility": "internal" 537 | }, 538 | "children": [ 539 | { 540 | "attributes": { 541 | "name": "uint", 542 | "type": "uint256" 543 | }, 544 | "id": 4796, 545 | "name": "ElementaryTypeName", 546 | "src": "107:4:4" 547 | } 548 | ], 549 | "id": 4797, 550 | "name": "VariableDeclaration", 551 | "src": "107:7:4" 552 | } 553 | ], 554 | "id": 4798, 555 | "name": "ParameterList", 556 | "src": "106:9:4" 557 | } 558 | ], 559 | "id": 4799, 560 | "name": "EventDefinition", 561 | "src": "90:26:4" 562 | }, 563 | { 564 | "attributes": { 565 | "documentation": null, 566 | "functionSelector": "ce6d41de", 567 | "implemented": true, 568 | "isConstructor": false, 569 | "kind": "function", 570 | "modifiers": [ 571 | null 572 | ], 573 | "name": "getMessage", 574 | "overrides": null, 575 | "scope": 4822, 576 | "stateMutability": "view", 577 | "virtual": false, 578 | "visibility": "public" 579 | }, 580 | "children": [ 581 | { 582 | "attributes": { 583 | "parameters": [ 584 | null 585 | ] 586 | }, 587 | "children": [], 588 | "id": 4800, 589 | "name": "ParameterList", 590 | "src": "138:2:4" 591 | }, 592 | { 593 | "children": [ 594 | { 595 | "attributes": { 596 | "constant": false, 597 | "name": "", 598 | "overrides": null, 599 | "scope": 4807, 600 | "stateVariable": false, 601 | "storageLocation": "memory", 602 | "type": "string", 603 | "value": null, 604 | "visibility": "internal" 605 | }, 606 | "children": [ 607 | { 608 | "attributes": { 609 | "name": "string", 610 | "type": "string" 611 | }, 612 | "id": 4801, 613 | "name": "ElementaryTypeName", 614 | "src": "161:6:4" 615 | } 616 | ], 617 | "id": 4802, 618 | "name": "VariableDeclaration", 619 | "src": "161:13:4" 620 | } 621 | ], 622 | "id": 4803, 623 | "name": "ParameterList", 624 | "src": "160:15:4" 625 | }, 626 | { 627 | "children": [ 628 | { 629 | "attributes": { 630 | "functionReturnParameters": 4803 631 | }, 632 | "children": [ 633 | { 634 | "attributes": { 635 | "argumentTypes": null, 636 | "overloadedDeclarations": [ 637 | null 638 | ], 639 | "referencedDeclaration": 4795, 640 | "type": "string storage ref", 641 | "value": "message" 642 | }, 643 | "id": 4804, 644 | "name": "Identifier", 645 | "src": "186:7:4" 646 | } 647 | ], 648 | "id": 4805, 649 | "name": "Return", 650 | "src": "179:14:4" 651 | } 652 | ], 653 | "id": 4806, 654 | "name": "Block", 655 | "src": "175:22:4" 656 | } 657 | ], 658 | "id": 4807, 659 | "name": "FunctionDefinition", 660 | "src": "119:78:4" 661 | }, 662 | { 663 | "attributes": { 664 | "documentation": null, 665 | "functionSelector": "368b8772", 666 | "implemented": true, 667 | "isConstructor": false, 668 | "kind": "function", 669 | "modifiers": [ 670 | null 671 | ], 672 | "name": "setMessage", 673 | "overrides": null, 674 | "scope": 4822, 675 | "stateMutability": "nonpayable", 676 | "virtual": false, 677 | "visibility": "public" 678 | }, 679 | "children": [ 680 | { 681 | "children": [ 682 | { 683 | "attributes": { 684 | "constant": false, 685 | "name": "newMessage", 686 | "overrides": null, 687 | "scope": 4821, 688 | "stateVariable": false, 689 | "storageLocation": "memory", 690 | "type": "string", 691 | "value": null, 692 | "visibility": "internal" 693 | }, 694 | "children": [ 695 | { 696 | "attributes": { 697 | "name": "string", 698 | "type": "string" 699 | }, 700 | "id": 4808, 701 | "name": "ElementaryTypeName", 702 | "src": "220:6:4" 703 | } 704 | ], 705 | "id": 4809, 706 | "name": "VariableDeclaration", 707 | "src": "220:24:4" 708 | } 709 | ], 710 | "id": 4810, 711 | "name": "ParameterList", 712 | "src": "219:27:4" 713 | }, 714 | { 715 | "attributes": { 716 | "parameters": [ 717 | null 718 | ] 719 | }, 720 | "children": [], 721 | "id": 4811, 722 | "name": "ParameterList", 723 | "src": "254:0:4" 724 | }, 725 | { 726 | "children": [ 727 | { 728 | "children": [ 729 | { 730 | "attributes": { 731 | "argumentTypes": null, 732 | "isConstant": false, 733 | "isLValue": false, 734 | "isPure": false, 735 | "lValueRequested": false, 736 | "operator": "=", 737 | "type": "string storage ref" 738 | }, 739 | "children": [ 740 | { 741 | "attributes": { 742 | "argumentTypes": null, 743 | "overloadedDeclarations": [ 744 | null 745 | ], 746 | "referencedDeclaration": 4795, 747 | "type": "string storage ref", 748 | "value": "message" 749 | }, 750 | "id": 4812, 751 | "name": "Identifier", 752 | "src": "258:7:4" 753 | }, 754 | { 755 | "attributes": { 756 | "argumentTypes": null, 757 | "overloadedDeclarations": [ 758 | null 759 | ], 760 | "referencedDeclaration": 4809, 761 | "type": "string memory", 762 | "value": "newMessage" 763 | }, 764 | "id": 4813, 765 | "name": "Identifier", 766 | "src": "268:10:4" 767 | } 768 | ], 769 | "id": 4814, 770 | "name": "Assignment", 771 | "src": "258:20:4" 772 | } 773 | ], 774 | "id": 4815, 775 | "name": "ExpressionStatement", 776 | "src": "258:20:4" 777 | }, 778 | { 779 | "children": [ 780 | { 781 | "attributes": { 782 | "argumentTypes": null, 783 | "isConstant": false, 784 | "isLValue": false, 785 | "isPure": false, 786 | "isStructConstructorCall": false, 787 | "lValueRequested": false, 788 | "names": [ 789 | null 790 | ], 791 | "tryCall": false, 792 | "type": "tuple()", 793 | "type_conversion": false 794 | }, 795 | "children": [ 796 | { 797 | "attributes": { 798 | "argumentTypes": [ 799 | { 800 | "typeIdentifier": "t_rational_1337_by_1", 801 | "typeString": "int_const 1337" 802 | } 803 | ], 804 | "overloadedDeclarations": [ 805 | null 806 | ], 807 | "referencedDeclaration": 4799, 808 | "type": "function (uint256)", 809 | "value": "HelloWorld" 810 | }, 811 | "id": 4816, 812 | "name": "Identifier", 813 | "src": "287:10:4" 814 | }, 815 | { 816 | "attributes": { 817 | "argumentTypes": null, 818 | "hexvalue": "31333337", 819 | "isConstant": false, 820 | "isLValue": false, 821 | "isPure": true, 822 | "lValueRequested": false, 823 | "subdenomination": null, 824 | "token": "number", 825 | "type": "int_const 1337", 826 | "value": "1337" 827 | }, 828 | "id": 4817, 829 | "name": "Literal", 830 | "src": "298:4:4" 831 | } 832 | ], 833 | "id": 4818, 834 | "name": "FunctionCall", 835 | "src": "287:16:4" 836 | } 837 | ], 838 | "id": 4819, 839 | "name": "EmitStatement", 840 | "src": "282:21:4" 841 | } 842 | ], 843 | "id": 4820, 844 | "name": "Block", 845 | "src": "254:53:4" 846 | } 847 | ], 848 | "id": 4821, 849 | "name": "FunctionDefinition", 850 | "src": "200:107:4" 851 | } 852 | ], 853 | "id": 4822, 854 | "name": "ContractDefinition", 855 | "src": "25:284:4" 856 | } 857 | ], 858 | "id": 4823, 859 | "name": "SourceUnit", 860 | "src": "0:309:4" 861 | }, 862 | "compiler": { 863 | "name": "solc", 864 | "version": "0.6.1+commit.e6f7d5a4.Emscripten.clang" 865 | }, 866 | "networks": { 867 | "1652190642321": { 868 | "events": {}, 869 | "links": {}, 870 | "address": "0x9561C133DD8580860B6b7E504bC5Aa500f0f06a7", 871 | "transactionHash": "0xf3f338bb482e4b95d3823371ecb3b24158227e1976d6798949b70e2d3de15ebc" 872 | } 873 | }, 874 | "schemaVersion": "3.4.3", 875 | "updatedAt": "2022-08-18T22:37:41.440Z", 876 | "devdoc": { 877 | "methods": {} 878 | }, 879 | "userdoc": { 880 | "methods": {} 881 | } 882 | } -------------------------------------------------------------------------------- /SmartContract/contracts/Migrations.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity >=0.4.21 <0.7.0; 3 | 4 | contract Migrations { 5 | address public owner; 6 | uint public last_completed_migration; 7 | 8 | constructor() public { 9 | owner = msg.sender; 10 | } 11 | 12 | modifier restricted() { 13 | if (msg.sender == owner) _; 14 | } 15 | 16 | function setCompleted(uint completed) public restricted { 17 | last_completed_migration = completed; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /SmartContract/contracts/PoseManager_ECDSA.sol: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2022 Authors of the POSE paper 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License 6 | as published by the Free Software Foundation; either version 2 7 | of the License, or (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | */ 18 | 19 | pragma solidity ^0.6.1; 20 | pragma experimental "ABIEncoderV2"; 21 | 22 | //The RSA-based version (attestation is performed via RSA signatures) 23 | contract PoseManager_ECDSA { 24 | 25 | //Constants 26 | uint public constant POOL_SIZE = 3; 27 | uint public constant TIMEOUT_INTERVAL = 15; //The maximal dispute time is 3 * TIMEOUT_INTERVAL 28 | //because the executive operator can get "extra time" by challenging the watchdogs 29 | 30 | //For attestation 31 | //@ClientDeveloper: The WRAPPER_PROGRAM_CODE_HASH is currently a dummy value. Once, the client attestation allows 32 | //for configurable attestation implement it to sign hash("Pose-Attest" || hash(Enclave-Program) || Enclave Ethereum Address || Enclave Encryption Key) 33 | //and define WRAPPER_PROGRAM_CODE_HASH to equal hash(Pose-Program) such that it equals hash(Enclave-Program) if the enclave 34 | //installed the POSE Program 35 | bytes32 constant WRAPPER_PROGRAM_CODE_HASH = keccak256(abi.encode(0)); //0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563 36 | address public constant ATTESTATION_AUTHORITY = 0x1dF62f291b2E969fB0849d99D9Ce41e2F137006e; 37 | 38 | //Phases a contract can occupy 39 | enum Phase { NONE, CREATION, EXECUTING, CHALLENGE_EXECUTOR, CHALLENGE_WATCHDOG, CRASHED } 40 | 41 | //Events 42 | event NewOperator(address operator); 43 | event CreationInitialized(uint id); 44 | event ContractCreated(uint id, bytes txData); 45 | event ExecutorChallenged(uint id, bytes txData); 46 | event ExecutorResponse(uint id, bytes txData); 47 | event ExecutorKicked(uint id, bytes txData); 48 | event WatchdogChallenged(uint id, bytes txData); 49 | event WatchdogResponse(uint id, bytes txData); 50 | event WatchdogFinalized(uint id, bytes txData); 51 | event ContractCrashed(uint id); 52 | 53 | //@ClientDeveloper: How to use events and the tx-data information 54 | // - Use the operator to listen on all of the events 55 | // - Use a web3j library for this, e.g. web3js 56 | // - When an event for a relevant id is registered do the following: 57 | // - Extract the information required from the txData field 58 | // - This field contains all function parameters (you can e.g. use it to extract the challenge message, ...) 59 | // - Read the other relevant data from the contract (e.g., Who is the current executor). Same informaiton can be received from the TEE as well 60 | // - Always give the txData to the TEE 61 | // - TEE interprets the txData and learns what it should do 62 | // - The txData contains the function that has been called, so the TEE knows how to interpret the txData 63 | // - e.g., if it is a deposit the TEE needs to update the state 64 | // - e.g., if it is a challenge the TEE needs to interpret the challenge message and answer it 65 | // - ... 66 | // - As the TEE can no longer access the on-chain state it needs to simulate the tx off-chain and evolve its off-chain state accordingly 67 | // - e.g., kick inactive watchdogs, ... 68 | // - This way the TEE can ensure that the local state and the on-chain state are always the same 69 | // - You only need to simulate the state that is relevant for the TEE 70 | // - You can for example ignore the timeout, because the TEE clock is not synchronized with the on-chain clock anyway 71 | // - The TEE updates it local incrementalTxHash which always needs to be the same as the on-chain one and need to be included into all signatures. 72 | // - This way the Manager can ensure that the TEE is up-to-date 73 | // - See modifier updateIncrementalTxHash to check how the incrementalTxHash is updated 74 | //- TxData has the following structure: 75 | // - The first 4 bytes are the first 4 bytes of the hash of the method signature 76 | // - These are used to determine the tx-type and thus to determine how to interpret the tx-data 77 | // - In Solidity the method-hash would be calculated with: bytes4(keccak256(bytes(method-signature))); 78 | // - Method signature are name and parameter-types without whitespaces and modifiers or location like "memory" 79 | // - Signature of register: register(address,bytes,bytes) 80 | // - Signature of initCreation: initCreation(address,bytes32,uint256) 81 | // - ... 82 | // - Sometimes types fo have synonyms: e.g. uint is actually uint256 83 | // - Constants need t: uint256[POOL_SIZE] is actually uint256[30] 84 | // - The other bytes are the abi-encoded function parameters 85 | // - In solidity they would be equal to abi.encode(p1,p2,...); 86 | 87 | //Operator information 88 | struct Operator { 89 | bool initialized; 90 | address teeSignatureAddress; 91 | bytes teeEncryptionKey; //If we use elliptic curve cryptography with 256-but curves, the public key is a point on that curve, and hence, 64 bytes of size. 92 | } 93 | 94 | //Contract information 95 | struct Contract { 96 | 97 | //General lifecycle management 98 | Phase phase; //Current phase 99 | bytes32 incrementalTxHash; //Incremental hash of all transactions relevant for this contract 100 | //This is used as a checkpoint that enables a contract to check that the TEE is up-to-date 101 | 102 | //Contract and pool information 103 | address payable poolAddress; // The address to the pool public key 104 | address creationOperator; // The address of the creation operator 105 | address[POOL_SIZE] operators; // The operator pool, a kicked operator is one witha ddress(0) 106 | uint executiveOperator; // The index of the current executive operator within the operator pool 107 | bytes32 codeHash; // The code hash of the application logic 108 | 109 | //Dispute information 110 | Phase fallbackPhase; // A watchdog challenge can be within another challenge. Therefore we need to store the fallback phase after the watchdog challenge 111 | uint8 watchdogsChallenged; // Watchdogs may only be challenged once during an execution challenge. This variable helprs to ensure that 112 | bytes32 execChallengeHash; // The hash of the challenge message of the executor challenge 113 | bytes32 watchdogChallengeHash; // The hash of the challengeHash of the watchdog challenge (we need both as watchdog challenge can be within executor challenge) 114 | uint8[POOL_SIZE] challengedWatchdogs; // Array that stores which watchdogs are challenged 115 | uint deadline; 116 | } 117 | 118 | //Operator mapping 119 | mapping(address => Operator) public operators; 120 | address[] public operatorList; //To enable the client to iterate over all operators, if we wanted to save gas, we could also iterate over the past events 121 | bytes32 public operatorIncrementalHash = 0; //The creaiton-TEE needs to sign the list of operators it receives to ensure that the input is correct 122 | //However, encoding the whole list of operators to check the signed list hash can become really expensive 123 | //Therefore we construct an incremental hash: newHash = hash(oldHash, new address); the initial hash is 0x00...00 124 | //The downside is that the TEE has to calculate this incrementalHash when receiving a list of operators itself 125 | 126 | //Contract mapping 127 | mapping(uint => Contract) public contracts; 128 | 129 | //****************** 130 | //Public functions 131 | 132 | 133 | //****************** 134 | //Registration 135 | 136 | //Registers a Operator and attests TEE, there may only be one TEE per operator 137 | function register(address teeSignatureAddress, bytes memory teeEncryptionKey, bytes memory attestationSignature) public { 138 | 139 | //Check that operator has not registered another TEE 140 | require(operators[msg.sender].initialized == false, "The operator has already registered a TEE!"); 141 | 142 | //Check the signature with the required signature algorithm //@ClientDeveloper: Here you can see what needs to be included into the attestation of a TEE 143 | bytes32 attestationHash = keccak256(abi.encode("Pose-Attest", WRAPPER_PROGRAM_CODE_HASH, teeSignatureAddress, teeEncryptionKey)); //TODO: After the testing we should include the manager-address here as well: keccak256(abi.encode("Furious-Attest", WRAPPER_PROGRAM_CODE_HASH, address(this), teeSignatureAddress, teeEncryptionKey)); 144 | require(verifySignature(attestationHash, attestationSignature, ATTESTATION_AUTHORITY), "Wrong attestation"); 145 | 146 | //Register operator 147 | operatorList.push(msg.sender); 148 | operators[msg.sender] = Operator(true, teeSignatureAddress, teeEncryptionKey); 149 | operatorIncrementalHash = keccak256(abi.encode(operatorIncrementalHash, msg.sender)); 150 | 151 | //Notify clients 152 | emit NewOperator(msg.sender); 153 | } 154 | 155 | //****************** 156 | //Creation 157 | 158 | //We do not challenge the creator. If he does not respond in time, the creation is simply not successful. Challenge would have the same effect. 159 | 160 | //Initializes the creation, we need this to ensure that the creation TEE gets the up-to-date state (e.g. list of operators) from the operator 161 | function initCreation(address creationOperator, bytes32 codeHash, uint freeId) public { 162 | 163 | //Checks 164 | require(contracts[freeId].phase == Phase.NONE, "Contract with this ID does already exist!"); 165 | require(operators[creationOperator].initialized == true, "Creation operator does not exist!"); 166 | 167 | //Creat contract Tuple 168 | address[POOL_SIZE] memory operatorArray; 169 | uint8[POOL_SIZE] memory challenged; 170 | contracts[freeId] = Contract(Phase.CREATION, operatorIncrementalHash, address(0), creationOperator, operatorArray, 0, codeHash, Phase.NONE, 0, 0, 0, challenged, now + TIMEOUT_INTERVAL); 171 | 172 | //Notify clients 173 | emit CreationInitialized(freeId); 174 | } 175 | 176 | //Enables the creation operator to challenge the pool during creation 177 | //Problem: During creation the TEEs do not receive the same message as they do not know the secret pool key 178 | //Solution: Simply interpret message as the concatination of all individual messages 179 | function challengeWatchdogsDuringCreation(uint id, address[POOL_SIZE] memory pool_operators, bytes memory message, uint8[POOL_SIZE] memory challengedOperators) public updateIncrementalTxHash(id, 0) { 180 | 181 | //Checks 182 | require(msg.sender == contracts[id].creationOperator, "Not the right account to challenge the watchdogs"); 183 | require(contracts[id].phase == Phase.CREATION && contracts[id].watchdogsChallenged < 1, "Not the right phase to challenge watchdogs or watchdogs have already been challenged during creation!"); 184 | 185 | //I think we can set this without a signature as it will be overwritten by a successful creation anyways 186 | contracts[id].operators = pool_operators; 187 | 188 | //Call the internal part of the watchdog challenge procedure (shared between watchdog challenges during execution and during creation) 189 | internalWatchdogChallenge(id, message, challengedOperators); 190 | } 191 | 192 | //Finalizes the creation. The TEE ensures that the values (e.g. Operator pool) are correct. We only need to check via the TEE-signature that it has received the correct inputs 193 | function finalizeCreation(uint id, address payable pool_address, address[POOL_SIZE] memory pool_operators, bytes memory signature) public updateIncrementalTxHash(id, 0){ 194 | 195 | //Checks 196 | require(contracts[id].phase == Phase.CREATION, "The contract with this ID is not in the right phase to be created!"); 197 | require(contracts[id].deadline >= now, "The creation deadline has expired!"); 198 | 199 | //Check Signature //@ClientDeveloper: Here you can see what needs to be included into the creation finalization signature 200 | bytes32 signedHash = keccak256(abi.encode("Creation-Attest", id, contracts[id].incrementalTxHash, pool_address, contracts[id].codeHash, pool_operators)); 201 | require(verifySignature(signedHash, signature, operators[contracts[id].creationOperator].teeSignatureAddress) == true, "Wrong signature for creation!"); 202 | 203 | //Update state 204 | contracts[id].poolAddress = pool_address; 205 | contracts[id].phase = Phase.EXECUTING; 206 | contracts[id].operators = pool_operators; 207 | 208 | //Notify clients 209 | emit ContractCreated(id, msg.data); 210 | } 211 | 212 | //****************** 213 | //Handling assets 214 | 215 | //Enables a party to deposit funds to a pool address, as we increment the checkpoint number this may only be done during phase executing 216 | function depositToContract(uint id) public payable updateIncrementalTxHash(id, msg.value){ 217 | 218 | //You can only deposit to an executing contract 219 | require(contracts[id].phase == Phase.EXECUTING, "Contract with this ID is not in phase EXECUTING!"); 220 | 221 | //Forward the money to the pool address 222 | contracts[id].poolAddress.transfer(msg.value); 223 | } 224 | 225 | //Enables a party to withdraw funds. The tx needs to be issued by the poolAddress (the pool-pk) and is broadcasted to the network by the client. 226 | //The tx contains the block number and block hash, when it was issued. 227 | //This way we ensure that the pool has been up-to-date with the blockchain when it has issued this payout. 228 | function withdraw(uint id, uint blocknumber, address payable receiver) public payable updateIncrementalTxHash(id, msg.value) { 229 | 230 | //Checks 231 | require(msg.sender == contracts[id].poolAddress, "The sender of the payout tx is not the pool with the specified ID!"); 232 | 233 | //Forwards the withdraw value to the receiver of the payout 234 | receiver.transfer(msg.value); 235 | } 236 | 237 | //****************** 238 | //Execution Challenges - Can either be atomic (just challenge the executor) or combined with a challenge to the watchdogs by the executor. Needs to be complete before completing the challenge to the executor 239 | 240 | //Challenge the executor to provide the current state or execute a move (what exactly is encoded into the message) 241 | function challengeExecutor(uint id, bytes memory message) public updateIncrementalTxHash(id, 0) { 242 | 243 | //Checks 244 | require(contracts[id].phase == Phase.EXECUTING, "Can only challenge executor of contract in phase executing!"); 245 | 246 | //Update state 247 | contracts[id].phase = Phase.CHALLENGE_EXECUTOR; 248 | contracts[id].deadline = now + TIMEOUT_INTERVAL; 249 | contracts[id].watchdogsChallenged = 0; 250 | contracts[id].execChallengeHash = keccak256(message); 251 | 252 | //Notify clients 253 | emit ExecutorChallenged(id, msg.data); 254 | 255 | } 256 | 257 | //Response of the executive operator 258 | function executorResponse(uint id, bytes memory response, bytes memory signature) public updateIncrementalTxHash(id, 0) { 259 | 260 | //Checks 261 | require(contracts[id].phase == Phase.CHALLENGE_EXECUTOR, "Challenge can only be answered if there is an unresolved challenge!"); 262 | require(contracts[id].deadline >= now, "The response deadline has expired!"); 263 | 264 | //Check Signature //@ClientDeveloper: Here you can see what needs to be included into the executor response signature 265 | bytes32 signedHash = keccak256(abi.encode("Challenge-Response", id, contracts[id].incrementalTxHash, response)); //Checkpoint-hash includes contracts[id].challengeHash 266 | require(verifySignature(signedHash, signature, operators[contracts[id].operators[contracts[id].executiveOperator]].teeSignatureAddress) == true, "Wrong signature for executor response!"); 267 | 268 | //Update state 269 | contracts[id].phase = Phase.EXECUTING; 270 | 271 | //Notify clients 272 | emit ExecutorResponse(id, msg.data); 273 | } 274 | 275 | //Enables any party to kick the executive operator if it does not respond to a challenge in time 276 | function executorTimeout(uint id) public updateIncrementalTxHash(id, 0) { 277 | 278 | //Checks 279 | require(contracts[id].phase == Phase.CHALLENGE_EXECUTOR, "Challenge can only be timed out if there is an unresolved challenge!"); 280 | require(contracts[id].deadline < now, "The response deadline has not expired!"); 281 | 282 | //Drop the executor = Set his address to address(0) 283 | address _executor = contracts[id].operators[contracts[id].executiveOperator]; 284 | contracts[id].operators[contracts[id].executiveOperator] = address(0); 285 | 286 | //Check if there is another active operator 287 | for(uint i = contracts[id].executiveOperator + 1; i < POOL_SIZE; i++) { 288 | if(contracts[id].operators[i] != address(0)){ 289 | 290 | //Update state 291 | contracts[id].executiveOperator = i; 292 | contracts[id].phase = Phase.EXECUTING; 293 | 294 | //Notify clients 295 | emit ExecutorKicked(id, msg.data); 296 | 297 | return; 298 | } 299 | } 300 | 301 | //Otherwise: Mark the contract as crashed 302 | contracts[id].phase = Phase.CRASHED; 303 | 304 | //Notify clients 305 | emit ContractCrashed(id); 306 | 307 | } 308 | 309 | //******************** 310 | // Challenge watchdogs 311 | 312 | //Enables the executors to challenge a list of watchdogs with a given message. 313 | //If their are individual messages for each watchdog, simply concatenate them to one 314 | function challengeWatchdog(uint id, bytes memory message, uint8[POOL_SIZE] memory challengedOperators) public updateIncrementalTxHash(id, 0){ 315 | 316 | //Checks 317 | require(msg.sender == contracts[id].operators[contracts[id].executiveOperator], "Not the right account to challenge the watchdogs"); 318 | require(contracts[id].phase == Phase.EXECUTING || (contracts[id].phase == Phase.CHALLENGE_EXECUTOR && contracts[id].watchdogsChallenged < 2), "Not the right phase to challenge watchdogs or watchdogs have already been challenged within the same executor challenge!"); //Correct phase 319 | 320 | //Internal function to prevent duplicate code 321 | internalWatchdogChallenge(id, message, challengedOperators); 322 | 323 | } 324 | 325 | //Answers a watchdog challenge. The operator gives the challenge to the TEE which generates a response. The response can also be: <> 326 | //Id 1 is the index of the party in the operator-list, Id 2 is the index of the party in the challenged-list 327 | function watchdogResponse(uint id, uint index, bytes memory response, bytes memory signature) public updateIncrementalTxHash(id, 0) { 328 | 329 | //Checks 330 | require(contracts[id].phase == Phase.CHALLENGE_WATCHDOG, "Not the right phase to provude a watchdog response"); 331 | require(contracts[id].deadline >= now, "The response deadline has expired!"); 332 | 333 | //Verify signatures //@ClientDeveloper: Here you can see what needs to be included into a watchdog response signature 334 | bytes32 signedHash = keccak256(abi.encode("Watchdog-challenge-Response", id, contracts[id].incrementalTxHash, response)); //Checkpoint-hash includes contracts[id].challengeHash 335 | require(verifySignature(signedHash, signature, operators[contracts[id].operators[index]].teeSignatureAddress) == true, "Wrong signature for executor response!"); 336 | 337 | //Mark the party as not-challenged in the challenge list 338 | contracts[id].challengedWatchdogs[index] = 0; 339 | 340 | //Notify clients 341 | emit WatchdogResponse(id, msg.data); 342 | } 343 | 344 | //Finalizes a watchdog challenge and kicks all watchdogs that have not responded 345 | function watchdogFinalization(uint id) public updateIncrementalTxHash(id, 0){ 346 | 347 | //Checks 348 | require(contracts[id].phase == Phase.CHALLENGE_WATCHDOG, "Not the right phase to provude a watchdog response"); 349 | require(contracts[id].deadline < now, "The response deadline has not expired!"); 350 | 351 | //Drop the watchdogs, that have not responded (The executor is ignored here) 352 | for(uint i = 0; i < POOL_SIZE; i++){ 353 | if(contracts[id].challengedWatchdogs[i] == 1){ 354 | contracts[id].operators[i] = address(0); //A kicked watchdog is simply one with address(0) 355 | } 356 | } 357 | 358 | //Return to the correct phase 359 | contracts[id].phase = contracts[id].fallbackPhase; 360 | contracts[id].watchdogsChallenged = contracts[id].watchdogsChallenged + 1; 361 | 362 | //Increase the timeout if there is an outer creation or executor challenge 363 | if (contracts[id].phase == Phase.CHALLENGE_EXECUTOR || contracts[id].phase == Phase.CREATION) { 364 | contracts[id].deadline = now + TIMEOUT_INTERVAL; 365 | } 366 | 367 | //Notify clients 368 | emit WatchdogFinalized(id, msg.data); 369 | } 370 | 371 | //****************** 372 | //Modifiers 373 | 374 | //This code is executed after each public function (besides initCreation) to include the new transaction into the contract-tx-history-hash 375 | modifier updateIncrementalTxHash(uint id, uint value) { 376 | _; 377 | //@ClientDeveloper: Check here how the incremental hash is created 378 | contracts[id].incrementalTxHash = keccak256(abi.encode(contracts[id].incrementalTxHash, msg.data, msg.sender, value)); 379 | } 380 | 381 | //****************** 382 | //Private functions (Mainly prevent duplicate code) 383 | 384 | //Duplicate code used by both watchdog challenges which dupdates the state and emits the event 385 | function internalWatchdogChallenge(uint id, bytes memory message, uint8[POOL_SIZE] memory challengedOperators) private { 386 | 387 | //Update state 388 | contracts[id].fallbackPhase = contracts[id].phase; 389 | contracts[id].phase = Phase.CHALLENGE_WATCHDOG; 390 | contracts[id].deadline = now + TIMEOUT_INTERVAL; 391 | contracts[id].watchdogChallengeHash = keccak256(message); 392 | contracts[id].challengedWatchdogs = challengedOperators; 393 | 394 | //Notify clients 395 | emit WatchdogChallenged(id, msg.data); 396 | } 397 | 398 | //****************** 399 | //Public helper functions 400 | 401 | //Verifies ECDSA signatures of Ethereum addresses 402 | //function verifySignature(bytes32 signedHash, bytes memory signature, address signer) public pure returns (bool) { 403 | // 404 | // //Parse the signature 405 | // (uint8 v, bytes32 r, bytes32 s) = abi.decode(signature, (uint8, bytes32, bytes32)); 406 | // 407 | // //Verify the signature 408 | // return (ecrecover(signedHash, v, r, s) == signer); 409 | //} 410 | 411 | //Verifies ECDSA signatures of prefixed and hashed encoded data: Hash the data, prefix it, hash it again, verify it against signature 412 | //TODO: If our client does not prefix we can use the funciton above 413 | function verifySignature(bytes32 _hashedDataInput, bytes memory _signature, address _party) public pure returns (bool){ 414 | 415 | //Convert signatures 416 | (uint8 v, bytes32 r, bytes32 s) = abi.decode(_signature, (uint8, bytes32, bytes32)); 417 | 418 | //Calc prefixed hash 419 | bytes32 _hash = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", _hashedDataInput)); 420 | 421 | return _party == ecrecover(_hash, v,r,s); 422 | 423 | } 424 | } 425 | -------------------------------------------------------------------------------- /SmartContract/contracts/PoseManager_RSA.sol: -------------------------------------------------------------------------------- 1 | //TODO: Add license 2 | 3 | pragma solidity ^0.6.1; 4 | pragma experimental "ABIEncoderV2"; 5 | import "./RSALibrary.sol"; 6 | 7 | //The RSA-based version (attestation is performed via RSA signatures) 8 | contract PoseManager_RSA is SolRsaVerify { 9 | 10 | //Constants 11 | uint public constant POOL_SIZE = 3; 12 | uint public constant TIMEOUT_INTERVAL = 15; //The maximal dispute time is 3 * TIMEOUT_INTERVAL 13 | //because the executive operator can get "extra time" by challenging the watchdogs 14 | 15 | //For attestation 16 | //@ClientDeveloper: The WRAPPER_PROGRAM_CODE_HASH is currently a dummy value. Once, the client attestation allows 17 | //for configurable attestation implement it to sign hash("Pose-Attest" || hash(Enclave-Program) || Enclave Ethereum Address || Enclave Encryption Key) 18 | //and define WRAPPER_PROGRAM_CODE_HASH to equal hash(Pose-Program) such that it equals hash(Enclave-Program) if the enclave 19 | //installed the POSE Program 20 | bytes32 constant WRAPPER_PROGRAM_CODE_HASH = 0x0a28e9ffef0073f9a6a674cf57ee77307f38f0f1bebb087888d9011ed0eeefdf; 21 | bytes constant ATTESTATION_AUTHORITY_E = "\x03"; 22 | bytes constant ATTESTATION_AUTHORITY_N = "\xbf\x0c\x3a\x0d\xf9\x55\x1e\x2c\xce\x27\x0f\xf8\xaf\x13\xe6\xfc\xc8\x79\xb4\xfb\x29\x10\xfa\x40\x28\x3c\x8e\x07\x5f\x1b\x3e\x61\xd8\xed\xc9\x9e\xee\xd9\x71\x31\xb2\xcb\xba\x8c\x4a\x77\x68\x2f\xe1\xb1\xd1\x2b\xe7\x75\xeb\x7c\x8d\x59\xf5\x9b\x69\x60\x6d\x7d\xf1\x8e\xd9\x3f\x63\x58\x75\x53\x0d\x7d\xfc\x18\x20\x10\xa3\x1b\xb4\x47\xdd\xb8\x51\x98\x52\xde\x08\x91\x9a\x51\x67\x5a\x54\x8b\xbe\x5d\xd4\xea\x0b\x97\x13\x8e\xfb\xf7\x4e\x5e\xd1\x33\xad\x4d\xb5\x12\xc1\x52\x91\x0d\xf0\xf4\x09\x0c\xeb\x05\xa9\x80\x09\xc9\xe6\xc3\xd2\x7b\x7d\x2a\x39\xdd\x26\x5d\xfe\xb1\xae\x76\x4e\xcf\x71\x26\x04\x8f\x5d\x26\x3b\x2c\x17\x73\x4b\x75\x0d\x0f\xc1\x58\xfd\x2d\x84\x29\xd2\x0d\x0c\xf9\x6b\x79\xdf\x48\x13\x17\x42\x70\x17\x85\x4f\xad\x52\xff\xae\xfb\x78\x47\x57\x79\x6f\xda\x0f\x21\x8a\xaf\x9f\x4f\x44\xf0\xd3\x16\xec\x38\x24\xfe\x88\x7c\x3a\x85\x56\xae\x18\x49\x5d\x17\x54\x8b\x63\xd7\x22\x4e\x7a\x37\xa2\x2b\xb5\xbb\xe0\x9c\x36\xcd\xbc\x87\x76\x19\x09\xa4\x6e\x64\x62\x15\xcb\xa0\xb7\xc3\x6e\x79\x86\x71\xd1\xb0\xc5\xc9\x8a\x90\x04\x59"; 23 | 24 | //Phases a contract can occupy 25 | enum Phase { NONE, CREATION, EXECUTING, CHALLENGE_EXECUTOR, CHALLENGE_WATCHDOG, CRASHED } 26 | 27 | //Events 28 | event NewOperator(address operator); 29 | event CreationInitialized(uint id); 30 | event ContractCreated(uint id, bytes txData); 31 | event ExecutorChallenged(uint id, bytes txData); 32 | event ExecutorResponse(uint id, bytes txData); 33 | event ExecutorKicked(uint id, bytes txData); 34 | event WatchdogChallenged(uint id, bytes txData); 35 | event WatchdogResponse(uint id, bytes txData); 36 | event WatchdogFinalized(uint id, bytes txData); 37 | event ContractCrashed(uint id); 38 | 39 | //@ClientDeveloper: How to use events and the tx-data information 40 | // - Use the operator to listen on all of the events 41 | // - Use a web3j library for this, e.g. web3js 42 | // - When an event for a relevant id is registered do the following: 43 | // - Extract the information required from the txData field 44 | // - This field contains all function parameters (you can e.g. use it to extract the challenge message, ...) 45 | // - Read the other relevant data from the contract (e.g., Who is the current executor). Same informaiton can be received from the TEE as well 46 | // - Always give the txData to the TEE 47 | // - TEE interprets the txData and learns what it should do 48 | // - The txData contains the function that has been called, so the TEE knows how to interpret the txData 49 | // - e.g., if it is a deposit the TEE needs to update the state 50 | // - e.g., if it is a challenge the TEE needs to interpret the challenge message and answer it 51 | // - ... 52 | // - As the TEE can no longer access the on-chain state it needs to simulate the tx off-chain and evolve its off-chain state accordingly 53 | // - e.g., kick inactive watchdogs, ... 54 | // - This way the TEE can ensure that the local state and the on-chain state are always the same 55 | // - You only need to simulate the state that is relevant for the TEE 56 | // - You can for example ignore the timeout, because the TEE clock is not synchronized with the on-chain clock anyway 57 | // - The TEE updates it local incrementalTxHash which always needs to be the same as the on-chain one and need to be included into all signatures. 58 | // - This way the Manager can ensure that the TEE is up-to-date 59 | // - See modifier updateIncrementalTxHash to check how the incrementalTxHash is updated 60 | //- TxData has the following structure: 61 | // - The first 4 bytes are the first 4 bytes of the hash of the method signature 62 | // - These are used to determine the tx-type and thus to determine how to interpret the tx-data 63 | // - In Solidity the method-hash would be calculated with: bytes4(keccak256(bytes(method-signature))); 64 | // - Method signature are name and parameter-types without whitespaces and modifiers or location like "memory" 65 | // - Signature of register: register(address,bytes,bytes) 66 | // - Signature of initCreation: initCreation(address,bytes32,uint256) 67 | // - ... 68 | // - Sometimes types fo have synonyms: e.g. uint is actually uint256 69 | // - Constants need t: uint256[POOL_SIZE] is actually uint256[30] 70 | // - The other bytes are the abi-encoded function parameters 71 | // - In solidity they would be equal to abi.encode(p1,p2,...); 72 | 73 | //Operator information 74 | struct Operator { 75 | bool initialized; 76 | address teeSignatureAddress; 77 | bytes teeEncryptionKey; //If we use elliptic curve cryptography with 256-but curves, the public key is a point on that curve, and hence, 64 bytes of size. 78 | } 79 | 80 | //Contract information 81 | struct Contract { 82 | 83 | //General lifecycle management 84 | Phase phase; //Current phase 85 | bytes32 incrementalTxHash; //Incremental hash of all transactions relevant for this contract 86 | //This is used as a checkpoint that enables a contract to check that the TEE is up-to-date 87 | 88 | //Contract and pool information 89 | address payable poolAddress; // The address to the pool public key 90 | address creationOperator; // The address of the creation operator 91 | address[POOL_SIZE] operators; // The operator pool, a kicked operator is one witha ddress(0) 92 | uint executiveOperator; // The index of the current executive operator within the operator pool 93 | bytes32 codeHash; // The code hash of the application logic 94 | 95 | //Dispute information 96 | Phase fallbackPhase; // A watchdog challenge can be within another challenge. Therefore we need to store the fallback phase after the watchdog challenge 97 | uint8 watchdogsChallenged; // Watchdogs may only be challenged once during an execution challenge. This variable helprs to ensure that 98 | bytes32 execChallengeHash; // The hash of the challenge message of the executor challenge 99 | bytes32 watchdogChallengeHash; // The hash of the challengeHash of the watchdog challenge (we need both as watchdog challenge can be within executor challenge) 100 | uint8[POOL_SIZE] challengedWatchdogs; // Array that stores which watchdogs are challenged 101 | uint deadline; 102 | } 103 | 104 | //Operator mapping 105 | mapping(address => Operator) public operators; 106 | address[] public operatorList; //To enable the client to iterate over all operators, if we wanted to save gas, we could also iterate over the past events 107 | bytes32 public operatorIncrementalHash = 0; //The creaiton-TEE needs to sign the list of operators it receives to ensure that the input is correct 108 | //However, encoding the whole list of operators to check the signed list hash can become really expensive 109 | //Therefore we construct an incremental hash: newHash = hash(oldHash, new address); the initial hash is 0x00...00 110 | //The downside is that the TEE has to calculate this incrementalHash when receiving a list of operators itself 111 | 112 | //Contract mapping 113 | mapping(uint => Contract) public contracts; 114 | 115 | //****************** 116 | //Public functions 117 | 118 | 119 | //****************** 120 | //Registration 121 | 122 | //Registers a Operator and attests TEE, there may only be one TEE per operator 123 | function register(address teeSignatureAddress, bytes memory teeEncryptionKey, bytes memory attestationSignature) public { 124 | 125 | //Check that operator has not registered another TEE 126 | require(operators[msg.sender].initialized == false, "The operator has already registered a TEE!"); 127 | 128 | //Check the signature with the required signature algorithm //@ClientDeveloper: Here you can see what needs to be included into the attestation of a TEE 129 | require(pkcs1Sha256VerifyRaw(abi.encodePacked("Pose-Attest", WRAPPER_PROGRAM_CODE_HASH, teeSignatureAddress, teeEncryptionKey), attestationSignature, ATTESTATION_AUTHORITY_E, ATTESTATION_AUTHORITY_N) == 0, "Wrong attestation"); 130 | 131 | //Register operator 132 | operatorList.push(msg.sender); 133 | operators[msg.sender] = Operator(true, teeSignatureAddress, teeEncryptionKey); 134 | operatorIncrementalHash = keccak256(abi.encode(operatorIncrementalHash, msg.sender)); 135 | 136 | //Notify clients 137 | emit NewOperator(msg.sender); 138 | } 139 | 140 | //****************** 141 | //Creation 142 | 143 | //We do not challenge the creator. If he does not respond in time, the creation is simply not successful. Challenge would have the same effect. 144 | 145 | //Initializes the creation, we need this to ensure that the creation TEE gets the up-to-date state (e.g. list of operators) from the operator 146 | function initCreation(address creationOperator, bytes32 codeHash, uint freeId) public { 147 | 148 | //Checks 149 | require(contracts[freeId].phase == Phase.NONE, "Contract with this ID does already exist!"); 150 | require(operators[creationOperator].initialized == true, "Creation operator does not exist!"); 151 | 152 | //Creat contract Tuple 153 | address[POOL_SIZE] memory operatorArray; 154 | uint8[POOL_SIZE] memory challenged; 155 | contracts[freeId] = Contract(Phase.CREATION, operatorIncrementalHash, address(0), creationOperator, operatorArray, 0, codeHash, Phase.NONE, 0, 0, 0, challenged, now + TIMEOUT_INTERVAL); 156 | 157 | //Notify clients 158 | emit CreationInitialized(freeId); 159 | } 160 | 161 | //Enables the creation operator to challenge the pool during creation 162 | //Problem: During creation the TEEs do not receive the same message as they do not know the secret pool key 163 | //Solution: Simply interpret message as the concatination of all individual messages 164 | function challengeWatchdogsDuringCreation(uint id, address[POOL_SIZE] memory pool_operators, bytes memory message, uint8[POOL_SIZE] memory challengedOperators) public updateIncrementalTxHash(id, 0) { 165 | 166 | //Checks 167 | require(msg.sender == contracts[id].creationOperator, "Not the right account to challenge the watchdogs"); 168 | require(contracts[id].phase == Phase.CREATION && contracts[id].watchdogsChallenged < 1, "Not the right phase to challenge watchdogs or watchdogs have already been challenged during creation!"); 169 | 170 | //I think we can set this without a signature as it will be overwritten by a successful creation anyways 171 | contracts[id].operators = pool_operators; 172 | 173 | //Call the internal part of the watchdog challenge procedure (shared between watchdog challenges during execution and during creation) 174 | internalWatchdogChallenge(id, message, challengedOperators); 175 | } 176 | 177 | //Finalizes the creation. The TEE ensures that the values (e.g. Operator pool) are correct. We only need to check via the TEE-signature that it has received the correct inputs 178 | function finalizeCreation(uint id, address payable pool_address, address[POOL_SIZE] memory pool_operators, bytes memory signature) public updateIncrementalTxHash(id, 0){ 179 | 180 | //Checks 181 | require(contracts[id].phase == Phase.CREATION, "The contract with this ID is not in the right phase to be created!"); 182 | require(contracts[id].deadline >= now, "The creation deadline has expired!"); 183 | 184 | //Check Signature //@ClientDeveloper: Here you can see what needs to be included into the creation finalization signature 185 | bytes32 signedHash = keccak256(abi.encode("Creation-Attest", id, contracts[id].incrementalTxHash, pool_address, contracts[id].codeHash, pool_operators)); 186 | require(verifySignature(signedHash, signature, operators[contracts[id].creationOperator].teeSignatureAddress) == true, "Wrong signature for creation!"); 187 | 188 | //Update state 189 | contracts[id].poolAddress = pool_address; 190 | contracts[id].phase = Phase.EXECUTING; 191 | contracts[id].operators = pool_operators; 192 | 193 | //Notify clients 194 | emit ContractCreated(id, msg.data); 195 | } 196 | 197 | //****************** 198 | //Handling assets 199 | 200 | //Enables a party to deposit funds to a pool address, as we increment the checkpoint number this may only be done during phase executing 201 | function depositToContract(uint id) public payable updateIncrementalTxHash(id, msg.value){ 202 | 203 | //You can only deposit to an executing contract 204 | require(contracts[id].phase == Phase.EXECUTING, "Contract with this ID is not in phase EXECUTING!"); 205 | 206 | //Forward the money to the pool address 207 | contracts[id].poolAddress.transfer(msg.value); 208 | } 209 | 210 | //Enables a party to withdraw funds. The tx needs to be issued by the poolAddress (the pool-pk) and is broadcasted to the network by the client. 211 | //The tx contains the block number and block hash, when it was issued. 212 | //This way we ensure that the pool has been up-to-date with the blockchain when it has issued this payout. 213 | function withdraw(uint id, uint blocknumber, address payable receiver) public payable updateIncrementalTxHash(id, msg.value) { 214 | 215 | //Checks 216 | require(msg.sender == contracts[id].poolAddress, "The sender of the payout tx is not the pool with the specified ID!"); 217 | 218 | //Forwards the withdraw value to the receiver of the payout 219 | receiver.transfer(msg.value); 220 | } 221 | 222 | //****************** 223 | //Execution Challenges - Can either be atomic (just challenge the executor) or combined with a challenge to the watchdogs by the executor. Needs to be complete before completing the challenge to the executor 224 | 225 | //Challenge the executor to provide the current state or execute a move (what exactly is encoded into the message) 226 | function challengeExecutor(uint id, bytes memory message) public updateIncrementalTxHash(id, 0) { 227 | 228 | //Checks 229 | require(contracts[id].phase == Phase.EXECUTING, "Can only challenge executor of contract in phase executing!"); 230 | 231 | //Update state 232 | contracts[id].phase = Phase.CHALLENGE_EXECUTOR; 233 | contracts[id].deadline = now + TIMEOUT_INTERVAL; 234 | contracts[id].watchdogsChallenged = 0; 235 | contracts[id].execChallengeHash = keccak256(message); 236 | 237 | //Notify clients 238 | emit ExecutorChallenged(id, msg.data); 239 | 240 | } 241 | 242 | //Response of the executive operator 243 | function executorResponse(uint id, bytes memory response, bytes memory signature) public updateIncrementalTxHash(id, 0) { 244 | 245 | //Checks 246 | require(contracts[id].phase == Phase.CHALLENGE_EXECUTOR, "Challenge can only be answered if there is an unresolved challenge!"); 247 | require(contracts[id].deadline >= now, "The response deadline has expired!"); 248 | 249 | //Check Signature //@ClientDeveloper: Here you can see what needs to be included into the executor response signature 250 | bytes32 signedHash = keccak256(abi.encode("Challenge-Response", id, contracts[id].incrementalTxHash, response)); //Checkpoint-hash includes contracts[id].challengeHash 251 | require(verifySignature(signedHash, signature, operators[contracts[id].operators[contracts[id].executiveOperator]].teeSignatureAddress) == true, "Wrong signature for executor response!"); 252 | 253 | //Update state 254 | contracts[id].phase = Phase.EXECUTING; 255 | 256 | //Notify clients 257 | emit ExecutorResponse(id, msg.data); 258 | } 259 | 260 | //Enables any party to kick the executive operator if it does not respond to a challenge in time 261 | function executorTimeout(uint id) public updateIncrementalTxHash(id, 0) { 262 | 263 | //Checks 264 | require(contracts[id].phase == Phase.CHALLENGE_EXECUTOR, "Challenge can only be timed out if there is an unresolved challenge!"); 265 | require(contracts[id].deadline < now, "The response deadline has not expired!"); 266 | 267 | //Drop the executor = Set his address to address(0) 268 | address _executor = contracts[id].operators[contracts[id].executiveOperator]; 269 | contracts[id].operators[contracts[id].executiveOperator] = address(0); 270 | 271 | //Check if there is another active operator 272 | for(uint i = contracts[id].executiveOperator + 1; i < POOL_SIZE; i++) { 273 | if(contracts[id].operators[i] != address(0)){ 274 | 275 | //Update state 276 | contracts[id].executiveOperator = i; 277 | contracts[id].phase = Phase.EXECUTING; 278 | 279 | //Notify clients 280 | emit ExecutorKicked(id, msg.data); 281 | 282 | return; 283 | } 284 | } 285 | 286 | //Otherwise: Mark the contract as crashed 287 | contracts[id].phase = Phase.CRASHED; 288 | 289 | //Notify clients 290 | emit ContractCrashed(id); 291 | 292 | } 293 | 294 | //******************** 295 | // Challenge watchdogs 296 | 297 | //Enables the executors to challenge a list of watchdogs with a given message. 298 | //If their are individual messages for each watchdog, simply concatenate them to one 299 | function challengeWatchdog(uint id, bytes memory message, uint8[POOL_SIZE] memory challengedOperators) public updateIncrementalTxHash(id, 0){ 300 | 301 | //Checks 302 | require(msg.sender == contracts[id].operators[contracts[id].executiveOperator], "Not the right account to challenge the watchdogs"); 303 | require(contracts[id].phase == Phase.EXECUTING || (contracts[id].phase == Phase.CHALLENGE_EXECUTOR && contracts[id].watchdogsChallenged < 2), "Not the right phase to challenge watchdogs or watchdogs have already been challenged within the same executor challenge!"); //Correct phase 304 | 305 | //Internal function to prevent duplicate code 306 | internalWatchdogChallenge(id, message, challengedOperators); 307 | 308 | } 309 | 310 | //Answers a watchdog challenge. The operator gives the challenge to the TEE which generates a response. The response can also be: <> 311 | //Id 1 is the index of the party in the operator-list, Id 2 is the index of the party in the challenged-list 312 | function watchdogResponse(uint id, uint index, bytes memory response, bytes memory signature) public updateIncrementalTxHash(id, 0) { 313 | 314 | //Checks 315 | require(contracts[id].phase == Phase.CHALLENGE_WATCHDOG, "Not the right phase to provude a watchdog response"); 316 | require(contracts[id].deadline >= now, "The response deadline has expired!"); 317 | 318 | //Verify signatures //@ClientDeveloper: Here you can see what needs to be included into a watchdog response signature 319 | bytes32 signedHash = keccak256(abi.encode("Watchdog-challenge-Response", id, contracts[id].incrementalTxHash, response)); //Checkpoint-hash includes contracts[id].challengeHash 320 | require(verifySignature(signedHash, signature, operators[contracts[id].operators[index]].teeSignatureAddress) == true, "Wrong signature for executor response!"); 321 | 322 | //Mark the party as not-challenged in the challenge list 323 | contracts[id].challengedWatchdogs[index] = 0; 324 | 325 | //Notify clients 326 | emit WatchdogResponse(id, msg.data); 327 | } 328 | 329 | //Finalizes a watchdog challenge and kicks all watchdogs that have not responded 330 | function watchdogFinalization(uint id) public updateIncrementalTxHash(id, 0){ 331 | 332 | //Checks 333 | require(contracts[id].phase == Phase.CHALLENGE_WATCHDOG, "Not the right phase to provude a watchdog response"); 334 | require(contracts[id].deadline < now, "The response deadline has not expired!"); 335 | 336 | //Drop the watchdogs, that have not responded (The executor is ignored here) 337 | for(uint i = 0; i < POOL_SIZE; i++){ 338 | if(contracts[id].challengedWatchdogs[i] == 1){ 339 | contracts[id].operators[i] = address(0); //A kicked watchdog is simply one with address(0) 340 | } 341 | } 342 | 343 | //Return to the correct phase 344 | contracts[id].phase = contracts[id].fallbackPhase; 345 | contracts[id].watchdogsChallenged = contracts[id].watchdogsChallenged + 1; 346 | 347 | //Increase the timeout if there is an outer creation or executor challenge 348 | if (contracts[id].phase == Phase.CHALLENGE_EXECUTOR || contracts[id].phase == Phase.CREATION) { 349 | contracts[id].deadline = now + TIMEOUT_INTERVAL; 350 | } 351 | 352 | //Notify clients 353 | emit WatchdogFinalized(id, msg.data); 354 | } 355 | 356 | //****************** 357 | //Modifiers 358 | 359 | //This code is executed after each public function (besides initCreation) to include the new transaction into the contract-tx-history-hash 360 | modifier updateIncrementalTxHash(uint id, uint value) { 361 | _; 362 | //@ClientDeveloper: Check here how the incremental hash is created 363 | contracts[id].incrementalTxHash = keccak256(abi.encode(contracts[id].incrementalTxHash, msg.data, msg.sender, value)); 364 | } 365 | 366 | //****************** 367 | //Private functions (Mainly prevent duplicate code) 368 | 369 | //Duplicate code used by both watchdog challenges which dupdates the state and emits the event 370 | function internalWatchdogChallenge(uint id, bytes memory message, uint8[POOL_SIZE] memory challengedOperators) private { 371 | 372 | //Update state 373 | contracts[id].fallbackPhase = contracts[id].phase; 374 | contracts[id].phase = Phase.CHALLENGE_WATCHDOG; 375 | contracts[id].deadline = now + TIMEOUT_INTERVAL; 376 | contracts[id].watchdogChallengeHash = keccak256(message); 377 | contracts[id].challengedWatchdogs = challengedOperators; 378 | 379 | //Notify clients 380 | emit WatchdogChallenged(id, msg.data); 381 | } 382 | 383 | //****************** 384 | //Public helper functions 385 | 386 | //Verifies ECDSA signatures of Ethereum addresses 387 | //function verifySignature(bytes32 signedHash, bytes memory signature, address signer) public pure returns (bool) { 388 | // 389 | // //Parse the signature 390 | // (uint8 v, bytes32 r, bytes32 s) = abi.decode(signature, (uint8, bytes32, bytes32)); 391 | // 392 | // //Verify the signature 393 | // return (ecrecover(signedHash, v, r, s) == signer); 394 | //} 395 | 396 | //Verifies ECDSA signatures of prefixed and hashed encoded data: Hash the data, prefix it, hash it again, verify it against signature 397 | //TODO: If our client does not prefix we can use the funciton above 398 | function verifySignature(bytes32 _hashedDataInput, bytes memory _signature, address _party) public pure returns (bool){ 399 | 400 | //Convert signatures 401 | (uint8 v, bytes32 r, bytes32 s) = abi.decode(_signature, (uint8, bytes32, bytes32)); 402 | 403 | //Calc prefixed hash 404 | bytes32 _hash = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", _hashedDataInput)); 405 | 406 | return _party == ecrecover(_hash, v,r,s); 407 | 408 | } 409 | } 410 | -------------------------------------------------------------------------------- /SmartContract/contracts/RSALibrary.sol: -------------------------------------------------------------------------------- 1 | - Copy the contents from [this contract](https://github.com/adria0/SolRsaVerify/blob/5746d395d782ebb7f1bf599c510c4942c9f18e25/contracts/SolRsaVerify.sol) to contracts/RSALibrary.sol 2 | - Replace `library SolRsaVerify {` (Line 25) with `contract SolRsaVerify {` 3 | -------------------------------------------------------------------------------- /SmartContract/measurements/interpretRSAResults.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | 3 | var measurements = JSON.parse(fs.readFileSync('./RSARegistration.json')); 4 | 5 | let registrationSum = 0; 6 | let registrationCount = 0; 7 | let deploymentSum = 0; 8 | let deplymentCount = 0; 9 | let differentValues = {}; 10 | 11 | let add = function(value){ 12 | if(differentValues["" + value]){ 13 | differentValues["" + value]++; 14 | } else { 15 | differentValues["" + value] = 1; 16 | } 17 | } 18 | 19 | for(let i in measurements){ 20 | 21 | if(measurements[i].function === "register"){ 22 | registrationCount++; 23 | registrationSum += measurements[i].gas; 24 | add(measurements[i].gas); 25 | } else if(measurements[i].function === "deploy"){ 26 | deplymentCount++; 27 | deploymentSum += measurements[i].gas; 28 | add(measurements[i].gas); 29 | } else { 30 | console.log("Error: function name does not match register or deployment") 31 | } 32 | } 33 | 34 | // console.log(registrationCount); 35 | // console.log(registrationSum); 36 | // console.log(deplymentCount); 37 | // console.log(deploymentSum); 38 | // console.log(differentValues); 39 | 40 | console.log("Registration: " + (registrationSum / registrationCount)); 41 | console.log("Deployment: " + (deploymentSum / deplymentCount)); 42 | -------------------------------------------------------------------------------- /SmartContract/migrations/1_initial_migration.js: -------------------------------------------------------------------------------- 1 | const Migrations = artifacts.require("Migrations"); 2 | const PoseManager = artifacts.require("PoseManager_ECDSA"); 3 | 4 | module.exports = function (deployer) { 5 | deployer.deploy(Migrations); 6 | deployer.deploy(PoseManager); 7 | }; 8 | -------------------------------------------------------------------------------- /SmartContract/migrations/2_updateManager.js: -------------------------------------------------------------------------------- 1 | const PoseManager = artifacts.require("PoseManager_ECDSA"); 2 | 3 | module.exports = function (deployer) { 4 | deployer.deploy(PoseManager); 5 | }; 6 | -------------------------------------------------------------------------------- /SmartContract/test/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AppliedCryptoGroup/PoseCode/2e54471d881bc33c08ed2ec4a417c7d09610cb59/SmartContract/test/.gitkeep -------------------------------------------------------------------------------- /SmartContract/test/ECDSASignatureTest.js: -------------------------------------------------------------------------------- 1 | const PoseManager = artifacts.require("PoseManager_ECDSA"); 2 | 3 | contract("Manager contract", async accounts => { 4 | it("register", async () => { 5 | 6 | let instance = await PoseManager.deployed(); 7 | 8 | //Hard-coded signer: 9 | let signer = web3.eth.accounts.privateKeyToAccount("0xb0057716d5917badaf911b193b12b910811c1497b5bada8d7711f758981c3773"); 10 | 11 | //Attestation hash: 12 | let attestHash = web3.utils.keccak256(web3.eth.abi.encodeParameters(['string', 'bytes32', 'address', 'bytes'], ['Pose-Attest', "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563", "0x90F8bf6A479f320ead074411a4B0e7944Ea8c9C1","0x00"])); 13 | 14 | //EncodedAttestationSignature 15 | let signature = signer.sign(attestHash); 16 | let encodedSignature = web3.eth.abi.encodeParameters(["uint8","bytes32","bytes32"],[signature.v,signature.r,signature.s]) 17 | 18 | await instance.register("0x90F8bf6A479f320ead074411a4B0e7944Ea8c9C1", "0x00", encodedSignature); 19 | 20 | assert.equal(0,0); 21 | }); 22 | }); 23 | -------------------------------------------------------------------------------- /SmartContract/test/RSASignatureTest.js: -------------------------------------------------------------------------------- 1 | const PoseManager = artifacts.require("PoseManager_RSA"); 2 | 3 | //To store evaluation results 4 | let gasLog = []; 5 | 6 | contract("Manager contract", async accounts => { 7 | 8 | //Evaluate the registration 9 | it("register", async () => { 10 | 11 | let instance, receipt, result, tx; 12 | 13 | //RSA public key 14 | let N = "0xBF0C3A0DF9551E2CCE270FF8AF13E6FCC879B4FB2910FA40283C8E075F1B3E61D8EDC99EEED97131B2CBBA8C4A77682FE1B1D12BE775EB7C8D59F59B69606D7DF18ED93F635875530D7DFC182010A31BB447DDB8519852DE08919A51675A548BBE5DD4EA0B97138EFBF74E5ED133AD4DB512C152910DF0F4090CEB05A98009C9E6C3D27B7D2A39DD265DFEB1AE764ECF7126048F5D263B2C17734B750D0FC158FD2D8429D20D0CF96B79DF481317427017854FAD52FFAEFB784757796FDA0F218AAF9F4F44F0D316EC3824FE887C3A8556AE18495D17548B63D7224E7A37A22BB5BBE09C36CDBC87761909A46E646215CBA0B7C36E798671D1B0C5C98A900459"; 15 | let e = "0x03"; 16 | 17 | //Some dummy encryption key 18 | let dummyEncryptionKey = "0x4242424242424242424242424242424242424242424242424242424242424242"; 19 | 20 | //Attestation strings for the 10 accounts := abi.encodePacked("Pose-Attest", hash(POSE Program), enclave address, encave encryption key) //The encryption key is the dummy encryption key 21 | //The 10 accounts are the ones generated by ganache-cli -d 22 | //Hard coded as web3js does not know abi.encodePacked 23 | let preimages = ["0x506f73652d4174746573740a28e9ffef0073f9a6a674cf57ee77307f38f0f1bebb087888d9011ed0eeefdf90f8bf6a479f320ead074411a4b0e7944ea8c9c14242424242424242424242424242424242424242424242424242424242424242", 24 | "0x506f73652d4174746573740a28e9ffef0073f9a6a674cf57ee77307f38f0f1bebb087888d9011ed0eeefdfffcf8fdee72ac11b5c542428b35eef5769c409f04242424242424242424242424242424242424242424242424242424242424242", 25 | "0x506f73652d4174746573740a28e9ffef0073f9a6a674cf57ee77307f38f0f1bebb087888d9011ed0eeefdf22d491bde2303f2f43325b2108d26f1eaba1e32b4242424242424242424242424242424242424242424242424242424242424242", 26 | "0x506f73652d4174746573740a28e9ffef0073f9a6a674cf57ee77307f38f0f1bebb087888d9011ed0eeefdfe11ba2b4d45eaed5996cd0823791e0c93114882d4242424242424242424242424242424242424242424242424242424242424242", 27 | "0x506f73652d4174746573740a28e9ffef0073f9a6a674cf57ee77307f38f0f1bebb087888d9011ed0eeefdfd03ea8624c8c5987235048901fb614fdca89b1174242424242424242424242424242424242424242424242424242424242424242", 28 | "0x506f73652d4174746573740a28e9ffef0073f9a6a674cf57ee77307f38f0f1bebb087888d9011ed0eeefdf95ced938f7991cd0dfcb48f0a06a40fa1af46ebc4242424242424242424242424242424242424242424242424242424242424242", 29 | "0x506f73652d4174746573740a28e9ffef0073f9a6a674cf57ee77307f38f0f1bebb087888d9011ed0eeefdf3e5e9111ae8eb78fe1cc3bb8915d5d461f3ef9a94242424242424242424242424242424242424242424242424242424242424242", 30 | "0x506f73652d4174746573740a28e9ffef0073f9a6a674cf57ee77307f38f0f1bebb087888d9011ed0eeefdf28a8746e75304c0780e011bed21c72cd78cd535e4242424242424242424242424242424242424242424242424242424242424242", 31 | "0x506f73652d4174746573740a28e9ffef0073f9a6a674cf57ee77307f38f0f1bebb087888d9011ed0eeefdfaca94ef8bd5ffee41947b4585a84bda5a3d3da6e4242424242424242424242424242424242424242424242424242424242424242", 32 | "0x506f73652d4174746573740a28e9ffef0073f9a6a674cf57ee77307f38f0f1bebb087888d9011ed0eeefdf1df62f291b2e969fb0849d99d9ce41e2f137006e4242424242424242424242424242424242424242424242424242424242424242"]; 33 | 34 | //Signatures on all of the 10 attestation strings 35 | let signatures = 36 | ["0x583a1d6ae990a637b70903ec743c5f85e8f952310807305380714a9af54b9ec08e7923356645bf9be2c45bb02b10f8db769e901d45ceaaee95acc905d1da5fe3fc8da3d1ff2ad04e98838220259cecda1f2f660b40b013632a8ca43101cf87109f1027f30bfd53e274dcc38675254ad6b43452b70832c193aac3daba9e9cea09e3cc888cde6970a804517bca3cc2705ce8e1cff3709f0e67d867b370c0d1caf05ec99237f5f4d2d530d219e37737d75a390c4bda6a2716f7c3d9ea29f7a2dd9bdc246f44aea0d07fb2e25c3546e4f805f93fd5c7d578725ee07c317c4d3c3f00d61ae81a1e2853d767443417201d96cec6dd180ba24175d63322b16248e1633f", 37 | "0x451d69cac2fb1f608ee880dea4bf08fa9ab6064a168483c3a0150ed76dbb224565f509f74d806f7771513e8b91adda560074150585e1603d2a867c07f8655284892c3c9808adedbda5a6c70cc0395d4eff331ce48180d55b34ca07c30602ea156d4287ddfdab1424547b80d39056dc0b6f6e0851ddcd8e2d27c13aca096156292fb40ec87da27d89ea12319fd1fb3e63637d19c273ce80805426fad1e55415fe76b9faeb9227e7a3370469d4376cce86178561c9c8295f4f9eb3844a210a9db8d8c37e230b491a0d3225f5f559fbf8ec7416cefbc53dadf830944c171063288940b2ecf5f53685ff4ff00f0b590a4c197f543a1edac3ba5feebca9a7f54af04c", 38 | "0x0dbc2fdde23e716ae469b34eb6b724e003ebe4d6c993a934156a33fcece9fd772bde6531a71cc1616c62dcd1ec81f90b543b81a935ce950ee215cb5b410d8b0dff6d82c8bb1bd3d5440ed7aeb755ac3688d224d74004ed86dafacb852e3a788cfbc4c073767d69cb9df4850f47d808769acf895b528db7970cf3a763b5df1c7120f362afc2ba498731427f03f56cb1264d39fcc3d083f2a99c3d12f278e432a868f38eb79f2bf5527663596dcdbaf1eb7934ae794ab2617f9140103fee3905b60d1ae13626b8d757aff2f06de8a3639433ad63604d542fa94b52b2547d28e64c82b08ea0f8bb9059b28abe803c89376ecfad9f90b486eb68d259958fd2774b12", 39 | "0x74c321cd6e32ab7bd6a9b783453e5091a6624ca86adcfd64046ce4681aaf03c4f1bc0d941cadf27962f9c1a43ffc92a54cfcdf4541e69d3e8c40f54985125fc5761f25f73bc244e589e9304a0a58c1275ec80d48e848e9a613f4159be00c5617da288b5813835ba329ec81e0f14157c9b890cdc80d53609e76c3f4037e58a0ed3631b4d93980a7c51a3bd5b474149876d18b016e2eb7e8403fd952492bdeb544a10e2ff1c2b094803ac6816e644575fb0810d6a3d267c3d84d4fca65c22b5bbcc564c60db21adbe308d9fb59b2bd13d33067105b52fdaf8007a230e75d8c2212088d88eb33dff685b68705f256bb6d57b568165443e64bc7f6c71b7650efaa53", 40 | "0xa9dbaea7dead39f262993d46f2673389deedb0cb2779d191340ced38921ca731d527f60814305c555bf5e21619765ccd4c1c0a5fea73de96d3b471ca62e993f9544fe3a12bc4f5419940f1a5f0acdc7d402c071e48028d4648cd867d5d10b0b2bc6480827978ec89d454018df69ff3ebd240cbf356fcef697813ff2ee4dde46cdd5a29d2cbeaa8d54396332fc1c1586f262d1558396eab5b2b9ff877b76ee7250b634fc8fcb4be41ec4d2cc6c4e8ddecee2c499e8d4bdd0552bba1dba044f7fbe001b73b32933e709fd252263ced81a7d1fcb1abd89176c782898b414c891b5fe979cec66580c43613f5845713281e50c38dc0b1d96f58143f0ed3532a95ddb5", 41 | "0x4944b696203e8c161e5031007ffc075b5a7a7829f87b1118e6375d449ed6c6387112f786061dfad142807c7e2e1f7b08cc0a3199c4c0709647c3a3f46cc96927d4f2168e812d30fef3541feda0f71d171e037976e8631c0a5b83464a9a2d05336942ed99d55cf1459ca78a5f236a8f4c1680505d8699aa9189ded17394aca51ec5d1de02706b5340c0070491e8dc5de7cfe7fa3e57af4165ceb865ccddd1ae453382bce290c89fe664807e28105f736525707d1fc54244bc3b80414290a4cfc37761cc8583fce9a813906ed28669ecca7975d4450f40c5ed50ff2e70a4106cc8ea0131944ac33f9bc07a22550e01f90318d8411e45fe6d4b9ff25b33c3050a9c", 42 | "0xbeaef148f554f98d1ed4606d7f87d77d69c9d986ef984a3fb3179aa569c98214e24c6b86b419a9459c8ed093a42d25c7f3fcf1202b8c8c9d50faa17afa4e6ede2d87ea8cae180bf02309c8255cbaf709c0af3f087efd1fbbd099a6ce6b71b0b6ed47a0cb7d8feac0b31bc6fd2627b895b155b78747bed4509a92df592a228224c02ad63ceb391d270fcf1a8ee65ef7d7f1aaf943fb6285a8e68d53eed3233931d4be12ed51a8b0a43bf5680131752b3d7bb31c819d2f2d86e6693fd533969b4963c5456a605bc1bb9c3920679616d1bbb0d45c75d7ca5eaee310159ea87316315b71e20a93ba35e7e9dba83246cf4a6c588f4c6810dd8d2274ea37437eaa5cde", 43 | "0x83fc3e404fcfcface817ff888597b2a573c02acc2e26ca79a6fcb857e0d0fa3cc78e5eacbc0375b6476b76f1fa3a708f9fa2941212025b6e14effec82e97c00b810a8905e55bed1ffd81d783e23d397bb906094a43684f387a51b6c0873650091a1de0a9a38a7c357389b6249e1cd556a91d65acfaa9743a491a6f765c10f553bc6b72a06af5ce7a2e7434bf882b3e4ec451329440cda60551f7c005f2249be5ebf1997eb0ac36cca1965cd580f6c31419b819ed807f34ec0de31048fb3ae1159afb29c4ef0dc359fc7b227467db1243788e88ef212035d00f0e0f0ea5e231ae440358e2c9a1ecb763c6ccc04dd823220344e3102279fd0ce1c3c51dbd3f40b3", 44 | "0x5e75d6420d3702799710a096f37406493e5f637d1dae7986e79dee9eca9f3fdac9ef22b0e7a7e3809348e3709cc9c1d1746306108e9cf8e7be392049c10ff9c1a188d1bd14b75802b890c467c202cac71026d814f238fe2676dcda818a27b547cbc3b80fc09a577fd43d95e5d404b4cd362bf30d2a39ad059b623398c65bededdb63522c791d100a4408c898cd9fcbe32e7fe6c36c743d8e48b2548e1c00e4670ade6f82dcea9f9a3cf15e68b54b1c4c4ac43643fb276af10c817959e4e0d5b78469e4cd01faabb15368ec73332089a4abcdc0779e130468322d99426b9a2cc49eeaa8833227283a38863f2d7f83741b7f72db4cd40f5687360e8cb9478f57ea", 45 | "0x6cfa24b0bd34ae8ec7138bc076dacb4701f6d4e2ad74a4f9b659e3939a35cfb42508b505975139a4732ef45ae5782a9bc7678c79ca38a66eb6fe3aa472e0ac2ff30345b4a7a9e07a3f4ff9d311bd5732940ecc02d6825bddbedbf00a8f00523fed363f0512716c41a55e82496feb3195c60fc61cb315ecd6b06b2125f50939c7db44d8619a768c5bd0747e43f3cf1563533382812eb24df0af2a75cb9a93f6856f0569830457e651b0b1b52056c34c6793d9dab3556281848d75a7bb8a38186df31fece3b6129ced92f63fde4a43e29c2a691ae37599b5f72096666edf991273fdc316cad846ddede5b2bf7eba6ac9d9d15b1424404f27949e48b8591d814d74"]; 46 | 47 | //Execute test 100 times 48 | for(let j = 0; j < 100; j++){ 49 | 50 | //Deploy new contract 51 | instance = await PoseManager.new(); 52 | receipt = await web3.eth.getTransactionReceipt(instance.transactionHash); 53 | gasLog.push({function:"deploy", gas:receipt.gasUsed}); 54 | 55 | //Regsiter each enclave 56 | for(let i in preimages){ 57 | //result = await instance.pkcs1Sha256VerifyRaw(preimages[i],signatures[i],e,N); 58 | // if(result == 0){ 59 | // console.log("Signature " + i + " is valid"); 60 | // } else { 61 | // console.log("Signature " + i + " is invalid"); 62 | // } 63 | 64 | tx = await instance.register(accounts[i],dummyEncryptionKey,signatures[i],{from:accounts[i]}); 65 | gasLog.push({ 66 | function: "register", 67 | tag: "" + j + "-" + i, 68 | gas: tx.receipt.gasUsed 69 | }); 70 | // console.log("Registration " + i + " is successful"); 71 | } 72 | } 73 | }); 74 | 75 | //Store measurements in file 76 | it("Write to file", async () => { 77 | require('fs').writeFileSync("./measurements/RSARegistration.json", JSON.stringify(gasLog, null, " ")); 78 | }); 79 | 80 | }); 81 | -------------------------------------------------------------------------------- /SmartContract/truffle-config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Use this file to configure your truffle project. It's seeded with some 3 | * common settings for different networks and features like migrations, 4 | * compilation and testing. Uncomment the ones you need or modify 5 | * them to suit your project as necessary. 6 | * 7 | * More information about configuration can be found at: 8 | * 9 | * truffleframework.com/docs/advanced/configuration 10 | * 11 | * To deploy via Infura you'll need a wallet provider (like @truffle/hdwallet-provider) 12 | * to sign your transactions before they're sent to a remote public node. Infura accounts 13 | * are available for free at: infura.io/register. 14 | * 15 | * You'll also need a mnemonic - the twelve word phrase the wallet uses to generate 16 | * public/private key pairs. If you're publishing your code to GitHub make sure you load this 17 | * phrase from a file you've .gitignored so it doesn't accidentally become public. 18 | * 19 | */ 20 | 21 | // const HDWalletProvider = require('@truffle/hdwallet-provider'); 22 | // const infuraKey = "fj4jll3k....."; 23 | // 24 | // const fs = require('fs'); 25 | // const mnemonic = fs.readFileSync(".secret").toString().trim(); 26 | 27 | module.exports = { 28 | /** 29 | * Networks define how you connect to your ethereum client and let you set the 30 | * defaults web3 uses to send transactions. If you don't specify one truffle 31 | * will spin up a development blockchain for you on port 9545 when you 32 | * run `develop` or `test`. You can ask a truffle command to use a specific 33 | * network from the command line, e.g 34 | * 35 | * $ truffle test --network 36 | */ 37 | 38 | networks: { 39 | // Useful for testing. The `development` name is special - truffle uses it by default 40 | // if it's defined here and no other network is specified at the command line. 41 | // You should run a client (like ganache-cli, geth or parity) in a separate terminal 42 | // tab if you use this network and you must also set the `host`, `port` and `network_id` 43 | // options below to some value. 44 | // 45 | // development: { 46 | // host: "127.0.0.1", // Localhost (default: none) 47 | // port: 8545, // Standard Ethereum port (default: none) 48 | // network_id: "*", // Any network (default: none) 49 | // websockets: true 50 | // }, 51 | development: { 52 | host: "127.0.0.1", // Localhost (default: none) 53 | port: 8545, // Standard Ethereum port (default: none) 54 | network_id: "*", // Any network (default: none) 55 | websockets: true 56 | } 57 | // Another network with more advanced options... 58 | // advanced: { 59 | // port: 8777, // Custom port 60 | // network_id: 1342, // Custom network 61 | // gas: 8500000, // Gas sent with each transaction (default: ~6700000) 62 | // gasPrice: 20000000000, // 20 gwei (in wei) (default: 100 gwei) 63 | // from:
, // Account to send txs from (default: accounts[0]) 64 | // websockets: true // Enable EventEmitter interface for web3 (default: false) 65 | // }, 66 | // Useful for deploying to a public network. 67 | // NB: It's important to wrap the provider as a function. 68 | // ropsten: { 69 | // provider: () => new HDWalletProvider(mnemonic, `https://ropsten.infura.io/v3/YOUR-PROJECT-ID`), 70 | // network_id: 3, // Ropsten's id 71 | // gas: 5500000, // Ropsten has a lower block limit than mainnet 72 | // confirmations: 2, // # of confs to wait between deployments. (default: 0) 73 | // timeoutBlocks: 200, // # of blocks before a deployment times out (minimum/default: 50) 74 | // skipDryRun: true // Skip dry run before migrations? (default: false for public nets ) 75 | // }, 76 | // Useful for private networks 77 | // private: { 78 | // provider: () => new HDWalletProvider(mnemonic, `https://network.io`), 79 | // network_id: 2111, // This network is yours, in the cloud. 80 | // production: true // Treats this network as if it was a public net. (default: false) 81 | // } 82 | }, 83 | 84 | // Set default mocha options here, use special reporters etc. 85 | mocha: { 86 | // timeout: 100000 87 | }, 88 | 89 | // Configure your compilers 90 | compilers: { 91 | solc: { 92 | version: "0.6.1", // Fetch exact version from solc-bin (default: truffle's version) 93 | // docker: true, // Use "0.5.1" you've installed locally with docker (default: false) 94 | settings: { // See the solidity docs for advice about optimization and evmVersion 95 | /**/ optimizer: { enabled: true, runs: 100 }, /**/ 96 | // evmVersion: "byzantium" 97 | } 98 | }, 99 | }, 100 | }; 101 | --------------------------------------------------------------------------------