PRCYCoin  2.0.0.7rc1
P2P Digital Currency
surjection_impl.h
Go to the documentation of this file.
1 /**********************************************************************
2  * Copyright (c) 2016 Andrew Poelstra *
3  * Distributed under the MIT software license, see the accompanying *
4  * file COPYING or http://www.opensource.org/licenses/mit-license.php.*
5  **********************************************************************/
6 
7 #ifndef _SECP256K1_SURJECTION_IMPL_H_
8 #define _SECP256K1_SURJECTION_IMPL_H_
9 
10 #include <assert.h>
11 #include <string.h>
12 
13 #include "eckey.h"
14 #include "group.h"
15 #include "scalar.h"
16 #include "hash.h"
17 
18 SECP256K1_INLINE static void secp256k1_surjection_genmessage(unsigned char *msg32, secp256k1_ge *ephemeral_input_tags, size_t n_input_tags, secp256k1_ge *ephemeral_output_tag) {
19  /* compute message */
20  size_t i;
21  unsigned char pk_ser[33];
22  size_t pk_len = sizeof(pk_ser);
23  secp256k1_sha256 sha256_en;
24 
25  secp256k1_sha256_initialize(&sha256_en);
26  for (i = 0; i < n_input_tags; i++) {
27  secp256k1_eckey_pubkey_serialize(&ephemeral_input_tags[i], pk_ser, &pk_len, 1);
28  assert(pk_len == sizeof(pk_ser));
29  secp256k1_sha256_write(&sha256_en, pk_ser, pk_len);
30  }
31  secp256k1_eckey_pubkey_serialize(ephemeral_output_tag, pk_ser, &pk_len, 1);
32  assert(pk_len == sizeof(pk_ser));
33  secp256k1_sha256_write(&sha256_en, pk_ser, pk_len);
34  secp256k1_sha256_finalize(&sha256_en, msg32);
35 }
36 
37 SECP256K1_INLINE static int secp256k1_surjection_genrand(secp256k1_scalar *s, size_t ns, const secp256k1_scalar *blinding_key) {
38  size_t i;
39  unsigned char sec_input[36];
40  secp256k1_sha256 sha256_en;
41 
42  /* compute s values */
43  secp256k1_scalar_get_b32(&sec_input[4], blinding_key);
44  for (i = 0; i < ns; i++) {
45  int overflow = 0;
46  sec_input[0] = i;
47  sec_input[1] = i >> 8;
48  sec_input[2] = i >> 16;
49  sec_input[3] = i >> 24;
50 
51  secp256k1_sha256_initialize(&sha256_en);
52  secp256k1_sha256_write(&sha256_en, sec_input, 36);
53  secp256k1_sha256_finalize(&sha256_en, sec_input);
54  secp256k1_scalar_set_b32(&s[i], sec_input, &overflow);
55  if (overflow == 1) {
56  memset(sec_input, 0, 32);
57  return 0;
58  }
59  }
60  memset(sec_input, 0, 32);
61  return 1;
62 }
63 
64 SECP256K1_INLINE static int secp256k1_surjection_compute_public_keys(secp256k1_gej *pubkeys, size_t n_pubkeys, const secp256k1_ge *input_tags, size_t n_input_tags, const unsigned char *used_tags, const secp256k1_ge *output_tag, size_t input_index, size_t *ring_input_index) {
65  size_t i;
66  size_t j = 0;
67  for (i = 0; i < n_input_tags; i++) {
68  if (used_tags[i / 8] & (1 << (i % 8))) {
69  secp256k1_ge tmpge;
70  secp256k1_ge_neg(&tmpge, &input_tags[i]);
71  secp256k1_gej_set_ge(&pubkeys[j], &tmpge);
72  secp256k1_gej_add_ge_var(&pubkeys[j], &pubkeys[j], output_tag, NULL);
73  if (ring_input_index != NULL && input_index == i) {
74  *ring_input_index = j;
75  }
76  j++;
77  if (j > n_pubkeys) {
78  return 0;
79  }
80  }
81  }
82  return 1;
83 }
84 
85 
86 #endif
secp256k1_sha256
Definition: hash.h:13
secp256k1_scalar
A scalar modulo the group order of the secp256k1 curve.
Definition: scalar_4x64.h:13
secp256k1_gej
A group element of the secp256k1 curve, in jacobian coordinates.
Definition: group.h:24
SECP256K1_INLINE
#define SECP256K1_INLINE
Definition: secp256k1.h:23
secp256k1_ge
A group element of the secp256k1 curve, in affine coordinates.
Definition: group.h:14