Rate This Document
Findability
Accuracy
Completeness
Readability

makeShare

In two-party operations, this function is called to split the original data of node 0 (compute party) and node 1 (non-compute party) into shares. When node 0 calls this function, it sets isRecvShare to 1 to receive the shares sent by node 1, and then sets isRecvShare to 0 to split its own data into shares. When the non-compute party calls this function, it sets isRecvShare to 0 to split its own data into shares and then sends the shares to the compute party. In three-party operations, this function is called to split the original data of any two nodes among node 0 (compute party) and nodes 1 and 2 (non-compute parties) into shares. Assume that nodes 0 and 1 have data. When node 0 calls this function, it sets isRecvShare to 1 to receive the shares sent by node 1, and then sets isRecvShare to 0 to split its own data into shares. When node 1 calls this function, it sets isRecvShare to 0 to split its own data into shares and sends the shares to node 0, and sets isRecvShare to 1 to receive the shares sent by node 0. Then, node 2 sets isRecvShare to 1 to receive the shares sent by node 0 and sets isRecvShare to 1 to receive the shares sent by node 1.

int makeShare(
    DG_TeeCtx *dgTeeCtx,
    int isRecvShare,
    DG_TeeInput *input,
    DG_MpcShare **share 
)

Parameters

Table 1 Description

Parameter

Description

Value Range

Input/Output

dgTeeCtx

KCAL context

Context initialized in section initTeeCtx.

Input

isRecvShare

  • 0: Splits the original data of a node itself into shares.
  • 1: Receives data shares of the other node.

0 or 1.

Input

input

This is the original data. If isRecvShare is set to 0, input can be null. If isRecvShare is not set to 0, input cannot be null.

Currently, only the double type is supported.

Input

share

The type of the share result:

DG_MpcShare

It is null as a single pointer and cannot be null as a double pointer.

Output

Table 2 DG_TeeInput structure

Member

Type

Description

data

DG_MpcDataUnion

The types of the input data strings, doubleNumbers, and u64Numbers are respectively DG_String *, double *, and u64 *.

size

uint64_t

Data volume

dataType

DG_MpcDataType

The enumerated data type is as follows:

MPC_INT (cryptographic comparison)

MPC_DOUBLE (cryptographic addition, subtraction, maximum, minimum, multiplication, division, averaging, summation, and sorting)

Table 3 DG_MpcDataUnion

Member

Type

Description

strings

DG_String

String array

u64Numbers

u64

u64 array

doubleNumbers

double

Double array

Table 4 DG_MpcShare structure

Member

Type

Description

dataShare

Share

Share structure

size

unsigned long

Data volume

shareType

DG_ShareType

Share type

Table 5 DG_ShareType enumeration

Member

Description

FIX_POINT

Data is converted into the double type when revealShare is executed.

NON_FIX_POINT

Data is converted into the u64 type when revealShare is executed.

Table 6 Share structure

Member

Type

Description

shares

u64*

Multiple shares corresponding to one piece of plaintext data

size

u64

The number of shares

Return Values

  • Success: 0 is returned.
  • Failure: The error code is returned.

Error Codes

Table 7 Error code

Error Code

Value

Description

Remarks

DG_FAILURE

4501

Data share splitting failure

Failed to verify the parameters.

Failed to split data into shares.

Failed to receive data from the other node.

Dependency

  • dgTeeCtx depends on the successful initialization of initTeeCtx.
  • You need to call the negotiateSeeds API to distribute seeds to all nodes.
  • #include "data_guard_mpc.h": required header file

Example

#include  "data_guard_mpc.h" 
    std::unique_ptr<double[]> inData = std::make_unique<double[]>(datas.size());
    for (int i = 0; i < datas.size(); i++) {
        inData[i] = (std::stod(datas[i].c_str())) * 1.0;
    }
  // DG_TeeInput teeInput indicates the data shares from the compute party.
    teeInput.data.doubleNumbers = inData.get();
    teeInput.size = static_cast<int>(datas.size());
    teeInput.dataType = MPC_DOUBLE;
    int res = aritOpts.negotiateSeeds(dgTee);
    printf("exchange seed res = %d\n", res);
    DG_MpcShareSet shareDat;
    std::unique_ptr<DG_MpcShare[]> share = std::make_unique<DG_MpcShare[]>(2);
    DG_MpcShare *share1 = nullptr;
    DG_MpcShare *share2 = nullptr;
    DG_TeeOutput *output = nullptr;
    if (nodeId == 0) { // Compute node 0 receives the data shares of compute node 1 and then splits the data of compute node 0 itself into shares.
         res = aritOpts.makeShare(dgTee, 1, nullptr, &share1); // teeInput
    		if (res != 0) {
      		printf("node 0 recv share data.[ret=%d]\n", res);
      		return res;
         }
         res = aritOpts.makeShare(dgTee, 0, teeInput, &share2);
         if (res != 0) {
            printf("node 0 make share self shar data fail.[ret=%d]\n", res);
            return res;
         }
} else { // Correspondingly, compute node 1 splits the data of compute node 1 itself into shares and then receives the data shares of compute node 0.
         res = aritOpts.makeShare(dgTee, 0, teeInput, &share1);
    if (res != 0) {
      	    printf("node 1 make share self shar data fail.[ret=%d]\n", res);
             return res;
          }
         res = aritOpts.makeShare(dgTee, 1, nullptr, &share2);
         if (res != 0) {
             printf("make share self shar data.[ret=%d]\n", res);
             return res;
         }
}
Test result: res is 0, and shares 1 and 2 are not null.
// Data shares
Note: The example is for reference only. It describes how to read data from a file for testing and cannot be executed.
Test result: res is 0 and the shares are not null.
  • Call the makeShare API using the aritOpts output of the successful DG_InitArithmeticOpts call.
  • If either node (compute node 0 or 1) returns an error code when calling an API, the node needs to use a task scheduling mechanism to notify the other node to terminate the service process. For example, if compute node 1 returns an error code when calling the makeShare API and compute node 0 is waiting to receive shares, compute node 1 needs to notify compute node 0 to stop receiving.