add changelog
[oweals/gnunet.git] / src / secretsharing / secretsharing_common.c
1 /*
2      This file is part of GNUnet.
3      Copyright (C) 2014 GNUnet e.V.
4
5      GNUnet is free software: you can redistribute it and/or modify it
6      under the terms of the GNU Affero General Public License as published
7      by the Free Software Foundation, either version 3 of the License,
8      or (at your option) any later version.
9
10      GNUnet is distributed in the hope that it will be useful, but
11      WITHOUT ANY WARRANTY; without even the implied warranty of
12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13      Affero General Public License for more details.
14
15      You should have received a copy of the GNU Affero General Public License
16      along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
18      SPDX-License-Identifier: AGPL3.0-or-later
19  */
20
21 #include "secretsharing.h"
22
23 /**
24  * Read a share from its binary representation.
25  *
26  * @param data Binary representation of the share.
27  * @param len Length of @a data.
28  * @param[out] readlen Number of bytes read,
29  *             ignored if NULL.
30  * @return The share, or NULL on error.
31  */
32 struct GNUNET_SECRETSHARING_Share *
33 GNUNET_SECRETSHARING_share_read (const void *data,
34                                  size_t len,
35                                  size_t *readlen)
36 {
37   struct GNUNET_SECRETSHARING_Share *share;
38   const struct GNUNET_SECRETSHARING_ShareHeaderNBO *sh = data;
39   const char *p;
40   size_t n;
41   uint16_t payload_size;
42
43   payload_size = ntohs (sh->num_peers)
44                  * (sizeof(uint16_t) + sizeof(struct
45                                               GNUNET_SECRETSHARING_FieldElement)
46                     + sizeof(struct GNUNET_PeerIdentity));
47
48   if (NULL != readlen)
49     *readlen = payload_size + sizeof *sh;
50
51   share = GNUNET_new (struct GNUNET_SECRETSHARING_Share);
52
53   share->threshold = ntohs (sh->threshold);
54   share->num_peers = ntohs (sh->num_peers);
55   share->my_peer = ntohs (sh->my_peer);
56
57   share->my_share = sh->my_share;
58   share->public_key = sh->public_key;
59
60   p = (const char *) &sh[1];
61
62   n = share->num_peers * sizeof(struct GNUNET_PeerIdentity);
63   share->peers = GNUNET_new_array (share->num_peers,
64                                    struct GNUNET_PeerIdentity);
65   GNUNET_memcpy (share->peers, p, n);
66   p += n;
67
68   n = share->num_peers * sizeof(struct GNUNET_SECRETSHARING_FieldElement);
69   share->sigmas = GNUNET_new_array (share->num_peers,
70                                     struct GNUNET_SECRETSHARING_FieldElement);
71   GNUNET_memcpy (share->sigmas, p, n);
72   p += n;
73
74   n = share->num_peers * sizeof(uint16_t);
75   share->original_indices = GNUNET_new_array (share->num_peers,
76                                               uint16_t);
77   GNUNET_memcpy (share->original_indices, p, n);
78
79   return share;
80 }
81
82
83 /**
84  * Convert a share to its binary representation.
85  * Can be called with a NULL @a buf to get the size of the share.
86  *
87  * @param share Share to write.
88  * @param buf Buffer to write to.
89  * @param buflen Number of writable bytes in @a buf.
90  * @param[out] writelen Pointer to store number of bytes written,
91  *             ignored if NULL.
92  * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure.
93  */
94 int
95 GNUNET_SECRETSHARING_share_write (const struct
96                                   GNUNET_SECRETSHARING_Share *share,
97                                   void *buf, size_t buflen, size_t *writelen)
98 {
99   uint16_t payload_size;
100   struct GNUNET_SECRETSHARING_ShareHeaderNBO *sh;
101   char *p;
102   int n;
103
104   payload_size = share->num_peers
105                  * (sizeof(uint16_t) + sizeof(struct
106                                               GNUNET_SECRETSHARING_FieldElement)
107                     + sizeof(struct GNUNET_PeerIdentity));
108
109   if (NULL != writelen)
110     *writelen = payload_size + sizeof(struct
111                                       GNUNET_SECRETSHARING_ShareHeaderNBO);
112
113   /* just a query for the writelen */
114   if (buf == NULL)
115     return GNUNET_OK;
116
117   /* wrong buffer size */
118   if (buflen < payload_size + sizeof(struct
119                                      GNUNET_SECRETSHARING_ShareHeaderNBO))
120     return GNUNET_SYSERR;
121
122   sh = buf;
123
124   sh->threshold = htons (share->threshold);
125   sh->num_peers = htons (share->num_peers);
126   sh->my_peer = htons (share->my_peer);
127
128   sh->my_share = share->my_share;
129   sh->public_key = share->public_key;
130
131   p = (void *) &sh[1];
132
133   n = share->num_peers * sizeof(struct GNUNET_PeerIdentity);
134   GNUNET_memcpy (p, share->peers, n);
135   p += n;
136
137   n = share->num_peers * sizeof(struct GNUNET_SECRETSHARING_FieldElement);
138   GNUNET_memcpy (p, share->sigmas, n);
139   p += n;
140
141   n = share->num_peers * sizeof(uint16_t);
142   GNUNET_memcpy (p, share->original_indices, n);
143
144   return GNUNET_OK;
145 }
146
147
148 void
149 GNUNET_SECRETSHARING_share_destroy (struct GNUNET_SECRETSHARING_Share *share)
150 {
151   GNUNET_free (share->original_indices);
152   share->original_indices = NULL;
153   GNUNET_free (share->sigmas);
154   share->sigmas = NULL;
155   GNUNET_free (share->peers);
156   share->peers = NULL;
157   GNUNET_free (share);
158 }