]> git.cryptolib.org Git - avr-crypto-lib.git/blob - bigint/bigint_io.c
initial part of bigint-library; some bugs left
[avr-crypto-lib.git] / bigint / bigint_io.c
1 /* bigint_io.c */
2 /*
3     This file is part of the AVR-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 "bigint.h"
22 #include <stdlib.h>
23 #include <string.h>
24
25 void bigint_print_hex(const bigint_t* a){
26         if(a->info&BIGINT_NEG_MASK){
27                 cli_putc('-');
28         }
29 //      cli_putc((a->info&BIGINT_NEG_MASK)?'-':'+'); /* print sign */
30         if(a->length_B!=0){
31                 cli_hexdump_rev(a->wordv, a->length_B);
32         }else{
33                 cli_putc('0');
34         }
35 }
36
37 #define BLOCKSIZE 20
38
39 static uint8_t char2nibble(char c){
40         if(c>='0' && c <='9'){
41                 return c-'0';
42         }
43         c |= 'A'^'a'; /* to lower case */
44         if(c>='a' && c <='f'){
45                 return c-'a'+10;
46         }
47         return 0xff;
48 }
49
50 static uint16_t read_byte(void){
51         uint8_t t1, t2;
52         char c;
53         c = cli_getc_cecho();
54         if(c=='-'){
55                 return 0x0500;
56         }
57         t1 = char2nibble(c);
58         if(t1 == 0xff){
59                 return 0x0100;
60         }
61         c = cli_getc_cecho();
62         t2 = char2nibble(c);
63         if(t2 == 0xff){
64                 return 0x0200|t1;
65         }
66         return (t1<<4)|t2;
67 }
68
69 uint8_t bigint_read_hex_echo(bigint_t* a){
70         uint16_t allocated=0;
71         uint8_t  shift4=0;
72         uint16_t  t;
73         a->length_B = 0;
74         a->wordv = NULL;
75         a->info = 0;
76         for(;;){
77                 if(allocated-a->length_B < 1){
78                         uint8_t *p;
79                         p = realloc(a->wordv, allocated+=BLOCKSIZE);
80                         if(p==NULL){
81                                 cli_putstr_P(PSTR("\r\nERROR: Out of memory!"));
82                                 free(a->wordv);
83                                 return 0xff;
84                         }
85                         a->wordv=p;
86                 }
87                 t = read_byte();
88                 if(a->length_B==0){
89                         if(t&0x0400){
90                                 /* got minus */
91                                 a->info |= BIGINT_NEG_MASK;
92                                 continue;
93                         }else{
94                                 if(t==0x0100){
95                                         free(a->wordv);
96                                         a->wordv=NULL;
97                                         return 1;
98                                 }
99                         }
100                 }
101                 if(t<=0x00ff){
102                         a->wordv[a->length_B++] = (uint8_t)t;
103                 }else{
104                         if(t&0x0200){
105                                 shift4 = 1;
106                                 a->wordv[a->length_B++] = (uint8_t)((t&0x0f)<<4);
107                         }
108                         break;
109                 }
110         }
111         /* we have to reverse the byte array */
112         uint8_t tmp;
113         uint8_t *p, *q;
114         p = a->wordv;
115         q = a->wordv+a->length_B-1;
116         while(q>p){
117                 tmp = *p;
118                 *p = *q;
119                 *q = tmp;
120                 p++; q--;
121         }
122         if(shift4){
123                 bigint_adjust(a);
124                 bigint_shiftright(a, 4);
125         }
126         bigint_adjust(a);
127         return 0;
128 }