3 * $Id: buf.c,v 1.3 2004/04/01 12:50:09 mdw Exp $
7 * (c) 2001 Straylight/Edgeware
10 /*----- Licensing notice --------------------------------------------------*
12 * This file is part of Catacomb.
14 * Catacomb is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU Library General Public License as
16 * published by the Free Software Foundation; either version 2 of the
17 * License, or (at your option) any later version.
19 * Catacomb is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU Library General Public License for more details.
24 * You should have received a copy of the GNU Library General Public
25 * License along with Catacomb; if not, write to the Free
26 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
30 /*----- Revision history --------------------------------------------------*
33 * Revision 1.3 2004/04/01 12:50:09 mdw
34 * Add cyclic group abstraction, with test code. Separate off exponentation
35 * functions for better static linking. Fix a buttload of bugs on the way.
36 * Generally ensure that negative exponents do inversion correctly. Add
37 * table of standard prime-field subgroups. (Binary field subgroups are
38 * currently unimplemented but easy to add if anyone ever finds a good one.)
40 * Revision 1.2 2003/11/10 22:18:30 mdw
43 * Revision 1.1 2003/10/11 21:02:33 mdw
44 * Import buf stuff from tripe.
46 * Revision 1.4 2001/06/19 22:09:54 mdw
47 * Expose interface, for use in the proxy.
49 * Revision 1.3 2001/03/03 12:06:48 mdw
50 * Use 16-bit lengths on MPs, since there's a packet limit of 64K anyway.
52 * Revision 1.2 2001/02/16 21:23:20 mdw
53 * Various minor changes. Check that MPs are in canonical form when
56 * Revision 1.1 2001/02/03 20:26:37 mdw
61 /*----- Header files ------------------------------------------------------*/
69 /*----- Main code ---------------------------------------------------------*/
71 /* --- @buf_init@ --- *
73 * Arguments: @buf *b@ = pointer to a buffer block
74 * @void *p@ = pointer to a buffer
75 * @size_t sz@ = size of the buffer
79 * Use: Initializes the buffer block appropriately.
82 void buf_init(buf
*b
, void *p
, size_t sz
)
89 /* --- @buf_break@ --- *
91 * Arguments: @buf *b@ = pointer to a buffer block
93 * Returns: Some negative value.
95 * Use: Marks a buffer as broken.
98 int buf_break(buf
*b
) { b
->f
|= BF_BROKEN
; return (-1); }
100 /* --- @buf_flip@ --- *
102 * Arguments: @buf *b@ = pointer to a buffer block
106 * Use: Flips a buffer so that if you've just been writing to it,
107 * you can now read from the bit you've written.
110 void buf_flip(buf
*b
)
116 /* --- @buf_ensure@ --- *
118 * Arguments: @buf *b@ = pointer to a buffer block
119 * @size_t sz@ = size of data wanted
121 * Returns: Zero if it worked, nonzero if there wasn't enough space.
123 * Use: Ensures that there are @sz@ bytes still in the buffer.
126 int buf_ensure(buf
*b
, size_t sz
) { return (BENSURE(b
, sz
)); }
128 /* --- @buf_get@ --- *
130 * Arguments: @buf *b@ = pointer to a buffer block
131 * @size_t sz@ = size of the buffer
133 * Returns: Pointer to the place in the buffer.
135 * Use: Reserves a space in the buffer of the requested size, and
136 * returns its start address.
139 void *buf_get(buf
*b
, size_t sz
)
149 /* --- @buf_put@ --- *
151 * Arguments: @buf *b@ = pointer to a buffer block
152 * @const void *p@ = pointer to a buffer
153 * @size_t sz@ = size of the buffer
155 * Returns: Zero if it worked, nonzero if there wasn't enough space.
157 * Use: Fetches data from some place and puts it in the buffer
160 int buf_put(buf
*b
, const void *p
, size_t sz
)
164 memcpy(BCUR(b
), p
, sz
);
169 /* --- @buf_getbyte@ --- *
171 * Arguments: @buf *b@ = pointer to a buffer block
173 * Returns: A byte, or less than zero if there wasn't a byte there.
175 * Use: Gets a single byte from a buffer.
178 int buf_getbyte(buf
*b
)
185 /* --- @buf_putbyte@ --- *
187 * Arguments: @buf *b@ = pointer to a buffer block
188 * @int ch@ = byte to write
190 * Returns: Zero if OK, nonzero if there wasn't enough space.
192 * Use: Puts a single byte in a buffer.
195 int buf_putbyte(buf
*b
, int ch
)
203 /* --- @buf_getu16@ --- *
205 * Arguments: @buf *b@ = pointer to a buffer block
206 * @uint16 *w@ = where to put the word
208 * Returns: Zero if OK, or nonzero if there wasn't a word there.
210 * Use: Gets a 16-bit word from a buffer.
213 int buf_getu16(buf
*b
, uint16
*w
)
222 /* --- @buf_putu16@ --- *
224 * Arguments: @buf *b@ = pointer to a buffer block
225 * @uint16 w@ = word to write
227 * Returns: Zero if OK, nonzero if there wasn't enough space.
229 * Use: Puts a 16-but word in a buffer.
232 int buf_putu16(buf
*b
, uint16 w
)
241 /* --- @buf_getu32@ --- *
243 * Arguments: @buf *b@ = pointer to a buffer block
244 * @uint32 *w@ = where to put the word
246 * Returns: Zero if OK, or nonzero if there wasn't a word there.
248 * Use: Gets a 32-bit word from a buffer.
251 int buf_getu32(buf
*b
, uint32
*w
)
260 /* --- @buf_putu32@ --- *
262 * Arguments: @buf *b@ = pointer to a buffer block
263 * @uint32 w@ = word to write
265 * Returns: Zero if OK, nonzero if there wasn't enough space.
267 * Use: Puts a 32-but word in a buffer.
270 int buf_putu32(buf
*b
, uint32 w
)
279 /* --- @buf_getmp@ --- *
281 * Arguments: @buf *b@ = pointer to a buffer block
283 * Returns: A multiprecision integer, or null if there wasn't one there.
285 * Use: Gets a multiprecision integer from a buffer.
288 mp
*buf_getmp(buf
*b
)
293 if (buf_getu16(b
, &sz
) || buf_ensure(b
, sz
))
295 m
= mp_loadb(MP_NEW
, BCUR(b
), sz
);
297 if (n
!= sz
&& n
!= 0 && sz
!= 1) {
305 /* --- @buf_putmp@ --- *
307 * Arguments: @buf *b@ = pointer to a buffer block
308 * @mp *m@ = a multiprecision integer
310 * Returns: Zero if it worked, nonzero if there wasn't enough space.
312 * Use: Puts a multiprecision integer to a buffer.
315 int buf_putmp(buf
*b
, mp
*m
)
317 size_t sz
= mp_octets(m
);
320 if (buf_putu16(b
, sz
) || buf_ensure(b
, sz
))
322 mp_storeb(m
, BCUR(b
), sz
);
327 /* --- @buf_getec@ --- *
329 * Arguments: @buf *b@ = pointer to a buffer block
330 * @ec *p@ = where to put the point
332 * Returns: Zero if it worked, nonzero if it failed.
334 * Use: Gets a multiprecision integer from a buffer. The point must
338 int buf_getec(buf
*b
, ec
*p
)
342 if (buf_ensure(b
, 2)) return (-1);
343 n
= LOAD16(BCUR(b
)); if (!n
) { BSTEP(b
, 2); EC_SETINF(p
); return (0); }
344 if ((x
= buf_getmp(b
)) == 0 || (y
= buf_getmp(b
)) == 0) {
345 mp_drop(x
); mp_drop(y
); return (-1);
347 EC_DESTROY(p
); p
->x
= x
; p
->y
= y
; p
->z
= 0;
351 /* --- @buf_putec@ --- *
353 * Arguments: @buf *b@ = pointer to a buffer block
354 * @ec *p@ = an elliptic curve point
356 * Returns: Zero if it worked, nonzero if there wasn't enough space.
358 * Use: Puts an elliptic curve point to a buffer.
361 int buf_putec(buf
*b
, ec
*p
)
363 if (EC_ATINF(p
)) return (buf_putu16(b
, 0));
364 if (buf_putmp(b
, p
->x
) || buf_putmp(b
, p
->y
)) return (-1);
368 /*----- That's all, folks -------------------------------------------------*/