6 #ifndef SECP256K1_MODULE_SURJECTION_MAIN
7 #define SECP256K1_MODULE_SURJECTION_MAIN
18 static size_t secp256k1_count_bits_set(
const unsigned char* data,
size_t count) {
21 for (i = 0; i < count; i++) {
22 #ifdef HAVE_BUILTIN_POPCOUNT
23 ret += __builtin_popcount(data[i]);
25 ret += !!(data[i] & 0x1);
26 ret += !!(data[i] & 0x2);
27 ret += !!(data[i] & 0x4);
28 ret += !!(data[i] & 0x8);
29 ret += !!(data[i] & 0x10);
30 ret += !!(data[i] & 0x20);
31 ret += !!(data[i] & 0x40);
32 ret += !!(data[i] & 0x80);
50 n_inputs = ((size_t) (input[1] << 8)) + input[0];
54 if (inputlen < 2 + (n_inputs + 7) / 8) {
58 signature_len = 32 * (1 + secp256k1_count_bits_set(&input[2], (n_inputs + 7) / 8));
59 if (inputlen != 2 + (n_inputs + 7) / 8 + signature_len) {
64 memcpy(proof->
data, &input[2 + (n_inputs + 7) / 8], signature_len);
71 size_t serialized_len;
79 signature_len = 32 * (1 + secp256k1_count_bits_set(proof->
used_inputs, (proof->
n_inputs + 7) / 8));
80 serialized_len = 2 + (proof->
n_inputs + 7) / 8 + signature_len;
81 if (*outputlen < serialized_len) {
89 *outputlen = serialized_len;
115 unsigned char state[32];
126 const size_t increment = rand_max > 256 ? 2 : 1;
128 const size_t selection_range = rand_max > 256 ? 0xffff : 0xff;
130 const size_t limit = ((selection_range + 1) / rand_max) * rand_max;
134 if (csprng->
state_i + increment >= 32) {
136 secp256k1_sha256_initialize(&sha);
137 secp256k1_sha256_write(&sha, csprng->
state, 32);
138 secp256k1_sha256_finalize(&sha, csprng->
state);
149 return val % rand_max;
156 size_t n_iterations = 0;
165 ARG_CHECK(n_input_tags_to_use <= n_input_tags);
168 secp256k1_surjectionproof_csprng_init(&csprng, random_seed32);
169 memset(proof->
data, 0,
sizeof(proof->
data));
173 int has_output_tag = 0;
178 for (i = 0; i < n_input_tags_to_use; i++) {
180 size_t next_input_index;
181 next_input_index = secp256k1_surjectionproof_csprng_next(&csprng, n_input_tags);
182 if (memcmp(&fixed_input_tags[next_input_index], fixed_output_tag,
sizeof(*fixed_output_tag)) == 0) {
183 *input_index = next_input_index;
187 if (!(proof->
used_inputs[next_input_index / 8] & (1 << (next_input_index % 8)))) {
188 proof->
used_inputs[next_input_index / 8] |= (1 << (next_input_index % 8));
196 if (has_output_tag) {
198 proof->initialized = 1;
202 if (n_iterations >= n_max_iterations) {
204 proof->initialized = 0;
219 size_t n_total_pubkeys;
220 size_t n_used_pubkeys;
221 size_t ring_input_index = 0;
226 unsigned char msg32[32];
237 CHECK(proof->initialized == 1);
241 secp256k1_scalar_set_b32(&tmps, input_blinding_key, &overflow);
245 secp256k1_scalar_set_b32(&blinding_key, output_blinding_key, &overflow);
251 if (secp256k1_scalar_eq(&tmps, &blinding_key) && !secp256k1_scalar_is_zero(&blinding_key)) {
254 secp256k1_scalar_negate(&tmps, &tmps);
255 secp256k1_scalar_add(&blinding_key, &blinding_key, &tmps);
260 if (n_used_pubkeys > n_total_pubkeys || n_total_pubkeys != n_ephemeral_input_tags) {
264 secp256k1_generator_load(&output, ephemeral_output_tag);
265 for (i = 0; i < n_total_pubkeys; i++) {
266 secp256k1_generator_load(&inputs[i], &ephemeral_input_tags[i]);
269 secp256k1_surjection_compute_public_keys(ring_pubkeys, n_used_pubkeys, inputs, n_total_pubkeys, proof->
used_inputs, &output, input_index, &ring_input_index);
272 rsizes[0] = (int) n_used_pubkeys;
273 indices[0] = (int) ring_input_index;
274 secp256k1_surjection_genmessage(msg32, inputs, n_total_pubkeys, &output);
275 if (secp256k1_surjection_genrand(borromean_s, n_used_pubkeys, &blinding_key) == 0) {
281 nonce = borromean_s[ring_input_index];
282 secp256k1_scalar_clear(&borromean_s[ring_input_index]);
283 if (
secp256k1_borromean_sign(&ctx->
ecmult_ctx, &ctx->
ecmult_gen_ctx, &proof->
data[0], borromean_s, ring_pubkeys, &nonce, &blinding_key, rsizes, indices, 1, msg32, 32) == 0) {
286 for (i = 0; i < n_used_pubkeys; i++) {
287 secp256k1_scalar_get_b32(&proof->
data[32 + 32 * i], &borromean_s[i]);
295 size_t n_total_pubkeys;
296 size_t n_used_pubkeys;
301 unsigned char msg32[32];
312 if (n_used_pubkeys == 0 || n_used_pubkeys > n_total_pubkeys || n_total_pubkeys != n_ephemeral_input_tags) {
316 secp256k1_generator_load(&output, ephemeral_output_tag);
317 for (i = 0; i < n_total_pubkeys; i++) {
318 secp256k1_generator_load(&inputs[i], &ephemeral_input_tags[i]);
321 if (secp256k1_surjection_compute_public_keys(ring_pubkeys, n_used_pubkeys, inputs, n_total_pubkeys, proof->
used_inputs, &output, 0, NULL) == 0) {
326 rsizes[0] = (int) n_used_pubkeys;
327 for (i = 0; i < n_used_pubkeys; i++) {
329 secp256k1_scalar_set_b32(&borromean_s[i], &proof->
data[32 + 32 * i], &overflow);
334 secp256k1_surjection_genmessage(msg32, inputs, n_total_pubkeys, &output);