]> git.cryptolib.org Git - avr-crypto-lib.git/blob - mqq-sign/mqq160-sign_P-stub.c
fixing E-Mail-Address & Copyright
[avr-crypto-lib.git] / mqq-sign / mqq160-sign_P-stub.c
1 /* mqq160-sign.c */
2 /*
3     This file is part of the AVR-Crypto-Lib.
4     Copyright (C) 2006-2015 Daniel Otte (bg@nerilex.org)
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    C code for MQQ160-SIGN suitable for 8-bit smart cards
21
22    It is supposed that the private key is "engraved" in
23    the ROM of the smart card - thus it is here stored as
24    predefined const arrays in "MQQ160-SIGN-PrivateKey.h"
25
26    Programmed by Danilo Gligoroski, 18 Mar 2010.
27 */
28
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <stdint.h>
33 #include <avr/pgmspace.h>
34 #include "memxor.h"
35 #include "mqq160-sign.h"
36
37 /*
38 This is just for testing purposes.
39 It should be programmed in a more flexible way
40 in the MQQ160-SIGN C Library.
41 */
42
43
44 void mqq_inv_affine_transformation(uint8_t *input_bytes, uint8_t *result, const mqq160_sign_key_t *key);
45 uint8_t mqq_q(uint8_t i, uint8_t b1, uint8_t b2, const mqq160_sign_key_t *key);
46
47
48 #if 0
49 static uint16_t MaskShort[8] = {0x8000, 0x4000, 0x2000, 0x1000, 0x0800, 0x0400, 0x0200, 0x0100};
50
51 static uint8_t mqq_q(uint8_t i, uint8_t b1, uint8_t b2, const mqq160_sign_key_t *key){
52         uint8_t  e[9];
53         uint16_t a[8];
54         uint8_t result, column, row, k;
55         int8_t j;
56         uint16_t temp;
57         uint8_t *tmp_ptr=key->a;
58         if(i&1){
59                 memcpy_P(e, key->cc1, 9);
60                 while(b1){
61                         if(b1&0x80){
62                                 memxor_idx_P((uint8_t*)e, tmp_ptr, 9, 9);
63                         }
64                         tmp_ptr++;
65                         b1 <<= 1;
66                 }
67         }else{
68                 memcpy_P(e, key->cc2, 9);
69                 while(b1){
70                         if(b1&0x80){
71                                 memxor_P((uint8_t*)e, tmp_ptr, 9);
72                         }
73                         tmp_ptr+=9;
74                         b1 <<= 1;
75                 }
76         }
77         /* So we finished with obtaining e0 .. e7 and e8 */
78
79         /* We XOR e[8] with b2 and that will be initial value to transform in order to solve a linear system of equations */
80         result=b2 ^ e[8];
81
82         /*
83            We can look at the bits of e0 .. e7 as a columns of a given matrix. We want to define 8 variables that have the rows
84            of that matrix. The variables need to be 16-bit because we will put into the upper 8 bits the bits of e0 .. e7,
85            and the bits of the variable result will be the Least Significant Bits of a[0] ... a[7].
86    */
87         for(j=0; j<8; ++j){
88                 row = 0;
89                 for(k=0; k<8; ++k){
90                         row |= (e[k]&0x80)>>(k);
91                         e[k]<<=1;
92                 }
93                 a[j]=(((uint16_t)row)<<8) | (result>>7);
94                 result <<= 1;
95         }
96
97         /* Now we finally realize Gausian elimination */
98
99         /* First we apply upper triangular transformation */
100         for(column=0; column<8; column++)
101         {
102                 row=column;
103                 while ((a[row] & MaskShort[column]) == 0){
104                         row++;
105                 }
106                 if(row>column)
107                 {
108                         temp=a[column];
109                         a[column]=a[row];
110                         a[row]=temp;
111                 }
112                 for (j=column+1; j<8; j++)
113                         if ((a[j]&MaskShort[column]) !=0)
114                                 a[j] ^= a[column];
115         }
116
117         /* Then we eliminate 1s above the main diagonal */
118         for (column=7; column>0; column--){
119                 for (j=column-1; j>=0; j--){
120                         if ((a[j]&MaskShort[column]) !=0){
121                                 a[j] ^= a[column];
122                         }
123                 }
124         }
125         /* The result is in the Least Significant Bits of a[0] ... a[7] */
126         result = 0;
127         for(j=0; j<8; ++j){
128                 result <<=1;
129                 result |= a[j]&1;
130         }
131         return(result);
132 }
133
134 #endif
135
136 void mqq160_sign_P(void *dest, const void *hash, const mqq160_sign_key_t *key_P){
137         uint8_t i, r1[20], byteindex;
138         mqq160_sign_key_t key;
139
140         memcpy_P(&key, key_P, sizeof(mqq160_sign_key_t));
141
142         mqq_inv_affine_transformation((uint8_t*)hash, (uint8_t*)dest, &key);
143         r1[0]=((uint8_t*)dest)[0];
144         for(i=1; i<20; ++i){
145                 r1[i] = mqq_q(i, r1[i-1], ((uint8_t*)dest)[i], &key);
146         }
147         /*
148         Affine transformation is just for the second call. The constant is extracted
149         from the 4 LSBs of the first 40 bytes of RP5[] and xor-ed to input_bytes[].
150         */
151         byteindex = 0;
152         for (i=0; i<20; i++){
153                 r1[i] ^=   (uint8_t)(pgm_read_byte(key.rp5+byteindex)<<4)
154                                  | (uint8_t)(pgm_read_byte(key.rp5+byteindex+1)&0x0F);
155                 byteindex += 2;
156         }
157         mqq_inv_affine_transformation(r1, (uint8_t*)dest, &key);
158 }