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