- dump client info on request
[oweals/gnunet.git] / src / secretsharing / secretsharing_common.c
1 /*
2      This file is part of GNUnet.
3      Copyright (C) 2014 Christian Grothoff (and other contributing authors)
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   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_malloc (sizeof *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 = (void *) &sh[1];
60
61   n = share->num_peers * sizeof (struct GNUNET_PeerIdentity);
62   share->peers = GNUNET_malloc (n);
63   memcpy (share->peers, p, n);
64   p += n;
65
66   n = share->num_peers * sizeof (struct GNUNET_SECRETSHARING_FieldElement);
67   share->sigmas = GNUNET_malloc (n);
68   memcpy (share->sigmas, p, n);
69   p += n;
70
71   n = share->num_peers * sizeof (uint16_t);
72   share->original_indices = GNUNET_malloc (n);
73   memcpy (share->original_indices, p, n);
74
75   return share;
76 }
77
78
79 /**
80  * Convert a share to its binary representation.
81  * Can be called with a NULL @a buf to get the size of the share.
82  *
83  * @param share Share to write.
84  * @param buf Buffer to write to.
85  * @param buflen Number of writable bytes in @a buf.
86  * @param[out] writelen Pointer to store number of bytes written,
87  *             ignored if NULL.
88  * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure.
89  */
90 int
91 GNUNET_SECRETSHARING_share_write (const struct GNUNET_SECRETSHARING_Share *share,
92                                   void *buf, size_t buflen, size_t *writelen)
93 {
94   uint16_t payload_size;
95   struct GNUNET_SECRETSHARING_ShareHeaderNBO *sh;
96   char *p;
97   int n;
98
99   payload_size = share->num_peers *
100       (sizeof (uint16_t) + sizeof (struct GNUNET_SECRETSHARING_FieldElement) +
101        sizeof (struct GNUNET_PeerIdentity));
102
103   if (NULL != writelen)
104     *writelen = payload_size + sizeof (struct GNUNET_SECRETSHARING_ShareHeaderNBO);
105
106   /* just a query for the writelen */
107   if (buf == NULL)
108     return GNUNET_OK;
109
110   /* wrong buffer size */
111   if (buflen < payload_size + sizeof (struct GNUNET_SECRETSHARING_ShareHeaderNBO))
112     return GNUNET_SYSERR;
113
114   sh = buf;
115
116   sh->threshold = htons (share->threshold);
117   sh->num_peers = htons (share->num_peers);
118   sh->my_peer = htons (share->my_peer);
119
120   sh->my_share = share->my_share;
121   sh->public_key = share->public_key;
122
123   p = (void *) &sh[1];
124
125   n = share->num_peers * sizeof (struct GNUNET_PeerIdentity);
126   memcpy (p, share->peers, n);
127   p += n;
128
129   n = share->num_peers * sizeof (struct GNUNET_SECRETSHARING_FieldElement);
130   memcpy (p, share->sigmas, n);
131   p += n;
132
133   n = share->num_peers * sizeof (uint16_t);
134   memcpy (p, share->original_indices, n);
135
136   return GNUNET_OK;
137 }
138
139
140 void
141 GNUNET_SECRETSHARING_share_destroy (struct GNUNET_SECRETSHARING_Share *share)
142 {
143   GNUNET_free (share->original_indices);
144   share->original_indices = NULL;
145   GNUNET_free (share->sigmas);
146   share->sigmas = NULL;
147   GNUNET_free (share->peers);
148   share->peers = NULL;
149   GNUNET_free (share);
150 }
151
152