Commitment Schemes

A commitment scheme allows one to commit to a chosen value (or a chosen statement) while keeping it hidden from others, with the ability to reveal the committed value later. There exist some commitment schemes that can be proven by ZK protocols.

The Committer class

class CmtCommitter

This the general class of the Committer side of a Commitment Scheme. A commitment scheme has a commitment phase in which the committer send the commitment to the Receiver, and a decommitment phase in which the the Committer sends the decommitment to the Receiver.

Commit and Decommit

void CmtCommitter::commit(const shared_ptr<CmtCommitValue>& input, long id)

This function is the heart of the commitment phase from the Committer’s point of view.

Parameters:
  • input – The value that the committer commits about.
  • id – Unique value attached to the input to keep track of the commitments in the case that many commitments are performed one after the other without decommiting them yet.
void CmtCommitter::decommit(long id)

This function is the heart of the decommitment phase from the Committer’s point of view.

Parameters id:Unique value used to identify which previously committed value needs to be decommitted now.

There are cases when the user wants to commit the input but remain non-interactive, meaning not to send the generate message yet. The reasons for doing that are vary, for example the user wants to prepare a lot of commitments and send together. In these cases the commit function is not useful since it sends the generates commit message to the other party. The following function provide the ability to generate the commitment and decommitment messages and get them without send to the other party:

shared_ptr<CmtCCommitmentMsg> CmtCommitter::generateCommitmentMsg(const shared_ptr<CmtCommitValue>& input, long id)

This function generates a commitment message using the given input and ID.

shared_ptr<CmtCDecommitmentMessage> CmtCommitter::generateDecommitmentMsg(long id)

This function generate a decommitment message using the given id.

Conversion to and from CmtCommitValue

vector<byte> CmtCommitter::generateBytesFromCommitValue(CmtCommitValue* value)

This function converts the given commit value to a byte array.

Parameters value:
 to get its bytes.
Returns:the generated bytes.
shared_ptr<CmtCommitValue> CmtCommitter::generateCommitValue(const vector<byte>& x)

This function wraps the raw data x with a suitable CommitValue instance according to the actual implementaion.

Parameters x:array to convert into a commitValue.
Returns:the created CommitValue.

Inner state functions

CmtCommitmentPhaseValues* CmtCommitter::getCommitmentPhaseValues(long id)

This function returns the values calculated during the commit phase for a specific commitment. This function is used for protocols that need values of the commitment, like ZK protocols during proofs on the commitment. We recommended not to call this function from somewhere else.

Parameters id:of the specific commitment
Returns:values calculated during the commit phase
vector<shared_ptr<void>> CmtCommitter::getPreProcessValues()

This function returns the values calculated during the preprocess phase. This function is used for protocols that need values of the commitment, like ZK protocols during proofs on the commitment. We recommended not to call this function from somewhere else.

Returns:values calculated during the preprocess phase
shared_ptr<CmtCommitValue> CmtCommitter::sampleRandomCommitValue()

This function samples random commit value to commit on.

Returns:the sampled commit value.

The Receiver class

class CmtReceiver

This the general class of the Receiver side of a Commitment Scheme. A commitment scheme has a commitment phase in which the Receiver waits for the commitment sent by the Committer; and a decommitment phase in which the Receiver waits for the decommitment sent by the Committer and checks whether to accept or reject the decommitment.

Receive Commitment and Decommitment

shared_ptr<CmtRCommitPhaseOutput> CmtReceiver::receiveCommitment()

This function is the heart of the commitment phase from the Receiver’s point of view.

Returns:the id of the commitment and some other information if necessary according to the implementing class.
shared_ptr<CmtCommitValue> CmtReceiver::receiveDecommitment(long id)

This function is the heart of the decommitment phase from the Receiver’s point of view.

Parameters id:wait for a specific message according to this id
Returns:the commitment
shared_ptr<CmtCommitValue> CmtReceiver::verifyDecommitment(CmtCCommitmentMsg* commitmentMsg, CmtCDecommitmentMessage* decommitmentMsg)

There are cases when the receiver gets the commitment and decommitments in the application (not by the channel), and the receiver does not use the receiveCommitment and receiveDecommitment function. In these cases this function should be called for each pair of commitment and decommitment messages. The reasons for doing that are vary, for example a protocol that prepare a lot of commitments and send together. In these cases the receiveCommitment and receiveDecommitment functions are not useful since they receive the generates messages separately to the other party. This function generates the message without sending it and this allows the user to save it and send it later if he wants.

Conversion to and from CmtCommitValue

vector<byte> CmtReceiver::generateBytesFromCommitValue(CmtCommitValue* value)

This function converts the given commit value to a byte array.

Parameters value:
 to get its bytes.
Returns:the generated bytes.

Inner state functions

shared_ptr<void> CmtReceiver::getCommitmentPhaseValues(long id)

Return the intermediate values used during the commitment phase.

Parameters id:get the commitment values according to this id.
Returns:a general array of Objects.
vector<shared_ptr<void>> CmtReceiver::getPreProcessedValues()

Return the values used during the pre-process phase (usually upon construction). Since these values vary between the different implementations this function returns a general array of Objects.

Returns:a general array of Objects

Implemented Protocols

Each concrete commitment protocol should have committer and receiver classes that extends the CmtCommitter and CmtReceiver abstract classes mentioned above or the CmtCommitterWithProofs and CmtReceiverWithProofs, in case the scheme can be proven.

Concrete Commitments protocols implemented so far are: * Pedersen commitment * Pedersen Hash commitment * Pedersen Trapdoor commitment * El Gamal commitment * El Gamal Hash commitment * Simple Hash commitment * Equivoqal commitments

Example of Usage

Commitment protocol has two sides: committer and receiver. In order to execute the commitment protocol, both committer and receiver should be created as separate programs (Usually not on the same machine).

Steps in committer creation:

  • Given a Channel object ch do:
    • Create a CmtCommitter (for example, CmtPedersenCommitter).
    • Create an instance of the concrete CommitValue that suits the commitment scheme (This can be done by calling the function generateCommitValue(byte[]).
    • Call the commit() function of the committer with the committed value and id.
    • Call the decommit() function of the committer with the same id sent to the commit() function.

Code example:

//create the committer
auto dlog = make_shared<OpenSSLDlogECF2m>("K-233");
CmtPedersenCommitter committer(ch, dlog, get_seeded_prg());

//generate CommitValue from string
vector<byte> msg(10, 0);
auto val = committer.generateCommitValue(msg);

//Commit on the commit value with id 2
committer.commit(val, 2);

//decommit id 2
committer.decommit(2);

Steps in receiver creation:

  • Given a Channel object ch do:
    • Create a CmtReceiver (for example, CmtPedersenReceiver).
    • Call the receiverCommitment() function of the receiver.
    • Call the receiveDecommitment() function of the receiver with the id given in the output of the receiverCommitment() function.
    • The CommitValue returned from the receiveDecommitment() can be converted to bytes using the generateBytesFromCommitValue() function of the receiver.

Code example:

//create the receiver
auto dlog = make_shared<OpenSSLDlogECF2m>("K-233");
CmtPedersenReceiver receiver(ch, dlog, get_seeded_prg());

//Receive the commitment on the commit value
auto output = receiver.receiveCommitment();

//Receive the decommit
auto val = receiver.receiveDecommitment(output.getCommitmentId());

//Convert the commitValue to bytes.
vector<byte> committedVector = receiver.generateBytesFromCommitValue(val.get());

for (int i=0; i<committedVector.size(); i++){
    cout << committedVector[i];
}
cout<<endl;