What is Secure Comparator

Secure Comparator is an implementation of Zero-Knowledge Proof-based protocol, built around OTR SMP implementation, but ported to ECC domain and reinforced with additional checks and features.

Secure Comparator allows two parties to compare a shared secret without revealing it to potentially dishonest party.

You might want to consult our whitepaper on Comparator's development and cryptographic protocol here to study the security/cryptography details (or there is an "Explain me like I'm 5"-style article on Zero Knowledge Proof in the Cossack Labs Medium blog).

Secure Comparator use cases

  • Login/password authentication: by sending login, client allows the server to allocate password (or secure derivative) and start comparing it.
  • OTP reinforcement: authenticating action within an already established communication/trust protocol.
  • Request authentication: authenticating data request by proving the knowledge of some significant part of the data's identification fields.
  • Repeated authentication: authenticating already established trust relationships using initial tokens and shared state data accumulated during the session.

Secure Comparator availability in Themis

Being the most recent addition to the mainline Themis code to the date, Secure Comparator is yet to get all the shine and polish that our other objects do have. However, Secure Comparator is already available in Go, C++, Ruby, Python, NodeJs, Java, and Objective-C/Swift wrappers. You can find the language-specific examples in the docs/examples folder.

Protocol

Our SMP protocol is very similar to the SMP implementation in the Cypherpunk’s OTR, except for the fact that we use ECC for all computations.

Let’s suppose we have two parties with secrets x and y respectively, and they wish to know whether x == y. They use ed25519 curve with G as a base point. Alice starts the protocol:

Alice:

  • picks two random numbers: a2 and a3,

  • computes G2a = a2 * G and G3a = a3 * G,

  • sends G2a and G3a to Bob.

Bob:

  • picks two random numbers: b2 and b3,

  • computes G2b = b2 * G and G3b = b3 * G,

  • computes G2 = b2 * G2a and G3 = b3 * G3a,

  • picks a random number r,

  • computes Pb = r * G3 and Qb = r * G + y * G2,

  • sends G2b, G3b, Pb and Qb to Alice.

Alice:

  • computes G2 = a2 * G2b and G3 = a3 * G3b,

  • picks a random number s,

  • computes Pa = s * G3 and Qa = s * G + x * G2,

  • computes Ra = a3 * (Qa - Qb),

  • sends Pa, Qa, Ra to Bob.

Bob:

  • computes Rb = b3 * (Qa - Qb),

  • computes Rab = b3 * Ra,

  • checks whether Rab == Pa - Pb,

  • sends Rb to Alice.

Alice:

  • computes Rab = a3 * Rb,

  • checks whether Rab == Pa - Pb.

If the Rab == Pa - Pb check is successful, each party is then convinced that x == y.
Since Rab = (Pa - Pb) + (a3 * b3 * (x - y)) * G2, if x == y, Rab = (Pa - Pb) + 0 * G2 = Pa - Pb. If x≠ y, then a3 * b3 * (x - y) * G2 is a random ECC point not known to any of the interacting parties, so no information is revealed.

Secure Comparator usage examples

Secure Comparator has two parties: initiator (client) and responder (server). They both initialise the Secure Comparator object, and, upon receiving anything from the communication channel, execute the next protocol step until the protocol is either successful or failed.

For example, you may look at the Python client and server.

Implementation details

Secure Comparator interface is described in src/themis/secure_comparator.h. Implementation doesn't cover the network layer, so it is your responsibility to send and receive the messages from one side to another.

To create Secure Comparator object, use secure_comparator_create function, then enter secret_data you want to compare using the secure_comparator_append_secret:

secure_comparator_t* secure_comparator_create(void);
themis_status_t secure_comparator_append_secret(secure_comparator_t *comp_ctx,
                                                const void *secret_data,
                                                size_t secret_data_length);

The first step of comparison is made by the initiator. You need to send compare_data to the responder.

themis_status_t secure_comparator_begin_compare(secure_comparator_t *comp_ctx,
                                                void *compare_data,
                                                size_t *compare_data_length);

Then responder and the initiator are proceeding with message calculations. The results of each step should be sent to the other party.

themis_status_t secure_comparator_proceed_compare(secure_comparator_t *comp_ctx,
                                                  const void *peer_compare_data,
                                                  size_t peer_compare_data_length,
                                                  void *compare_data,
                                                  size_t *compare_data_length);

The result of the comparison can be checked calling secure_comparator_get_result function, and returns "success" if the secrets match.

themis_status_t secure_comparator_get_result(const secure_comparator_t *comp_ctx);