mpt-crypto
Confidential Multi-Purpose Tokens Cryptographic Library
Loading...
Searching...
No Matches
proof_pok_sk.c
Go to the documentation of this file.
1
39#include "secp256k1_mpt.h"
40#include <string.h>
41#include <openssl/sha.h>
42#include <openssl/rand.h>
43#include <stdlib.h>
44
45/* --- Internal Helpers --- */
46
47static int pubkey_equal(const secp256k1_context* ctx, const secp256k1_pubkey* pk1, const secp256k1_pubkey* pk2) {
48 return secp256k1_ec_pubkey_cmp(ctx, pk1, pk2) == 0;
49}
50
51static int generate_random_scalar(const secp256k1_context* ctx, unsigned char* scalar) {
52 do {
53 if (RAND_bytes(scalar, 32) != 1) return 0;
54 } while (!secp256k1_ec_seckey_verify(ctx, scalar));
55 return 1;
56}
57
59 const secp256k1_context* ctx,
60 unsigned char* e_out,
61 const secp256k1_pubkey* pk,
62 const secp256k1_pubkey* T,
63 const unsigned char* context_id)
64{
65 SHA256_CTX sha;
66 unsigned char buf[33];
67 unsigned char h[32];
68 size_t len;
69 const char* domain = "MPT_POK_SK_REGISTER";
70
71 SHA256_Init(&sha);
72 SHA256_Update(&sha, domain, strlen(domain));
73
74 len = 33;
75 secp256k1_ec_pubkey_serialize(ctx, buf, &len, pk, SECP256K1_EC_COMPRESSED);
76 SHA256_Update(&sha, buf, 33);
77
78 len = 33;
79 secp256k1_ec_pubkey_serialize(ctx, buf, &len, T, SECP256K1_EC_COMPRESSED);
80 SHA256_Update(&sha, buf, 33);
81
82 if (context_id) {
83 SHA256_Update(&sha, context_id, 32);
84 }
85
86 SHA256_Final(h, &sha);
88}
89
90/* --- Public API --- */
91
93 const secp256k1_context* ctx,
94 unsigned char* proof_out,
95 const secp256k1_pubkey* pk,
96 const unsigned char* sk,
97 const unsigned char* context_id)
98{
99 unsigned char k[32];
100 unsigned char e[32];
101 unsigned char s[32];
102 unsigned char term[32];
103 secp256k1_pubkey T;
104 size_t len;
105 int ok = 0;
106
107 if (!secp256k1_ec_seckey_verify(ctx, sk)) return 0;
108 if (!generate_random_scalar(ctx, k)) goto cleanup;
109 if (!secp256k1_ec_pubkey_create(ctx, &T, k)) goto cleanup;
110
111 build_pok_challenge(ctx, e, pk, &T, context_id);
112
113 // s = k + e*sk
114 memcpy(term, sk, 32);
115 if (!secp256k1_ec_seckey_tweak_mul(ctx, term, e)) goto cleanup;
116 memcpy(s, k, 32);
117 if (!secp256k1_ec_seckey_tweak_add(ctx, s, term)) goto cleanup;
118
119 // Serialize: T (33) || s (32)
120 unsigned char* ptr = proof_out;
121 len = 33;
122 if (!secp256k1_ec_pubkey_serialize(ctx, ptr, &len, &T, SECP256K1_EC_COMPRESSED)) goto cleanup;
123 ptr += 33;
124 memcpy(ptr, s, 32);
125
126 ok = 1;
127
128 cleanup:
129 OPENSSL_cleanse(k, 32);
130 OPENSSL_cleanse(term, 32);
131 OPENSSL_cleanse(s, 32);
132 return ok;
133}
134
136 const secp256k1_context* ctx,
137 const unsigned char* proof, // Caller MUST ensure this is at least 65 bytes
138 const secp256k1_pubkey* pk,
139 const unsigned char* context_id)
140{
141 secp256k1_pubkey T, LHS, RHS, ePk;
142 unsigned char e[32], s[32];
143 const unsigned char* ptr = proof;
144 int ok = 0;
145
146 /* 1. Parse T (33 bytes) */
147 if (!secp256k1_ec_pubkey_parse(ctx, &T, ptr, 33)) goto cleanup;
148 ptr += 33;
149
150 /* 2. Parse s (32 bytes) */
151 memcpy(s, ptr, 32);
152 if (!secp256k1_ec_seckey_verify(ctx, s)) goto cleanup;
153
154 /* 3. Recompute Challenge */
155 build_pok_challenge(ctx, e, pk, &T, context_id);
156
157 /* 4. Verify Equation: s*G == T + e*Pk */
158 if (!secp256k1_ec_pubkey_create(ctx, &LHS, s)) goto cleanup;
159
160 ePk = *pk;
161 if (!secp256k1_ec_pubkey_tweak_mul(ctx, &ePk, e)) goto cleanup;
162
163 const secp256k1_pubkey* addends[2] = {&T, &ePk};
164 if (!secp256k1_ec_pubkey_combine(ctx, &RHS, addends, 2)) goto cleanup;
165
166 if (!pubkey_equal(ctx, &LHS, &RHS)) goto cleanup;
167
168 ok = 1;
169
170 cleanup:
171 return ok;
172}
int secp256k1_mpt_pok_sk_verify(const secp256k1_context *ctx, const unsigned char *proof, const secp256k1_pubkey *pk, const unsigned char *context_id)
static void build_pok_challenge(const secp256k1_context *ctx, unsigned char *e_out, const secp256k1_pubkey *pk, const secp256k1_pubkey *T, const unsigned char *context_id)
static int pubkey_equal(const secp256k1_context *ctx, const secp256k1_pubkey *pk1, const secp256k1_pubkey *pk2)
static int generate_random_scalar(const secp256k1_context *ctx, unsigned char *scalar)
int secp256k1_mpt_pok_sk_prove(const secp256k1_context *ctx, unsigned char *proof_out, const secp256k1_pubkey *pk, const unsigned char *sk, const unsigned char *context_id)
void secp256k1_mpt_scalar_reduce32(unsigned char out32[32], const unsigned char in32[32])
Definition mpt_scalar.c:106