- log
[oweals/gnunet.git] / src / secretsharing / secretsharing_common.c
1 /*
2      This file is part of GNUnet.
3      (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., 59 Temple Place - Suite 330,
18      Boston, MA 02111-1307, 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, size_t len, size_t *readlen)
34 {
35   struct GNUNET_SECRETSHARING_Share *share;
36   const struct GNUNET_SECRETSHARING_ShareHeaderNBO *sh = data;
37   char *p;
38   size_t n;
39   uint16_t payload_size;
40
41   payload_size = ntohs (sh->num_peers) * 
42       (sizeof (uint16_t) + sizeof (struct GNUNET_SECRETSHARING_FieldElement) + 
43        sizeof (struct GNUNET_PeerIdentity));
44
45   if (NULL != readlen)
46     *readlen = payload_size + sizeof *sh;
47
48   share = GNUNET_malloc (sizeof *share);
49
50   share->threshold = ntohs (sh->threshold);
51   share->num_peers = ntohs (sh->num_peers);
52   share->my_peer = ntohs (sh->my_peer);
53
54   share->my_share = sh->my_share;
55   share->public_key = sh->public_key;
56
57   p = (void *) &sh[1];
58
59   n = share->num_peers * sizeof (struct GNUNET_PeerIdentity);
60   share->peers = GNUNET_malloc (n);
61   memcpy (share->peers, p, n);
62   p += n;
63
64   n = share->num_peers * sizeof (struct GNUNET_SECRETSHARING_FieldElement);
65   share->sigmas = GNUNET_malloc (n);
66   memcpy (share->sigmas, p, n);
67   p += n;
68
69   n = share->num_peers * sizeof (uint16_t);
70   share->original_indices = GNUNET_malloc (n);
71   memcpy (share->original_indices, p, n);
72
73   return share;
74 }
75
76
77 /**
78  * Convert a share to its binary representation.
79  * Can be called with a NULL @a buf to get the size of the share.
80  *
81  * @param share Share to write.
82  * @param buf Buffer to write to.
83  * @param buflen Number of writable bytes in @a buf.
84  * @param[out] writelen Pointer to store number of bytes written,
85  *             ignored if NULL.
86  * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure.
87  */
88 int
89 GNUNET_SECRETSHARING_share_write (const struct GNUNET_SECRETSHARING_Share *share,
90                                   void *buf, size_t buflen, size_t *writelen)
91 {
92   uint16_t payload_size;
93   struct GNUNET_SECRETSHARING_ShareHeaderNBO *sh;
94   char *p;
95   int n;
96
97   payload_size = share->num_peers * 
98       (sizeof (uint16_t) + sizeof (struct GNUNET_SECRETSHARING_FieldElement) + 
99        sizeof (struct GNUNET_PeerIdentity));
100
101   if (NULL != writelen)
102     *writelen = payload_size + sizeof (struct GNUNET_SECRETSHARING_ShareHeaderNBO);
103
104   /* just a query for the writelen */
105   if (buf == NULL)
106     return GNUNET_OK;
107
108   /* wrong buffer size */
109   if (buflen < payload_size + sizeof (struct GNUNET_SECRETSHARING_ShareHeaderNBO))
110     return GNUNET_SYSERR;
111
112   sh = buf;
113
114   sh->threshold = htons (share->threshold);
115   sh->num_peers = htons (share->num_peers);
116   sh->my_peer = htons (share->my_peer);
117
118   sh->my_share = share->my_share;
119   sh->public_key = share->public_key;
120
121   p = (void *) &sh[1];
122
123   n = share->num_peers * sizeof (struct GNUNET_PeerIdentity);
124   memcpy (p, share->peers, n);
125   p += n;
126
127   n = share->num_peers * sizeof (struct GNUNET_SECRETSHARING_FieldElement);
128   memcpy (p, share->sigmas, n);
129   p += n;
130
131   n = share->num_peers * sizeof (uint16_t);
132   memcpy (p, share->original_indices, n);
133
134   return GNUNET_OK;
135 }
136
137