X-Git-Url: https://git.cryptolib.org/?a=blobdiff_plain;f=mqq-sign%2Fmqq160-sign_P-stub.c;fp=mqq-sign%2Fmqq160-sign_P-stub.c;h=d8c889f68ceea0868642b45e1721148492c66f2f;hb=056b130e8185a29017a3f3feb0b7db4e84080b09;hp=0000000000000000000000000000000000000000;hpb=c9c11514d91b8c19f77d65ac051b998bd99048b0;p=avr-crypto-lib.git diff --git a/mqq-sign/mqq160-sign_P-stub.c b/mqq-sign/mqq160-sign_P-stub.c new file mode 100644 index 0000000..d8c889f --- /dev/null +++ b/mqq-sign/mqq160-sign_P-stub.c @@ -0,0 +1,158 @@ +/* mqq160-sign.c */ +/* + This file is part of the AVR-Crypto-Lib. + Copyright (C) 2010 Danilo Gligoroski, 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 . +*/ +/* + C code for MQQ160-SIGN suitable for 8-bit smart cards + + It is supposed that the private key is "engraved" in + the ROM of the smart card - thus it is here stored as + predefined const arrays in "MQQ160-SIGN-PrivateKey.h" + + Programmed by Danilo Gligoroski, 18 Mar 2010. +*/ + +#include +#include +#include +#include +#include +#include "memxor.h" +#include "mqq160-sign.h" + +/* +This is just for testing purposes. +It should be programmed in a more flexible way +in the MQQ160-SIGN C Library. +*/ + + +void mqq_inv_affine_transformation(uint8_t* input_bytes, uint8_t* result, const mqq160_sign_key_t* key); +uint8_t mqq_q(uint8_t i, uint8_t b1, uint8_t b2, const mqq160_sign_key_t* key); + + +#if 0 +static uint16_t MaskShort[8] = {0x8000, 0x4000, 0x2000, 0x1000, 0x0800, 0x0400, 0x0200, 0x0100}; + +static uint8_t mqq_q(uint8_t i, uint8_t b1, uint8_t b2, const mqq160_sign_key_t* key){ + uint8_t e[9]; + uint16_t a[8]; + uint8_t result, column, row, k; + int8_t j; + uint16_t temp; + uint8_t *tmp_ptr=key->a; + if(i&1){ + memcpy_P(e, key->cc1, 9); + while(b1){ + if(b1&0x80){ + memxor_idx_P((uint8_t*)e, tmp_ptr, 9, 9); + } + tmp_ptr++; + b1 <<= 1; + } + }else{ + memcpy_P(e, key->cc2, 9); + while(b1){ + if(b1&0x80){ + memxor_P((uint8_t*)e, tmp_ptr, 9); + } + tmp_ptr+=9; + b1 <<= 1; + } + } + /* So we finished with obtaining e0 .. e7 and e8 */ + + /* We XOR e[8] with b2 and that will be initial value to transform in order to solve a linear system of equations */ + result=b2 ^ e[8]; + + /* + 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 + of that matrix. The variables need to be 16-bit because we will put into the upper 8 bits the bits of e0 .. e7, + and the bits of the variable result will be the Least Significant Bits of a[0] ... a[7]. + */ + for(j=0; j<8; ++j){ + row = 0; + for(k=0; k<8; ++k){ + row |= (e[k]&0x80)>>(k); + e[k]<<=1; + } + a[j]=(((uint16_t)row)<<8) | (result>>7); + result <<= 1; + } + + /* Now we finally realize Gausian elimination */ + + /* First we apply upper triangular transformation */ + for(column=0; column<8; column++) + { + row=column; + while ((a[row] & MaskShort[column]) == 0){ + row++; + } + if(row>column) + { + temp=a[column]; + a[column]=a[row]; + a[row]=temp; + } + for (j=column+1; j<8; j++) + if ((a[j]&MaskShort[column]) !=0) + a[j] ^= a[column]; + } + + /* Then we eliminate 1s above the main diagonal */ + for (column=7; column>0; column--){ + for (j=column-1; j>=0; j--){ + if ((a[j]&MaskShort[column]) !=0){ + a[j] ^= a[column]; + } + } + } + /* The result is in the Least Significant Bits of a[0] ... a[7] */ + result = 0; + for(j=0; j<8; ++j){ + result <<=1; + result |= a[j]&1; + } + return(result); +} + +#endif + +void mqq160_sign_P(void* dest, const void* hash, const mqq160_sign_key_t* key_P){ + uint8_t i, r1[20], byteindex; + mqq160_sign_key_t key; + + memcpy_P(&key, key_P, sizeof(mqq160_sign_key_t)); + + mqq_inv_affine_transformation((uint8_t*)hash, (uint8_t*)dest, &key); + r1[0]=((uint8_t*)dest)[0]; + for(i=1; i<20; ++i){ + r1[i] = mqq_q(i, r1[i-1], ((uint8_t*)dest)[i], &key); + } + /* + Affine transformation is just for the second call. The constant is extracted + from the 4 LSBs of the first 40 bytes of RP5[] and xor-ed to input_bytes[]. + */ + byteindex = 0; + for (i=0; i<20; i++){ + r1[i] ^= (uint8_t)(pgm_read_byte(key.rp5+byteindex)<<4) + | (uint8_t)(pgm_read_byte(key.rp5+byteindex+1)&0x0F); + byteindex += 2; + } + mqq_inv_affine_transformation(r1, (uint8_t*)dest, &key); +}