
$$x.y = 3.4 = 12$$
$$U+V = -949534405+949534417 = 12$$

$$x.y = 5.4 = 20$$
$$U+V = -949534405+949534425 = 20$$
uint32_t x = 4;
bignum256 xBig = convertToBignum(x);
- choosing multiplicative share at the server, (small number so that calculation can be done or easily visualized)
bignum256 a = convertToBignum(rand());
curve_point A;
scalar_multiply(&curveName,&a,&A);
sendPoint(&A,socket,buffer);
- generates a random scalar
a, point multiplies it with G and sends A
receivePoint(&B,socket,buffer);
curve_point aB;
point_multiply(&curveName,&a,&B,&aB);
bignum256 k0 = aB.x;
curve_point B_A;
curve_point aB_A;
bignum256 k1;
point_subtract(&curveName,&B,&A,&B_A);
point_multiply(&curveName,&a,&B_A,&aB_A);
k1 = aB_A.x;
- receives
B from client
- calculated
k0 -> $k_0 = (a.B)_x$
- calculated
k1 -> $k_1 = (a.(B-A))_x$
bignum256 m0,m1,uiBig;
uint32_t ui = rand();
uiBig = convertToBignum(ui);
m0 = uiBig;
m1 = uiBig;
bn_addmod(&m1,&xBig,&curveName.prime);
bignum256 e0,e1;
bn_xor(&e0,&m0,&k0);
bn_xor(&e1,&m1,&k1);
- for ith bit choosing ui and calculating m0 and m1
$$m_0 = u_i$$
$$m_1 = u_i + x$$
- now encrypting them m0 with k0 and m1 with k1
sendBignum(&e0,socket,buffer);
sendBignum(&e1,socket,buffer);
bignum256 twoPow = convertToBignum((1<<i));
bn_multiply(&twoPow,&uiBig,&curveName.prime);
bn_addmod(&u, &uiBig, &curveName.prime);
- sending them to client
- now for each i performing step (calculating the additive share of server)
$$U = \sum\limits_{i=0}^k (2^i * U_i)$$
uint32_t y = 3;
bignum256 yBig = convertToBignum(y);
- choosing multiplicative share at the client, (small number so that calculation can be done or easily visualized)
receivePoint(&A,socket,buffer);
bignum256 b = convertToBignum(rand());
curve_point B;
scalar_multiply(&curveName,&b,&B);
if((1LL<<i)&y){
point_add(&curveName,&A,&B);
}
sendPoint(&B,socket,buffer);
- receive A then calculating B on the basis of the ith bit of y
- then sending B back to server
curve_point bA;
point_multiply(&curveName,&b,&A,&bA);
bignum256 kc = bA.x;
- calculating decryption key $k_c = (b.A)_x$
bignum256 e0,e1;
receiveBignum(&e0,socket,buffer);
receiveBignum(&e1,socket,buffer);
bignum256 mcBig;
uint32_t mc;
if((1<<i)&y){
bn_xor(&mcBig,&kc,&e1);
}
else{
bn_xor(&mcBig,&kc,&e0);
}
- receiving e0 and e1 from server
- on the basis of ith bit of y decrypting the part that was required (either e0 or e1)
bignum256 twoPow = convertToBignum((1<<i));
bn_multiply(&twoPow,&mcBig,&curveName.prime);
bn_addmod(&v,&mcBig,&curveName.prime);
- calculating v (additive share of client)
$$V = \sum\limits_{i=0}^k (2^i * m_{ci})$$
- negating U = -U
- checking
$$x*y = U+V$$
- created a client class and then run
boost::asio::io_context io_context;
boost::asio::ip::tcp::resolver resolver(io_context);
auto endpoints = resolver.resolve("127.0.0.1", "8888");
boost::asio::ip::tcp::socket socket(io_context);
boost::asio::connect(socket, endpoints);
boost::system::error_code error;
- basic boost asio setup with port and ip
- first serial id is signed using client private key and then sent
resetBuffer();
signDigest(clientsPrivatekey,clientSerialId,clientSerialIdSignature);
encodeDataToBuffer(clientSerialIdSignature,64,clientSerialId,32,buffer,bufferSize);
socket.write_some(boost::asio::buffer(buffer),error);
- after this random number is received from server and used serverpublic key to verify it
uint8_t randomNumber[32];
uint8_t randomNumberSignature[64];
resetBuffer();
socket.read_some(boost::asio::buffer(buffer));
decodeDataFromBuffer(randomNumberSignature,randomNumber,buffer,bufferSize);
if(!isSignVerified(serverPublicKey,randomNumberSignature,randomNumber)){
std::cout<<"not verified server\n";
}
else{
std::cout<<"sign verified\n";
}
- again random number is signed using private client key and then sent
resetBuffer();
signDigest(clientsPrivatekey,randomNumber,randomNumberSignature);
encodeDataToBuffer(randomNumberSignature,64,randomNumber,32,buffer,bufferSize);
socket.write_some(boost::asio::buffer(buffer),error);
- implementing cot while sending e0 e1 and key
uint32_t x = 3;
std::cout << "Client x=" << x << "\n";
uint32_t Uis[2], Mcs[2];
uint8_t a_priv[2][32], A_bytes[2][65];
for(int i=0; i<2; ++i) {
Uis[i] = rand() % 16;
generateRandomNumber(a_priv[i]);
uint32_t e0, e1;
cotRoundSend(Uis[i], x, a_priv[i], A_bytes[i], e0, e1);
socket.write_some(boost::asio::buffer(A_bytes[i], 65));
socket.write_some(boost::asio::buffer(&e0, 4));
socket.write_some(boost::asio::buffer(&e1, 4));
}
for(int i=0; i<2; ++i) {
socket.read_some(boost::asio::buffer(&Mcs[i], 4));
}
int32_t U = 0;
for(int i=0; i<2; ++i) {
U -= (Uis[i] << i);
}
std::cout << "Client additive U=" << U << "\n";
- receiving client serial id and verifying it
uint8_t clientSerialId[32];
uint8_t clientSerialIdSignature[64];
resetBuffer();
socket.read_some(boost::asio::buffer(buffer));
decodeDataFromBuffer(clientSerialIdSignature,clientSerialId,buffer,bufferSize);
if(!isSignVerified(clientsPublickey,clientSerialIdSignature,clientSerialId)){
std::cout<<"not verified continuing to another client\n";
continue;
}
else{
std::cout<<"sign verified\n";
}
- generating random number and sending for verification
uint8_t randomNumber[32];
uint8_t randomNumberSignature[64];
resetBuffer();
generateRandomNumber(randomNumber);
signDigest(serverPrivateKey,randomNumber,randomNumberSignature);
encodeDataToBuffer(randomNumberSignature,64,randomNumber,32,buffer,bufferSize);
boost::asio::write(socket, boost::asio::buffer(buffer), ignored_error);
- receiving that random number an verifying and adding clientSerialId
uint8_t recRandomNumber[32];
uint8_t recRandomNumberSignature[64];
resetBuffer();
socket.read_some(boost::asio::buffer(buffer));
decodeDataFromBuffer(recRandomNumberSignature,recRandomNumber,buffer,bufferSize);
if(!isSignVerified(clientsPublickey,recRandomNumberSignature,recRandomNumber)){
std::cout<<"not verified continuing to another client\n";
continue;
}
else{
std::cout<<"sign verified\n";
}
memcpy(this->clientSerialId,clientSerialId,32);