]> git.cryptolib.org Git - arm-crypto-lib.git/blob - bigint/bigint_io.c
switching to packed structure
[arm-crypto-lib.git] / bigint / bigint_io.c
1 /* bigint_io.c */
2 /*
3     This file is part of the ARM-Crypto-Lib.
4     Copyright (C) 2010 Daniel Otte (daniel.otte@rub.de)
5
6     This program 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 3 of the License, or
9     (at your option) any later version.
10
11     This program 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, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "cli.h"
21 #include "hexdigit_tab.h"
22 #include "bigint.h"
23 #include <stdlib.h>
24 #include <string.h>
25
26 void bigint_print_hex(const bigint_t* a){
27         if(a->length_W==0){
28                 cli_putc('0');
29                 return;
30         }
31         if(a->info&BIGINT_NEG_MASK){
32                 cli_putc('-');
33         }
34 //      cli_putc((a->info&BIGINT_NEG_MASK)?'-':'+'); /* print sign */
35 /*      if(a->wordv[a->length_W-1]<0x10){
36                 cli_putc(hexdigit_tab_uc[a->wordv[a->length_W-1]]);
37                 cli_hexdump_rev(a->wordv, a->length_W-1);
38         } else {
39 */
40         //      cli_hexdump_rev(a->wordv, a->length_W*sizeof(bigint_word_t));
41 //      }
42         uint32_t idx;
43         uint8_t print_zero=0;
44         uint8_t *p,x,y;
45         p = (uint8_t*)&(a->wordv[a->length_W-1])+sizeof(bigint_word_t)-1;
46         for(idx = a->length_W * sizeof(bigint_word_t); idx > 0; --idx){
47                 x = *p >> 4;
48                 y = *p & 0xf;
49                 if(x!=0 || print_zero!=0){
50                         cli_putc(hexdigit_tab_lc[x]);
51                 }
52                 if(x){
53                         print_zero = 1;
54                 }
55                 if(y!=0 || print_zero!=0){
56                         cli_putc(hexdigit_tab_lc[y]);
57                 }
58                 if(y){
59                         print_zero = 1;
60                 }
61                 --p;
62         }
63 }
64
65 #define BLOCKSIZE 32
66
67 static uint8_t char2nibble(char c){
68         if(c>='0' && c <='9'){
69                 return c-'0';
70         }
71         c |= 'A'^'a'; /* to lower case */
72         if(c>='a' && c <='f'){
73                 return c-'a'+10;
74         }
75         return 0xff;
76 }
77
78 static uint16_t read_byte(void){
79         uint8_t t1, t2;
80         char c;
81         c = cli_getc_cecho();
82         if(c=='-'){
83                 return 0x0500;
84         }
85         t1 = char2nibble(c);
86         if(t1 == 0xff){
87                 return 0x0100;
88         }
89         c = cli_getc_cecho();
90         t2 = char2nibble(c);
91         if(t2 == 0xff){
92                 return 0x0200|t1;
93         }
94         return (t1<<4)|t2;
95 }
96
97 uint8_t bigint_read_hex_echo(bigint_t* a){
98         uint16_t allocated=0;
99         uint8_t  shift4=0;
100         uint16_t  t, idx = 0;
101         a->length_W = 0;
102         a->wordv = NULL;
103         a->info = 0;
104         for(;;){
105                 if(allocated - idx < 1){
106                         bigint_word_t *p;
107                         p = realloc(a->wordv, allocated += BLOCKSIZE);
108                         if(p==NULL){
109                                 cli_putstr("\r\nERROR: Out of memory!");
110                                 free(a->wordv);
111                                 return 0xff;
112                         }
113                         memset((uint8_t*)p + allocated - BLOCKSIZE, 0, BLOCKSIZE);
114                         a->wordv=p;
115                 }
116                 t = read_byte();
117                 if(idx==0){
118                         if(t&0x0400){
119                                 /* got minus */
120                                 a->info |= BIGINT_NEG_MASK;
121                                 continue;
122                         }else{
123                                 if(t==0x0100){
124                                         free(a->wordv);
125                                         a->wordv=NULL;
126                                         return 1;
127                                 }
128                         }
129                 }
130                 if(t<=0x00ff){
131                         ((uint8_t*)(a->wordv))[idx++] = (uint8_t)t;
132                 }else{
133                         if(t&0x0200){
134                                 shift4 = 1;
135                                 ((uint8_t*)(a->wordv))[idx++] = (uint8_t)((t&0x0f)<<4);
136                         }
137                         break;
138                 }
139         }
140         /* we have to reverse the byte array */
141         uint8_t tmp;
142         uint8_t *p, *q;
143         a->length_W = (idx + sizeof(bigint_word_t)-1)/sizeof(bigint_word_t);
144         p = (uint8_t*)(a->wordv);
145         q = (uint8_t*)a->wordv + idx - 1;
146         while(q>p){
147                 tmp = *p;
148                 *p = *q;
149                 *q = tmp;
150                 p++; q--;
151         }
152         bigint_adjust(a);
153         if(shift4){
154                 bigint_shiftright(a, 4);
155         }
156         return 0;
157 }