@@ -21,6 +21,11 @@ typedef struct {
2121 unsigned char data [64 ];
2222} secp256k1_generator ;
2323
24+ /**
25+ * Static constant generator 'h' maintained for historical reasons.
26+ */
27+ SECP256K1_API extern const secp256k1_generator * secp256k1_generator_h ;
28+
2429/** Parse a 33-byte generator byte sequence into a generator object.
2530 *
2631 * Returns: 1 if input contains a valid generator.
@@ -86,6 +91,149 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_generator_generate_blin
8691 const unsigned char * blind32
8792) SECP256K1_ARG_NONNULL (1 ) SECP256K1_ARG_NONNULL (2 ) SECP256K1_ARG_NONNULL (3 ) SECP256K1_ARG_NONNULL (4 );
8893
94+ /** Opaque data structure that stores a Pedersen commitment
95+ *
96+ * The exact representation of data inside is implementation defined and not
97+ * guaranteed to be portable between different platforms or versions. It is
98+ * however guaranteed to be 64 bytes in size, and can be safely copied/moved.
99+ * If you need to convert to a format suitable for storage, transmission, or
100+ * comparison, use secp256k1_pedersen_commitment_serialize and
101+ * secp256k1_pedersen_commitment_parse.
102+ */
103+ typedef struct {
104+ unsigned char data [64 ];
105+ } secp256k1_pedersen_commitment ;
106+
107+ /** Parse a 33-byte commitment into a commitment object.
108+ *
109+ * Returns: 1 if input contains a valid commitment.
110+ * Args: ctx: a secp256k1 context object.
111+ * Out: commit: pointer to the output commitment object
112+ * In: input: pointer to a 33-byte serialized commitment key
113+ */
114+ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_pedersen_commitment_parse (
115+ const secp256k1_context * ctx ,
116+ secp256k1_pedersen_commitment * commit ,
117+ const unsigned char * input
118+ ) SECP256K1_ARG_NONNULL (1 ) SECP256K1_ARG_NONNULL (2 ) SECP256K1_ARG_NONNULL (3 );
119+
120+ /** Serialize a commitment object into a serialized byte sequence.
121+ *
122+ * Returns: 1 always.
123+ * Args: ctx: a secp256k1 context object.
124+ * Out: output: a pointer to a 33-byte byte array
125+ * In: commit: a pointer to a secp256k1_pedersen_commitment containing an
126+ * initialized commitment
127+ */
128+ SECP256K1_API int secp256k1_pedersen_commitment_serialize (
129+ const secp256k1_context * ctx ,
130+ unsigned char * output ,
131+ const secp256k1_pedersen_commitment * commit
132+ ) SECP256K1_ARG_NONNULL (1 ) SECP256K1_ARG_NONNULL (2 ) SECP256K1_ARG_NONNULL (3 );
133+
134+ /** Generate a pedersen commitment.
135+ * Returns 1: Commitment successfully created.
136+ * 0: Error. The blinding factor is larger than the group order
137+ * (probability for random 32 byte number < 2^-127) or results in the
138+ * point at infinity. Retry with a different factor.
139+ * In: ctx: pointer to a context object, initialized for signing and Pedersen commitment (cannot be NULL)
140+ * blind: pointer to a 32-byte blinding factor (cannot be NULL)
141+ * value: unsigned 64-bit integer value to commit to.
142+ * gen: additional generator 'h'
143+ * Out: commit: pointer to the commitment (cannot be NULL)
144+ *
145+ * Blinding factors can be generated and verified in the same way as secp256k1 private keys for ECDSA.
146+ */
147+ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_pedersen_commit (
148+ const secp256k1_context * ctx ,
149+ secp256k1_pedersen_commitment * commit ,
150+ const unsigned char * blind ,
151+ uint64_t value ,
152+ const secp256k1_generator * gen
153+ ) SECP256K1_ARG_NONNULL (1 ) SECP256K1_ARG_NONNULL (2 ) SECP256K1_ARG_NONNULL (3 ) SECP256K1_ARG_NONNULL (5 );
154+
155+ /** Computes the sum of multiple positive and negative blinding factors.
156+ * Returns 1: Sum successfully computed.
157+ * 0: Error. A blinding factor is larger than the group order
158+ * (probability for random 32 byte number < 2^-127). Retry with
159+ * different factors.
160+ * In: ctx: pointer to a context object (cannot be NULL)
161+ * blinds: pointer to pointers to 32-byte character arrays for blinding factors. (cannot be NULL)
162+ * n: number of factors pointed to by blinds.
163+ * npositive: how many of the initial factors should be treated with a positive sign.
164+ * Out: blind_out: pointer to a 32-byte array for the sum (cannot be NULL)
165+ */
166+ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_pedersen_blind_sum (
167+ const secp256k1_context * ctx ,
168+ unsigned char * blind_out ,
169+ const unsigned char * const * blinds ,
170+ size_t n ,
171+ size_t npositive
172+ ) SECP256K1_ARG_NONNULL (1 ) SECP256K1_ARG_NONNULL (2 ) SECP256K1_ARG_NONNULL (3 );
173+
174+ /** Verify a tally of pedersen commitments
175+ * Returns 1: commitments successfully sum to zero.
176+ * 0: Commitments do not sum to zero or other error.
177+ * In: ctx: pointer to a context object (cannot be NULL)
178+ * commits: pointer to array of pointers to the commitments. (cannot be NULL if pcnt is non-zero)
179+ * pcnt: number of commitments pointed to by commits.
180+ * ncommits: pointer to array of pointers to the negative commitments. (cannot be NULL if ncnt is non-zero)
181+ * ncnt: number of commitments pointed to by ncommits.
182+ *
183+ * This computes sum(commit[0..pcnt)) - sum(ncommit[0..ncnt)) == 0.
184+ *
185+ * A pedersen commitment is xG + vA where G and A are generators for the secp256k1 group and x is a blinding factor,
186+ * while v is the committed value. For a collection of commitments to sum to zero, for each distinct generator
187+ * A all blinding factors and all values must sum to zero.
188+ *
189+ */
190+ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_pedersen_verify_tally (
191+ const secp256k1_context * ctx ,
192+ const secp256k1_pedersen_commitment * const * commits ,
193+ size_t pcnt ,
194+ const secp256k1_pedersen_commitment * const * ncommits ,
195+ size_t ncnt
196+ ) SECP256K1_ARG_NONNULL (1 ) SECP256K1_ARG_NONNULL (2 ) SECP256K1_ARG_NONNULL (4 );
197+
198+ /** Sets the final Pedersen blinding factor correctly when the generators themselves
199+ * have blinding factors.
200+ *
201+ * Consider a generator of the form A' = A + rG, where A is the "real" generator
202+ * but A' is the generator provided to verifiers. Then a Pedersen commitment
203+ * P = vA' + r'G really has the form vA + (vr + r')G. To get all these (vr + r')
204+ * to sum to zero for multiple commitments, we take three arrays consisting of
205+ * the `v`s, `r`s, and `r'`s, respectively called `value`s, `generator_blind`s
206+ * and `blinding_factor`s, and sum them.
207+ *
208+ * The function then subtracts the sum of all (vr + r') from the last element
209+ * of the `blinding_factor` array, setting the total sum to zero.
210+ *
211+ * Returns 1: Blinding factor successfully computed.
212+ * 0: Error. A blinding_factor or generator_blind are larger than the group
213+ * order (probability for random 32 byte number < 2^-127). Retry with
214+ * different values.
215+ *
216+ * In: ctx: pointer to a context object
217+ * value: array of asset values, `v` in the above paragraph.
218+ * May not be NULL unless `n_total` is 0.
219+ * generator_blind: array of asset blinding factors, `r` in the above paragraph
220+ * May not be NULL unless `n_total` is 0.
221+ * n_total: Total size of the above arrays
222+ * n_inputs: How many of the initial array elements represent commitments that
223+ * will be negated in the final sum
224+ * In/Out: blinding_factor: array of commitment blinding factors, `r'` in the above paragraph
225+ * May not be NULL unless `n_total` is 0.
226+ * the last value will be modified to get the total sum to zero.
227+ */
228+ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_pedersen_blind_generator_blind_sum (
229+ const secp256k1_context * ctx ,
230+ const uint64_t * value ,
231+ const unsigned char * const * generator_blind ,
232+ unsigned char * const * blinding_factor ,
233+ size_t n_total ,
234+ size_t n_inputs
235+ );
236+
89237# ifdef __cplusplus
90238}
91239# endif
0 commit comments