]> git.cryptolib.org Git - arm-crypto-lib.git/blobdiff - bigint/bigint_io.c
starting to make bigint more portable/32-bit efficient
[arm-crypto-lib.git] / bigint / bigint_io.c
diff --git a/bigint/bigint_io.c b/bigint/bigint_io.c
new file mode 100644 (file)
index 0000000..d0dde86
--- /dev/null
@@ -0,0 +1,159 @@
+/* bigint_io.c */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2010 Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "cli.h"
+#include "hexdigit_tab.h"
+#include "bigint.h"
+#include <stdlib.h>
+#include <string.h>
+
+void bigint_print_hex(const bigint_t* a){
+       if(a->length_B==0){
+               cli_putc('0');
+               return;
+       }
+       if(a->info&BIGINT_NEG_MASK){
+               cli_putc('-');
+       }
+//     cli_putc((a->info&BIGINT_NEG_MASK)?'-':'+'); /* print sign */
+/*     if(a->wordv[a->length_B-1]<0x10){
+               cli_putc(hexdigit_tab_uc[a->wordv[a->length_B-1]]);
+               cli_hexdump_rev(a->wordv, a->length_B-1);
+       } else {
+*/
+       //      cli_hexdump_rev(a->wordv, a->length_B*sizeof(bigint_word_t));
+//     }
+       uint32_t idx;
+       uint8_t print_zero=0;
+       uint8_t *p,x,y;
+       p = (uint8_t*)&(a->wordv[a->length_B-1])+sizeof(bigint_word_t)-1;
+       for(idx=a->length_B*sizeof(bigint_word_t); idx>0; --idx){
+               x = *p >> 4;
+               y = *p & 0xf;
+               if(x!=0 || print_zero!=0){
+                       cli_putc(hexdigit_tab_lc[x]);
+               }
+               if(x){
+                       print_zero = 1;
+               }
+               if(y!=0 || print_zero!=0){
+                       cli_putc(hexdigit_tab_lc[y]);
+               }
+               if(y){
+                       print_zero = 1;
+               }
+               --p;
+       }
+}
+
+#define BLOCKSIZE 32
+
+static uint8_t char2nibble(char c){
+       if(c>='0' && c <='9'){
+               return c-'0';
+       }
+       c |= 'A'^'a'; /* to lower case */
+       if(c>='a' && c <='f'){
+               return c-'a'+10;
+       }
+       return 0xff;
+}
+
+static uint16_t read_byte(void){
+       uint8_t t1, t2;
+       char c;
+       c = cli_getc_cecho();
+       if(c=='-'){
+               return 0x0500;
+       }
+       t1 = char2nibble(c);
+       if(t1 == 0xff){
+               return 0x0100;
+       }
+       c = cli_getc_cecho();
+       t2 = char2nibble(c);
+       if(t2 == 0xff){
+               return 0x0200|t1;
+       }
+       return (t1<<4)|t2;
+}
+
+uint8_t bigint_read_hex_echo(bigint_t* a){
+       uint16_t allocated=0;
+       uint8_t  shift4=0;
+       uint16_t  t;
+       a->length_B = 0;
+       a->wordv = NULL;
+       a->info = 0;
+       for(;;){
+               if(allocated-a->length_B < 1){
+                       bigint_word_t *p;
+                       p = realloc(a->wordv, allocated+=BLOCKSIZE);
+                       if(p==NULL){
+                               cli_putstr("\r\nERROR: Out of memory!");
+                               free(a->wordv);
+                               return 0xff;
+                       }
+                       memset((uint8_t*)p+allocated-BLOCKSIZE, 0, BLOCKSIZE);
+                       a->wordv=p;
+               }
+               t = read_byte();
+               if(a->length_B==0){
+                       if(t&0x0400){
+                               /* got minus */
+                               a->info |= BIGINT_NEG_MASK;
+                               continue;
+                       }else{
+                               if(t==0x0100){
+                                       free(a->wordv);
+                                       a->wordv=NULL;
+                                       return 1;
+                               }
+                       }
+               }
+               if(t<=0x00ff){
+                       ((uint8_t*)(a->wordv))[a->length_B++] = (uint8_t)t;
+               }else{
+                       if(t&0x0200){
+                               shift4 = 1;
+                               ((uint8_t*)(a->wordv))[a->length_B++] = (uint8_t)((t&0x0f)<<4);
+                       }
+                       break;
+               }
+       }
+       /* we have to reverse the byte array */
+       uint8_t tmp;
+       uint8_t *p, *q;
+       p = (uint8_t*)(a->wordv);
+       q = (uint8_t*)a->wordv+a->length_B-1;
+       while(q>p){
+               tmp = *p;
+               *p = *q;
+               *q = tmp;
+               p++; q--;
+       }
+       a->length_B = (a->length_B+sizeof(bigint_word_t)-1)/sizeof(bigint_word_t);
+       if(shift4){
+               bigint_adjust(a);
+               bigint_shiftright(a, 4);
+       }else{
+               bigint_adjust(a);
+       }
+       return 0;
+}