]> git.cryptolib.org Git - avr-crypto-lib.git/blob - mqq-sign/mqq160-sign_P-asm.S
global style change (now * is attached to identifier not to type)
[avr-crypto-lib.git] / mqq-sign / mqq160-sign_P-asm.S
1 /* mqq160-sign_P-asm.S */
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  * \file     mqq160-sign_P-asm.S
21  * \email    daniel.otte@rub.de
22  * \author   Daniel Otte
23  * \date     2010-03-21
24  * \license  GPLv3 or later
25  *
26  */
27
28 #include "avr-asm-macros.S"
29
30 #if 0
31 static void mqq_inv_affine_transformation(uint8_t *input_bytes, uint8_t *result, const mqq160_sign_key_t *key){
32         /* The matrix SInv is given as two permutations of 160 elements. */
33         uint8_t j, byteindex, bitindex, bitindex_d, byteindex_d, rp1, rp5;
34         uint8_t *r1_ptr, *r5_ptr;
35         uint8_t h1[20];
36
37         /* Initialize H1 and H2 = 0 */
38         memset(h1, 0, 20);
39         memset(result, 0, 20);
40
41         /*
42            Fill H1 with bits of InputBytes accordingly to RP1 permutation
43            and fill H2 with bits of InputBytes accordingly to RP5 permutation
44         */
45         bitindex_d = 0x80;
46         byteindex_d = 0;
47         j=160;
48         r1_ptr = key->rp1;
49         r5_ptr = key->rp5;
50         do{
51                 rp1 = pgm_read_byte(r1_ptr++);
52                 rp5 = pgm_read_byte(r5_ptr++);
53                 byteindex = rp1>>3;
54                 bitindex = 0x80 >> (rp1&0x07);
55                 if (input_bytes[byteindex] & bitindex){
56                         h1[byteindex_d] ^= bitindex_d;
57                 }
58
59                 byteindex = rp5>>3;
60                 bitindex = 0x80 >> (rp5&0x07);
61                 if (input_bytes[byteindex] & bitindex){
62                         result[byteindex_d] ^= bitindex_d;
63                 }
64                 bitindex_d >>= 1;
65                 if(bitindex_d==0){
66                         ++byteindex_d;
67                         bitindex_d = 0x80;
68                 }
69         }while(--j);
70
71         for (j=0; j<20; j++){
72                 result[j] ^= h1[j] ^ h1[pgm_read_byte(j+mod20_table)]
73                                    ^ h1[pgm_read_byte(8+j+mod20_table)]
74                                    ^ h1[pgm_read_byte(12+j+mod20_table)];
75         }
76 }
77 #endif
78
79 fetch_bit:
80         lpm r0, Z+
81         mov r28, r0
82         ldi r29, 0x80
83         andi r28, 7
84         breq 3f
85 2:      lsr r29
86         dec r28
87         brne 2b
88 3:      mov r28, r0
89         lsr r28
90         lsr r28
91         lsr r28
92         mov r0, r29
93         clr r29
94         add r28, r24
95         adc r29, r25
96         ld r28, Y
97         clt
98         and r28, r0
99         breq 4f
100         set
101 4:  ret
102
103 xres_0 = 18
104 xres_1 = 19
105 h_0 = 20
106 h_1 = 21
107 xrp5_0 = 22
108 xrp5_1 = 23
109 inp_0 =  24
110 inp_1 =  25
111 tmp_0 =  22
112 tmp_1 =  23
113 tmp_2 =  24
114 tmp_3 =  25
115 tmp_4 =  18
116
117 /*
118  param input_bytes: r24:r25
119  param result:      r22:r23
120  param key:         r20:r21
121 */
122 ;.global mqq_inv_affine_transformation
123 mqq_inv_affine_transformation:
124         push r17
125 ;       push r28
126 ;       push r29
127         stack_alloc 20
128         adiw r30, 1   /* Z points to stack space for h1 */
129         movw r28, r20 /* Y points to the key struct in RAM */
130         movw xres_0, r22
131         movw r26, r30 /* X points to h1[0] */
132         ldd xrp5_0, Y+8 /* load pointer rp5 to xrp5 */
133         ldd xrp5_1, Y+9
134         movw h_0, r30
135         ldd r30, Y+6 /* load pointer to rp1 in Z */
136         ldd r31, Y+7
137         ldi r17, 20
138 20:     rcall fetch_bit
139         bld r1, 7
140         rcall fetch_bit
141         bld r1, 6
142         rcall fetch_bit
143         bld r1, 5
144         rcall fetch_bit
145         bld r1, 4
146         rcall fetch_bit
147         bld r1, 3
148         rcall fetch_bit
149         bld r1, 2
150         rcall fetch_bit
151         bld r1, 1
152         rcall fetch_bit
153         bld r1, 0
154         st X+, r1
155         dec r17
156         brne 20b
157 ;----
158         movw r26, xres_0 /* X points to result */
159         movw r30, xrp5_0
160         ldi r17, 20
161 20:     rcall fetch_bit
162         bld r1, 7
163         rcall fetch_bit
164         bld r1, 6
165         rcall fetch_bit
166         bld r1, 5
167         rcall fetch_bit
168         bld r1, 4
169         rcall fetch_bit
170         bld r1, 3
171         rcall fetch_bit
172         bld r1, 2
173         rcall fetch_bit
174         bld r1, 1
175         rcall fetch_bit
176         bld r1, 0
177         st X+, r1
178         dec r17
179         brne 20b
180         clr r1
181 ; --- now we mix result with h1
182         sbiw r26, 20 /* adjusting X to point at result[0] */
183         movw tmp_2, h_0
184         ldi r30, lo8(affine_mix_lut)
185         ldi r31, hi8(affine_mix_lut)
186         ldi r17, 20
187 30:
188         ld tmp_0, X
189         movw r28, tmp_2
190         ld tmp_1, Y+
191         movw tmp_2, r28
192         eor tmp_0, tmp_1
193         movw r28, h_0
194         lpm r0, Z+
195         mov tmp_4, r0
196         andi tmp_4, 0x0f
197         add r28, tmp_4
198         adc r29, r1
199         ld tmp_1, Y
200         eor tmp_0, tmp_1
201         adiw r28, 4
202         sbrc r0, 7
203         adiw r28, 4
204         ld tmp_1, Y
205         eor tmp_0, tmp_1
206         adiw r28, 4
207         sbrc r0, 6
208         adiw r28, 4
209         ld tmp_1, Y
210         eor tmp_0, tmp_1
211         st X+, tmp_0
212         dec r17
213         brne 30b
214
215         stack_free 20
216 ;       pop r29
217 ;       pop r28
218         pop r17
219         ret
220
221 affine_mix_lut:
222         .byte 0x84, 0x85, 0x86, 0x87
223         .byte 0xC0, 0xC1, 0xC2, 0xC3
224         .byte 0x40, 0x41, 0x42, 0x43
225         .byte 0x44, 0x45, 0x46, 0x47
226         .byte 0x80, 0x81, 0x82, 0x83
227
228 /******************************************************************************/
229
230 xres  = 20
231 tmp_0 = 23
232 tmp_1 = 22
233 tmp_2 = 21
234 tmp_3 = 19
235 /*
236   param i:    r24
237   param b1:   r22
238   param b2:   r20
239   param key:  r18:r19
240 */
241 ;.global mqq_q
242 mqq_q:
243 ;       push r28
244 ;       push r29
245 ;       stack_alloc 25, r26, r27
246 ;       adiw r26, 1  /* X points to e[0] */
247         movw r28, r18
248         sbrs r24, 0
249         adiw r28, 2
250         ldd r30, Y+2
251         ldd r31, Y+3
252         ldi r28, 9
253 10:     lpm r0, Z+
254         st X+, r0
255         dec r28
256         brne 10b
257         sbiw r26, 9 /* adjust X to point at e[0] */
258 ;---
259         movw r28, r18
260         ld r30, Y+ /* Z points to a[0] in progmem */
261         ld r31, Y
262         sbrs r24, 0
263         rjmp 40f
264 20:
265         sbrs r22, 7
266         rjmp 30f
267         ldi r25, 9
268         movw r28, r30
269 25:     lpm r0, Z
270     adiw r30, 9
271     ld r24, X
272         eor r24, r0
273         st X+, r24
274         dec r25
275         brne 25b
276         movw r30, r28
277         sbiw r26, 9
278 30:
279         adiw r30, 1
280         lsl r22
281         breq 60f
282         rjmp 20b
283 40:
284         sbrs r22, 7
285         rjmp 50f
286         ldi r25, 9
287         movw r28, r30
288 45:     lpm r0, Z+
289     ld r24, X
290         eor r24, r0
291         st X+, r24
292         dec r25
293         brne 45b
294         movw r30, r28
295         sbiw r26, 9
296 50:
297         adiw r30, 9
298         lsl r22
299         breq 60f
300         rjmp 40b
301 60:
302 ;------ all inputs are consumed, X points at e[0]
303 ;------ So we finished with obtaining e0 .. e7 and e8
304         movw r28, r26
305         ldd r0, Y+8
306         eor xres, r0
307 ;---
308
309 /*
310    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
311    of that matrix. The variables need to be 16-bit because we will put into the upper 8 bits the bits of e0 .. e7,
312    and the bits of the variable result will be the Least Significant Bits of a[0] ... a[7].
313 */
314         adiw r28, 9 /* Y points at a[0] */
315         ldi r25, 8
316 63:
317         ldi r24, 8
318         clr tmp_0
319 65:     ld tmp_1, X
320         lsl tmp_1
321         st X+, tmp_1
322         rol tmp_0
323         dec r24
324         brne 65b
325 ;---
326         clr tmp_1
327         lsl xres
328         rol tmp_1
329         st Y+, tmp_1
330         st Y+, tmp_0
331         sbiw r26, 8
332         dec r25
333         brne 63b
334 ;------- First we apply upper triangular transformation
335         sbiw r28, 16  /* Y points at a[0] */
336         movw r30, r28 /* Z points at a[0] */
337
338 col = 25
339         ldi r24, 8
340         clr col
341 70:
342         mov r1, col
343         ldi tmp_3, 0x80
344         tst r1
345         breq 72f
346 71:     lsr tmp_3
347         dec r1
348         brne 71b
349 72:
350         clt
351         movw r28, r30 /* Y points at a[row]*/
352 73:     ldd tmp_0, Y+1
353         and tmp_0, tmp_3
354         brne 74f
355         set
356         adiw r28, 2
357         rjmp 73b
358 74:
359     /* Y points at a[row] */
360         /* if T is set we have to permute [Y] and [Z] */
361         brtc 75f
362         ld tmp_0, Y
363         ld tmp_1, Z
364         st Y, tmp_1
365         st Z, tmp_0
366         ldd tmp_0, Y+1
367         ldd tmp_1, Z+1
368         std Y+1, tmp_1
369         std Z+1, tmp_0
370 75: /* permutation done */
371         ldi r26, 7
372         sub r26, col
373         breq 78f
374         movw r28, r30
375 76:     adiw r28, 2
376         ldd tmp_0, Y+1
377         and tmp_0, tmp_3
378         breq 77f
379         ld tmp_0, Y
380         ld tmp_1, Z
381         eor tmp_0, tmp_1
382         st Y, tmp_0
383         ldd tmp_0, Y+1
384         ldd tmp_1, Z+1
385         eor tmp_0, tmp_1
386         std Y+1, tmp_0
387 77:
388         dec r26
389         brne 76b
390 78:
391         adiw r30, 2
392         inc col
393         dec r24
394         brne 70b
395 79:
396 ;------ Then we eliminate 1s above the main diagonal
397
398         ldi col, 7
399         ldi tmp_3, 1
400         sbiw r30, 2
401 80:
402         movw r28, r30
403         mov r26, col
404 81:
405         sbiw r28, 2
406         ldd tmp_0, Y+1
407         and tmp_0, tmp_3
408         breq 82f
409         ld tmp_0, Y
410         ld tmp_1, Z
411         eor tmp_0, tmp_1
412         st Y, tmp_0
413         ldd tmp_0, Y+1
414         ldd tmp_1, Z+1
415         eor tmp_0, tmp_1
416         std Y+1, tmp_0
417 82:
418         dec r26
419         brne 81b
420         sbiw r30, 2
421         lsl tmp_3
422         dec col
423         brne 80b
424 89:
425 ;------ The result is in the Least Significant Bits of a[0] ... a[7]
426         /* Z should point at a[0] */
427         ldi r25, 8
428         clr r24
429 90:
430         ld tmp_0, Z
431         adiw r30, 2
432         lsr tmp_0
433         rol r24
434         dec r25
435         brne 90b
436 mqq_q_exit:
437 ;       stack_free 25
438 ;       pop r29
439 ;       pop r28
440         ret
441
442 /******************************************************************************/
443
444 /*
445   param dest:  r24:r25
446   param hash:  r22:r23
447   param key:   r20:r21
448 */
449
450 dest_0 =  2
451 dest_1 =  3
452 xr1_0  =  4
453 xr1_1  =  5
454 key_0  =  6
455 key_1  =  7
456 i      =  8
457 c      =  9
458 qstack_0 = 10
459 qstack_1 = 11
460
461 .global mqq160_sign_P
462 mqq160_sign_P:
463         push_range 2, 11
464         push_range 28, 29
465         stack_alloc 10+20, r26, r27  /* r1[20] + key */
466         adiw r26, 1 /* X points to stack memory */
467         movw key_0, r26
468         /* load key structure */
469         movw r30, r20
470         ldi r18, 10
471 10:     lpm r0, Z+
472         st X+, r0
473         dec r18
474         brne 10b
475         movw xr1_0, r26
476         movw dest_0, r24
477         /* call to mqq_inv_affine_transformation(hash, dest, &key); */
478         movw r24, r22
479         movw r22, dest_0
480         movw r20, key_0
481         rcall mqq_inv_affine_transformation
482         /* r1[0]=((uint8_t*)dest)[0]; */
483
484         movw r26, dest_0
485         movw r30, xr1_0
486         ld r0, X
487         st Z, r0
488 ;----
489         ldi r18, 19
490         mov c, r18
491         clr i
492         inc i
493         stack_alloc 25, r28, r29
494         adiw r28, 1
495         movw qstack_0, r28
496 20:     mov r24, i
497         movw r26, xr1_0
498         add r26, i
499         adc r27, r1
500         sbiw r26, 1
501         ld r22, X
502         movw r26, dest_0
503         add r26, i
504         adc r27, r1
505         ld r20, X
506         movw r18, key_0
507         movw r26, qstack_0
508         rcall mqq_q
509         movw r26, xr1_0
510         add r26, i
511         adc r27, r1
512         st X, r24
513         inc i
514         dec c
515         brne 20b
516         stack_free 25
517 ;-----
518
519
520         movw r28, key_0
521         ldd r30, Y+8
522         ldd r31, Y+9
523         movw r26, xr1_0
524         ldi r18, 20
525 30: lpm r20, Z+
526         swap r20
527         andi r20, 0xF0
528         lpm r21, Z+
529         andi r21, 0x0F
530         or r20, r21
531         ld r21, X
532         eor r21, r20
533         st X+, r21
534         dec r18
535         brne 30b
536 ;----
537
538         movw r24, xr1_0
539         movw r22, dest_0
540         movw r20, key_0
541         rcall mqq_inv_affine_transformation
542         stack_free 30
543         pop_range 28, 29
544         pop_range 2, 11
545         ret
546
547