fix out-of-tree build of GNUnet
[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
6      it under the terms of the GNU General Public License as published
7      by the Free Software Foundation; either version 3, or (at your
8      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      General Public License for more details.
14
15      You should have received a copy of the GNU General Public License
16      along with GNUnet; see the file COPYING.  If not, write to the
17      Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18      Boston, MA 02110-1301, USA.
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 GNUNET_SECRETSHARING_FieldElement) +
45        sizeof (struct GNUNET_PeerIdentity));
46
47   if (NULL != readlen)
48     *readlen = payload_size + sizeof *sh;
49
50   share = GNUNET_new (struct GNUNET_SECRETSHARING_Share);
51
52   share->threshold = ntohs (sh->threshold);
53   share->num_peers = ntohs (sh->num_peers);
54   share->my_peer = ntohs (sh->my_peer);
55
56   share->my_share = sh->my_share;
57   share->public_key = sh->public_key;
58
59   p = (const char *) &sh[1];
60
61   n = share->num_peers * sizeof (struct GNUNET_PeerIdentity);
62   share->peers = GNUNET_new_array (share->num_peers,
63                                    struct GNUNET_PeerIdentity);
64   GNUNET_memcpy (share->peers, p, n);
65   p += n;
66
67   n = share->num_peers * sizeof (struct GNUNET_SECRETSHARING_FieldElement);
68   share->sigmas = GNUNET_new_array (share->num_peers,
69                                     struct GNUNET_SECRETSHARING_FieldElement);
70   GNUNET_memcpy (share->sigmas, p, n);
71   p += n;
72
73   n = share->num_peers * sizeof (uint16_t);
74   share->original_indices = GNUNET_new_array (share->num_peers,
75                                               uint16_t);
76   GNUNET_memcpy (share->original_indices, p, n);
77
78   return share;
79 }
80
81
82 /**
83  * Convert a share to its binary representation.
84  * Can be called with a NULL @a buf to get the size of the share.
85  *
86  * @param share Share to write.
87  * @param buf Buffer to write to.
88  * @param buflen Number of writable bytes in @a buf.
89  * @param[out] writelen Pointer to store number of bytes written,
90  *             ignored if NULL.
91  * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure.
92  */
93 int
94 GNUNET_SECRETSHARING_share_write (const struct GNUNET_SECRETSHARING_Share *share,
95                                   void *buf, size_t buflen, size_t *writelen)
96 {
97   uint16_t payload_size;
98   struct GNUNET_SECRETSHARING_ShareHeaderNBO *sh;
99   char *p;
100   int n;
101
102   payload_size = share->num_peers *
103       (sizeof (uint16_t) + sizeof (struct GNUNET_SECRETSHARING_FieldElement) +
104        sizeof (struct GNUNET_PeerIdentity));
105
106   if (NULL != writelen)
107     *writelen = payload_size + sizeof (struct GNUNET_SECRETSHARING_ShareHeaderNBO);
108
109   /* just a query for the writelen */
110   if (buf == NULL)
111     return GNUNET_OK;
112
113   /* wrong buffer size */
114   if (buflen < payload_size + sizeof (struct GNUNET_SECRETSHARING_ShareHeaderNBO))
115     return GNUNET_SYSERR;
116
117   sh = buf;
118
119   sh->threshold = htons (share->threshold);
120   sh->num_peers = htons (share->num_peers);
121   sh->my_peer = htons (share->my_peer);
122
123   sh->my_share = share->my_share;
124   sh->public_key = share->public_key;
125
126   p = (void *) &sh[1];
127
128   n = share->num_peers * sizeof (struct GNUNET_PeerIdentity);
129   GNUNET_memcpy (p, share->peers, n);
130   p += n;
131
132   n = share->num_peers * sizeof (struct GNUNET_SECRETSHARING_FieldElement);
133   GNUNET_memcpy (p, share->sigmas, n);
134   p += n;
135
136   n = share->num_peers * sizeof (uint16_t);
137   GNUNET_memcpy (p, share->original_indices, n);
138
139   return GNUNET_OK;
140 }
141
142
143 void
144 GNUNET_SECRETSHARING_share_destroy (struct GNUNET_SECRETSHARING_Share *share)
145 {
146   GNUNET_free (share->original_indices);
147   share->original_indices = NULL;
148   GNUNET_free (share->sigmas);
149   share->sigmas = NULL;
150   GNUNET_free (share->peers);
151   share->peers = NULL;
152   GNUNET_free (share);
153 }