61 unsigned char amount_scalar[32] = {0};
63 for (
int i = 0; i < 8; ++i) {
64 amount_scalar[31 - i] = (amount >> (i * 8)) & 0xFF;
66 return secp256k1_ec_pubkey_create(ctx, mG, amount_scalar);
73 const secp256k1_context* ctx,
75 const secp256k1_pubkey* c1,
const secp256k1_pubkey* c2,
76 const secp256k1_pubkey* pk,
77 const secp256k1_pubkey* mG,
78 const secp256k1_pubkey* T1,
const secp256k1_pubkey* T2,
79 const unsigned char* tx_context_id)
82 unsigned char buf[33];
85 const char* domain =
"MPT_POK_PLAINTEXT_PROOF";
88 SHA256_Update(&sha, domain, strlen(domain));
91 len = 33; secp256k1_ec_pubkey_serialize(ctx, buf, &len, c1, SECP256K1_EC_COMPRESSED); SHA256_Update(&sha, buf, 33);
92 len = 33; secp256k1_ec_pubkey_serialize(ctx, buf, &len, c2, SECP256K1_EC_COMPRESSED); SHA256_Update(&sha, buf, 33);
93 len = 33; secp256k1_ec_pubkey_serialize(ctx, buf, &len, pk, SECP256K1_EC_COMPRESSED); SHA256_Update(&sha, buf, 33);
98 len = 33; secp256k1_ec_pubkey_serialize(ctx, buf, &len, mG, SECP256K1_EC_COMPRESSED); SHA256_Update(&sha, buf, 33);
102 len = 33; secp256k1_ec_pubkey_serialize(ctx, buf, &len, T1, SECP256K1_EC_COMPRESSED); SHA256_Update(&sha, buf, 33);
103 len = 33; secp256k1_ec_pubkey_serialize(ctx, buf, &len, T2, SECP256K1_EC_COMPRESSED); SHA256_Update(&sha, buf, 33);
106 SHA256_Update(&sha, tx_context_id, 32);
109 SHA256_Final(h, &sha);
116 const secp256k1_context* ctx,
117 unsigned char* proof,
118 const secp256k1_pubkey* c1,
119 const secp256k1_pubkey* c2,
120 const secp256k1_pubkey* pk_recipient,
122 const unsigned char* randomness_r,
123 const unsigned char* tx_context_id)
128 unsigned char term[32];
129 secp256k1_pubkey T1, T2;
131 secp256k1_pubkey* mG_ptr = NULL;
136 if (!secp256k1_ec_seckey_verify(ctx, randomness_r))
goto cleanup;
142 if (!secp256k1_ec_pubkey_create(ctx, &T1, t))
goto cleanup;
145 if (!secp256k1_ec_pubkey_tweak_mul(ctx, &T2, t))
goto cleanup;
156 memcpy(term, randomness_r, 32);
157 if (!secp256k1_ec_seckey_tweak_mul(ctx, term, e))
goto cleanup;
158 if (!secp256k1_ec_seckey_tweak_add(ctx, s, term))
goto cleanup;
161 unsigned char* ptr = proof;
163 if (!secp256k1_ec_pubkey_serialize(ctx, ptr, &len, &T1, SECP256K1_EC_COMPRESSED))
goto cleanup;
167 if (!secp256k1_ec_pubkey_serialize(ctx, ptr, &len, &T2, SECP256K1_EC_COMPRESSED))
goto cleanup;
175 OPENSSL_cleanse(t, 32);
176 OPENSSL_cleanse(term, 32);
178 OPENSSL_cleanse(s, 32);
182 const secp256k1_context* ctx,
183 const unsigned char* proof,
184 const secp256k1_pubkey* c1,
185 const secp256k1_pubkey* c2,
186 const secp256k1_pubkey* pk_recipient,
188 const unsigned char* tx_context_id)
190 secp256k1_pubkey T1, T2;
194 secp256k1_pubkey* mG_ptr = NULL;
195 const unsigned char* ptr = proof;
197 secp256k1_pubkey LHS, RHS, term;
198 const secp256k1_pubkey* pts[2];
202 if (!secp256k1_ec_pubkey_parse(ctx, &T1, ptr, 33))
goto cleanup; ptr += 33;
203 if (!secp256k1_ec_pubkey_parse(ctx, &T2, ptr, 33))
goto cleanup; ptr += 33;
207 if (!secp256k1_ec_seckey_verify(ctx, s))
goto cleanup;
219 if (!secp256k1_ec_pubkey_create(ctx, &LHS, s))
goto cleanup;
222 if (!secp256k1_ec_pubkey_tweak_mul(ctx, &term, e))
goto cleanup;
223 pts[0] = &T1; pts[1] = &term;
224 if (!secp256k1_ec_pubkey_combine(ctx, &RHS, pts, 2))
goto cleanup;
232 if (!secp256k1_ec_pubkey_tweak_mul(ctx, &LHS, s))
goto cleanup;
235 secp256k1_pubkey Y = *c2;
237 secp256k1_pubkey neg_mG = *mG_ptr;
238 if (!secp256k1_ec_pubkey_negate(ctx, &neg_mG))
goto cleanup;
239 pts[0] = c2; pts[1] = &neg_mG;
240 if (!secp256k1_ec_pubkey_combine(ctx, &Y, pts, 2))
goto cleanup;
245 if (!secp256k1_ec_pubkey_tweak_mul(ctx, &term, e))
goto cleanup;
246 pts[0] = &T2; pts[1] = &term;
247 if (!secp256k1_ec_pubkey_combine(ctx, &RHS, pts, 2))
goto cleanup;
int secp256k1_equality_plaintext_verify(const secp256k1_context *ctx, const unsigned char *proof, const secp256k1_pubkey *c1, const secp256k1_pubkey *c2, const secp256k1_pubkey *pk_recipient, uint64_t amount, const unsigned char *tx_context_id)
Verifies a proof of knowledge of plaintext and randomness.
int secp256k1_equality_plaintext_prove(const secp256k1_context *ctx, unsigned char *proof, const secp256k1_pubkey *c1, const secp256k1_pubkey *c2, const secp256k1_pubkey *pk_recipient, uint64_t amount, const unsigned char *randomness_r, const unsigned char *tx_context_id)
Generates a proof that an ElGamal ciphertext correctly encrypts a known plaintext m and that the prov...
static void compute_challenge_equality(const secp256k1_context *ctx, unsigned char *e_out, const secp256k1_pubkey *c1, const secp256k1_pubkey *c2, const secp256k1_pubkey *pk, const secp256k1_pubkey *mG, const secp256k1_pubkey *T1, const secp256k1_pubkey *T2, const unsigned char *tx_context_id)