|
| 1 | +# coding: utf-8 |
| 2 | +""" |
| 3 | + Demo to show for DevCon, focusing on client interface, allowing clients to disconnect after giving inputs and reconnect to get output |
| 4 | + while also allowing servers to store values |
| 5 | +""" |
| 6 | +from typing import Type |
| 7 | +from Compiler.types import sint, regint, Array, MemValue |
| 8 | +from Compiler.library import print_ln, do_while, for_range, accept_client_connection, listen_for_clients, if_, if_e, else_, crash |
| 9 | +from Compiler.instructions import closeclientconnection |
| 10 | +from Compiler.util import if_else |
| 11 | +from Compiler.circuit import sha3_256 |
| 12 | +from Compiler.GC.types import sbitvec, sbit |
| 13 | + |
| 14 | + |
| 15 | +SECRET_INDEX = regint(1) |
| 16 | +PORTNUM = 8013 |
| 17 | +MAX_DATA_PROVIDERS = 1000 |
| 18 | +INPUT_BYTES = 4 |
| 19 | +DELTA = '63ce8963a8d236f2ed41f2c6f4cc81fa' |
| 20 | +ZERO_ENCODINGS = ['4d367c38a3db6de1c3273559ccc80a4d', '54d6d355990433a2acc3c9a4eb76c911', 'f796787dc39a2d9b611637b56b3851f7', '85d9e61682e59a1b01c7cef839f06a4c', 'f397bc83b842ee1884a30beb43be8ef0', 'b80264fb280eaa10fe509e83450dca9c', '99769731800fc7723c85a4e27e8c8748', 'cd8310c1c2f17e9a5b9ae08d08279fc8', 'ee577842a72ea783596f773b7ca6d317', 'ff235b8c43e2f63e92c6e35a2f31090e', '5f53449406446cba75abc40dc1515b25', 'b201d8d8a59786752500572db96897ed', '4a612e9042d49a3012c254018bfd5663', '90fefc14b6d980bcc272b3f6586f1beb', '6ef28030ac56cca07a9e50a718a03149', 'b2e8609a91729106774fb23a54748bb3', '083ca4d4e9ca27b68945140113ecb363', '135b8dfb68420cf9ce7c8824e0523c94', '7f870730d973029cad3561a9ed02a461', 'b791d7213350d1c163f2854083592a1c', '1fa7c67f0cfd635bfadaba7adce6ee79', '0f3287fed18a40bf9a734f97423562b8', '9b58b466655bf6ee87dce6aab6707323', 'e488f970c6dfc51f6cff9a5518bf1d5c', 'e446fd7f2ae8ee84558e0e2e7da523ab', '3d2c96a16177c28a020689954b71eabc', 'a34eb40287c086a8b94a7159f9fde686', 'debc23a0acd3c90a2beb92e8254cff56', 'f8d2d7a6173c987d1036af6f7a652140', '121bf26a0e09ed1544e793f4a924fe03', '6d25836999abc4eccdd2d9ddd6d6853e', 'd0fdbd9d6a8cb4a25e60400d37704ad1'] |
| 21 | + |
| 22 | + |
| 23 | +def accept_client(): |
| 24 | + client_socket_id = accept_client_connection(PORTNUM) |
| 25 | + placeholder = regint.read_from_socket(client_socket_id) |
| 26 | + return client_socket_id |
| 27 | + |
| 28 | + |
| 29 | +def client_input(t: Type[sint], client_socket_id: regint): |
| 30 | + """ |
| 31 | + Send share of random value, receive input and deduce share. |
| 32 | + """ |
| 33 | + received = t.receive_from_client(2, client_socket_id) |
| 34 | + return received[0], sbitvec(received[1], 256) |
| 35 | + |
| 36 | +def calculate_data_commitment(num_bytes_followers: int, followers: sint, delta: sbitvec, encoding: list[sbitvec], nonce: sbitvec): |
| 37 | + # Adjust based on data_type |
| 38 | + ASCII_BASE = 48 |
| 39 | + DOT_ASCII = 46 |
| 40 | + followers_bits_list = [] |
| 41 | + number = followers |
| 42 | + divisors = [sint(10 ** (num_bytes_followers - i)) for i in range(num_bytes_followers)] |
| 43 | + for divisor in divisors: |
| 44 | + curr_digit = number.int_div(divisor, 4*num_bytes_followers) |
| 45 | + followers_bits_list.extend(sbit(ele) for ele in sbitvec(curr_digit+ASCII_BASE, 8).v) |
| 46 | + number = number.int_mod(divisor, 4*num_bytes_followers) |
| 47 | + dot_sbit_vec = sbitvec(sint(46),8).v |
| 48 | + insert_index = (num_bytes_followers - 2) * 8 |
| 49 | + for ele in [sbit(ele) for ele in dot_sbit_vec][::-1]: |
| 50 | + followers_bits_list.insert(insert_index, ele) |
| 51 | + active_encoding:list[sbitvec] = [] |
| 52 | + for i in range(len(encoding)): |
| 53 | + filtered_delta = [] |
| 54 | + for j in range(len(delta)): |
| 55 | + filtered_delta.append(followers_bits_list[i].if_else(delta[j], sbit(0))) |
| 56 | + filtered_delta = sbitvec.from_vec(filtered_delta) |
| 57 | + active_encoding.append(encoding[i].bit_xor(filtered_delta)) |
| 58 | + |
| 59 | + concat = nonce.bit_decompose() + sbitvec(sint(num_bytes_followers+1), 8).bit_decompose() |
| 60 | + for i in range(len(encoding)): |
| 61 | + if i%8 ==0: |
| 62 | + concat = concat + sbitvec(sint(1), 8).bit_decompose() |
| 63 | + concat = concat+active_encoding[i].bit_decompose() |
| 64 | + return sha3_256(sbitvec.compose(concat)) |
| 65 | + |
| 66 | + |
| 67 | +def main(): |
| 68 | + # put as array to make it object |
| 69 | + # First element is the number of clients |
| 70 | + client_values = sint.Array(1 + MAX_DATA_PROVIDERS) |
| 71 | + commitment_values = sint.Array(MAX_DATA_PROVIDERS) |
| 72 | + |
| 73 | + |
| 74 | + # Start listening for client socket connections |
| 75 | + print_ln('Calling listen_for_clients(%s)...', PORTNUM) |
| 76 | + listen_for_clients(PORTNUM) |
| 77 | + print_ln('Listening for client connections on base port %s', PORTNUM) |
| 78 | + |
| 79 | + client_socket_id = accept_client() |
| 80 | + print_ln('Accepted client connection. client_socket_id: %s', client_socket_id) |
| 81 | + |
| 82 | + input_value, input_nonce = client_input(sint, client_socket_id) |
| 83 | + client_values[SECRET_INDEX] = input_value |
| 84 | + client_values[0] = client_values[0] + 1 |
| 85 | + client_values.write_to_file(0) |
| 86 | + |
| 87 | + # these are shared directly to each computation party so can just hardcode |
| 88 | + input_delta = sbitvec.from_hex(DELTA) |
| 89 | + input_zero_encodings = [sbitvec.from_hex(e) for e in ZERO_ENCODINGS] |
| 90 | + |
| 91 | + # nonce must be secret_shared |
| 92 | + input_commitment = calculate_data_commitment(INPUT_BYTES-1, input_value, input_delta, input_zero_encodings, input_nonce) |
| 93 | + input_commitment.reveal_print_hex() |
| 94 | + |
| 95 | + # commitment of input i is stored in commitment_values[i-1] |
| 96 | + commitment_values[SECRET_INDEX-1] = input_commitment |
| 97 | + commitment_values.write_to_file(1 + MAX_DATA_PROVIDERS) |
| 98 | + print_ln('commitment_values: after update: %s', [commitment_values[i].reveal() for i in range(MAX_DATA_PROVIDERS)]) |
| 99 | + sint.reveal_to_clients([client_socket_id],[commitment_values[SECRET_INDEX-1]]) |
| 100 | + print_ln('Now closing this connection') |
| 101 | + #print_ln('Num data providers: %s', client_values[0].reveal()) |
| 102 | + |
| 103 | + closeclientconnection(client_socket_id) |
| 104 | + |
| 105 | + |
| 106 | +main() |
0 commit comments