chiark / gitweb /
Add some more vectors, and a whinge about how Skipjack test vectors are.
[catacomb] / mpscan.h
1 /* -*-c-*-
2  *
3  * $Id: mpscan.h,v 1.4 2000/07/29 17:03:31 mdw Exp $
4  *
5  * Sequential bit scan of multiprecision integers
6  *
7  * (c) 1999 Straylight/Edgeware
8  */
9
10 /*----- Licensing notice --------------------------------------------------* 
11  *
12  * This file is part of Catacomb.
13  *
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.
18  * 
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.
23  * 
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,
27  * MA 02111-1307, USA.
28  */
29
30 /*----- Revision history --------------------------------------------------* 
31  *
32  * $Log: mpscan.h,v $
33  * Revision 1.4  2000/07/29 17:03:31  mdw
34  * Add support for left-to-right bitscanning, for use in modular
35  * exponentiation.
36  *
37  * Revision 1.3  1999/12/10 23:29:48  mdw
38  * Change header file guard names.
39  *
40  * Revision 1.2  1999/11/13 01:55:10  mdw
41  * Fixed so that they compile.  Minor interface changes.
42  *
43  * Revision 1.1  1999/09/03 08:41:12  mdw
44  * Initial import.
45  *
46  */
47
48 #ifndef CATACOMB_MPSCAN_H
49 #define CATACOMB_MPSCAN_H
50
51 #ifdef __cplusplus
52   extern "C" {
53 #endif
54
55 /*----- Header files ------------------------------------------------------*/
56
57 #ifndef CATACOMB_MPW_H
58 #  include "mpw.h"
59 #endif
60
61 /*----- Data structures ---------------------------------------------------*/
62
63 typedef struct mpscan {
64   const mpw *v, *vl;                    /* Vector of words to scan */
65   mpw w;                                /* Current word to scan */
66   int bits;                             /* Number of bits left in @w@ */
67 } mpscan;
68
69 /*----- Right-to-left scanning --------------------------------------------*/
70
71 /* --- @mpscan_initx@ --- *
72  *
73  * Arguments:   @mpscan *m@ = pointer to bitscanner structure
74  *              @const mpw *v, *vl@ = vector of words to scan
75  *
76  * Returns:     ---
77  *
78  * Use:         Initializes a bitscanner from a low-level base-and-limit
79  *              representation of an integer.  Initially no bit is ready; you
80  *              must call @mpscan_step@ before anything useful will come
81  *              out.
82  */
83
84 #define MPSCAN_INITX(m_, v_, vl_) do {                                  \
85   mpscan *_m = (m_);                                                    \
86   _m->v = (v_);                                                         \
87   _m->vl = (vl_);                                                       \
88   _m->bits = 0;                                                         \
89 } while (0)
90
91 extern void mpscan_initx(mpscan */*m*/, const mpw */*v*/, const mpw */*vl*/);
92
93 /* --- @mpscan_step@ --- *
94  *
95  * Arguments:   @mpscan *m@ = pointer to bitscanner
96  *
97  * Returns:     Nonzero if there is another bit to read.
98  *
99  * Use:         Steps on to the next bit in the integer.  The macro version
100  *              evaluates its argument multiple times.
101  */
102
103 #define MPSCAN_STEP(m)                                                  \
104   ((m)->bits ? ((m)->w >>= 1, (m)->bits--, 1) :                         \
105    (m)->v < (m)->vl ? ((m)->w = *(m)->v++,                              \
106                        (m)->bits = MPW_BITS - 1, 1) :                   \
107    0)
108
109 extern int mpscan_step(mpscan */*m*/);
110
111 /* --- @mpscan_bit@ --- *
112  *
113  * Arguments:   @const mpscan *m@ = pointer to bitscanner
114  *
115  * Returns:     The value of the current bit.
116  *
117  * Use:         Reads the value of the current bit looked at by a
118  *              bitscanner.
119  */
120
121 #define MPSCAN_BIT(m) ((m)->w & 1)
122
123 extern int mpscan_bit(const mpscan */*m*/);
124
125 /*----- Left-to right-scanning --------------------------------------------*/
126
127 /* --- @mpscan_rinitx@ --- *
128  *
129  * Arguments:   @mpscan *m@ = pointer to bitscanner structure
130  *              @const mpw *v, *vl@ = vector of words to scan
131  *
132  * Returns:     ---
133  *
134  * Use:         Initializes a reverse bitscanner from a low-level
135  *              vector-and-length representation of an integer.  Initially no
136  *              bit is ready; you must call @mpscan_rstep@ before anything
137  *              useful will come out.
138  */
139
140 #define MPSCAN_RINITX(m_, v_, vl_) do {                                 \
141   mpscan *_m = (m_);                                                    \
142   _m->v = (v_);                                                         \
143   _m->vl = (vl_);                                                       \
144   while (_m->vl > _m->v && !_m->vl[-1])                                 \
145     _m->vl--;                                                           \
146   _m->bits = 0;                                                         \
147 } while (0)
148
149 extern void mpscan_rinitx(mpscan */*m*/,
150                           const mpw */*v*/, const mpw */*vl*/);
151
152 /* --- @mpscan_rstep@ --- *
153  *
154  * Arguments:   @mpscan *m@ = pointer to bitscanner
155  *
156  * Returns:     Nonzero if there is another bit to read.
157  *
158  * Use:         Steps on to the next bit in the integer.  The macro version
159  *              evaluates its argument multiple times.
160  */
161
162 #define MPSCAN_RSTEP(m)                                                 \
163   ((m)->bits ? ((m)->w <<= 1, (m)->bits--, 1) :                         \
164    (m)->vl > (m)->v ? ((m)->w = *--(m)->vl,                             \
165                        (m)->bits = MPW_BITS - 1, 1) :                   \
166    0)
167
168 extern int mpscan_rstep(mpscan */*m*/);
169
170 /* --- @mpscan_rbit@ --- *
171  *
172  * Arguments:   @const mpscan *m@ = pointer to bitscanner
173  *
174  * Returns:     The value of the current bit.
175  *
176  * Use:         Reads the value of the current bit looked at by a
177  *              reverse bitscanner.
178  */
179
180 #define MPSCAN_RBIT(m) (((m)->w >> (MPW_BITS - 1)) & 1)
181
182 extern int mpscan_rbit(const mpscan */*m*/);
183
184 /*----- That's all, folks -------------------------------------------------*/
185
186 #ifdef __cplusplus
187   }
188 #endif
189
190 #endif