8626032a0974ef25384053a4782ad8d5dcb95a27
[gnupg.git] / mpi / mpi-scan.c
1 /* mpi-scan.c  -  MPI functions
2  *      Copyright (c) 1997 by Werner Koch (dd9jn)
3  *
4  * This file is part of G10.
5  *
6  * G10 is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * G10 is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19  */
20
21 #include <config.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include "mpi-internal.h"
25
26 /****************
27  * Scan through an mpi and return byte for byte. a -1 is returned to indicate
28  * the end of the mpi. Scanning is done from the lsb to the msb, returned
29  * values are in the range of 0 .. 255.
30  *
31  * FIXME: This code is VERY ugly!
32  */
33 int
34 mpi_getbyte( MPI a, unsigned index )
35 {
36     int i, j;
37     unsigned n;
38     mpi_ptr_t ap;
39     mpi_limb_t limb;
40
41     ap = a->d;
42     for(n=0,i=0; i < a->nlimbs; i++ ) {
43         limb = ap[i];
44         for( j=0; j < BYTES_PER_MPI_LIMB; j++, n++ )
45             if( n == index )
46                 return (limb >> j*8) & 0xff;
47     }
48     return -1;
49 }
50
51
52 /****************
53  * Put a value at position INDEX into A. index counts from lsb to msb
54  */
55 void
56 mpi_putbyte( MPI a, unsigned index, int c )
57 {
58     int i, j;
59     unsigned n;
60     mpi_ptr_t ap;
61     mpi_limb_t limb;
62
63 #if BYTES_PER_MPI_LIMB != 4
64   #error please enhance this function, its ugly - i know.
65 #endif
66     c &= 0xff;
67     ap = a->d;
68     for(n=0,i=0; i < a->alloced; i++ ) {
69         limb = ap[i];
70         for( j=0; j < BYTES_PER_MPI_LIMB; j++, n++ )
71             if( n == index ) {
72                 if( j == 0 )
73                     limb = (limb & 0xffffff00) | c;
74                 else if( j == 1 )
75                     limb = (limb & 0xffff00ff) | (c<<8);
76                 else if( j == 2 )
77                     limb = (limb & 0xff00ffff) | (c<<16);
78                 else
79                     limb = (limb & 0x00ffffff) | (c<<24);
80                 if( a->nlimbs <= i )
81                     a->nlimbs = i+1;
82                 ap[i] = limb;
83                 return;
84             }
85     }
86     abort(); /* index out of range */
87 }
88