├── .gitignore ├── AES128.c ├── AES128.h ├── AESCCM.c ├── AESCCM.h ├── AESMMO.c ├── AESMMO.h ├── DRNG.c ├── DRNG.h ├── ECCK.c ├── ECCK.h ├── ECDSA.c ├── ECDSA.h ├── GF2n.c ├── GF2n.h ├── GFp.c ├── GFp.h ├── OpenECC.c ├── OpenECC.h ├── README.md ├── TEST163.c └── TEST233.c /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files 2 | *.slo 3 | *.lo 4 | *.o 5 | 6 | # Compiled Dynamic libraries 7 | *.so 8 | 9 | # Compiled Static libraries 10 | *.lai 11 | *.la 12 | *.a 13 | 14 | # Temp files 15 | *~ 16 | *.swp 17 | -------------------------------------------------------------------------------- /AES128.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 Xinxin Fan 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * - Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * - Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in 12 | * the documentation and/or other materials provided with the 13 | * distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 25 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 | * POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #include "OpenECC.h" 30 | #include "AES128.h" 31 | 32 | //load 4 bytes into a 32-bit word 33 | static void LOAD32(uint8 const *y, uint32 *x) { 34 | uint8 *xptr = (uint8 *)x; 35 | 36 | *(xptr ) = *(y + 3); 37 | *(xptr + 1) = *(y + 2); 38 | *(xptr + 2) = *(y + 1); 39 | *(xptr + 3) = *(y ); 40 | } 41 | 42 | //convert a 32-bit word to 4 bytes 43 | static void STORE32(uint32 const x, uint8 *y) { 44 | uint8 *xptr = (uint8 *)&x; 45 | 46 | *(y ) = *(xptr + 3); 47 | *(y + 1) = *(xptr + 2); 48 | *(y + 2) = *(xptr + 1); 49 | *(y + 3) = *(xptr ); 50 | } 51 | 52 | //macros for extracting bytes from a 32-bit word x 53 | #define ROTR(x, n) (((x) >> (n)) | ((x) << (32 - (n)))) 54 | #define byte(x, n) (uint32)((uint8 *)&(x))[(n)] 55 | 56 | //Four look-up tables T_0, T_1, T_2, T_3 57 | //Generate T_1, T_2, T_3 from T_0 by cyclic shifts 58 | #define Te0(x) TE0[x] 59 | #define Te1(x) ROTR(TE0[x], 8) 60 | #define Te2(x) ROTR(TE0[x], 16) 61 | #define Te3(x) ROTR(TE0[x], 24) 62 | 63 | //Extract s-box from the table T_0 64 | #define Te4_0(x) (TE0[x] >> 8) & 0xff 65 | #define Te4_1(x) TE0[x] & 0xff00 66 | #define Te4_2(x) TE0[x] & 0xff0000 67 | #define Te4_3(x) (TE0[x] << 8) & 0xff000000 68 | 69 | static const uint32 TE0[256] = { 70 | 0xc66363a5UL, 0xf87c7c84UL, 0xee777799UL, 0xf67b7b8dUL, 71 | 0xfff2f20dUL, 0xd66b6bbdUL, 0xde6f6fb1UL, 0x91c5c554UL, 72 | 0x60303050UL, 0x02010103UL, 0xce6767a9UL, 0x562b2b7dUL, 73 | 0xe7fefe19UL, 0xb5d7d762UL, 0x4dababe6UL, 0xec76769aUL, 74 | 0x8fcaca45UL, 0x1f82829dUL, 0x89c9c940UL, 0xfa7d7d87UL, 75 | 0xeffafa15UL, 0xb25959ebUL, 0x8e4747c9UL, 0xfbf0f00bUL, 76 | 0x41adadecUL, 0xb3d4d467UL, 0x5fa2a2fdUL, 0x45afafeaUL, 77 | 0x239c9cbfUL, 0x53a4a4f7UL, 0xe4727296UL, 0x9bc0c05bUL, 78 | 0x75b7b7c2UL, 0xe1fdfd1cUL, 0x3d9393aeUL, 0x4c26266aUL, 79 | 0x6c36365aUL, 0x7e3f3f41UL, 0xf5f7f702UL, 0x83cccc4fUL, 80 | 0x6834345cUL, 0x51a5a5f4UL, 0xd1e5e534UL, 0xf9f1f108UL, 81 | 0xe2717193UL, 0xabd8d873UL, 0x62313153UL, 0x2a15153fUL, 82 | 0x0804040cUL, 0x95c7c752UL, 0x46232365UL, 0x9dc3c35eUL, 83 | 0x30181828UL, 0x379696a1UL, 0x0a05050fUL, 0x2f9a9ab5UL, 84 | 0x0e070709UL, 0x24121236UL, 0x1b80809bUL, 0xdfe2e23dUL, 85 | 0xcdebeb26UL, 0x4e272769UL, 0x7fb2b2cdUL, 0xea75759fUL, 86 | 0x1209091bUL, 0x1d83839eUL, 0x582c2c74UL, 0x341a1a2eUL, 87 | 0x361b1b2dUL, 0xdc6e6eb2UL, 0xb45a5aeeUL, 0x5ba0a0fbUL, 88 | 0xa45252f6UL, 0x763b3b4dUL, 0xb7d6d661UL, 0x7db3b3ceUL, 89 | 0x5229297bUL, 0xdde3e33eUL, 0x5e2f2f71UL, 0x13848497UL, 90 | 0xa65353f5UL, 0xb9d1d168UL, 0x00000000UL, 0xc1eded2cUL, 91 | 0x40202060UL, 0xe3fcfc1fUL, 0x79b1b1c8UL, 0xb65b5bedUL, 92 | 0xd46a6abeUL, 0x8dcbcb46UL, 0x67bebed9UL, 0x7239394bUL, 93 | 0x944a4adeUL, 0x984c4cd4UL, 0xb05858e8UL, 0x85cfcf4aUL, 94 | 0xbbd0d06bUL, 0xc5efef2aUL, 0x4faaaae5UL, 0xedfbfb16UL, 95 | 0x864343c5UL, 0x9a4d4dd7UL, 0x66333355UL, 0x11858594UL, 96 | 0x8a4545cfUL, 0xe9f9f910UL, 0x04020206UL, 0xfe7f7f81UL, 97 | 0xa05050f0UL, 0x783c3c44UL, 0x259f9fbaUL, 0x4ba8a8e3UL, 98 | 0xa25151f3UL, 0x5da3a3feUL, 0x804040c0UL, 0x058f8f8aUL, 99 | 0x3f9292adUL, 0x219d9dbcUL, 0x70383848UL, 0xf1f5f504UL, 100 | 0x63bcbcdfUL, 0x77b6b6c1UL, 0xafdada75UL, 0x42212163UL, 101 | 0x20101030UL, 0xe5ffff1aUL, 0xfdf3f30eUL, 0xbfd2d26dUL, 102 | 0x81cdcd4cUL, 0x180c0c14UL, 0x26131335UL, 0xc3ecec2fUL, 103 | 0xbe5f5fe1UL, 0x359797a2UL, 0x884444ccUL, 0x2e171739UL, 104 | 0x93c4c457UL, 0x55a7a7f2UL, 0xfc7e7e82UL, 0x7a3d3d47UL, 105 | 0xc86464acUL, 0xba5d5de7UL, 0x3219192bUL, 0xe6737395UL, 106 | 0xc06060a0UL, 0x19818198UL, 0x9e4f4fd1UL, 0xa3dcdc7fUL, 107 | 0x44222266UL, 0x542a2a7eUL, 0x3b9090abUL, 0x0b888883UL, 108 | 0x8c4646caUL, 0xc7eeee29UL, 0x6bb8b8d3UL, 0x2814143cUL, 109 | 0xa7dede79UL, 0xbc5e5ee2UL, 0x160b0b1dUL, 0xaddbdb76UL, 110 | 0xdbe0e03bUL, 0x64323256UL, 0x743a3a4eUL, 0x140a0a1eUL, 111 | 0x924949dbUL, 0x0c06060aUL, 0x4824246cUL, 0xb85c5ce4UL, 112 | 0x9fc2c25dUL, 0xbdd3d36eUL, 0x43acacefUL, 0xc46262a6UL, 113 | 0x399191a8UL, 0x319595a4UL, 0xd3e4e437UL, 0xf279798bUL, 114 | 0xd5e7e732UL, 0x8bc8c843UL, 0x6e373759UL, 0xda6d6db7UL, 115 | 0x018d8d8cUL, 0xb1d5d564UL, 0x9c4e4ed2UL, 0x49a9a9e0UL, 116 | 0xd86c6cb4UL, 0xac5656faUL, 0xf3f4f407UL, 0xcfeaea25UL, 117 | 0xca6565afUL, 0xf47a7a8eUL, 0x47aeaee9UL, 0x10080818UL, 118 | 0x6fbabad5UL, 0xf0787888UL, 0x4a25256fUL, 0x5c2e2e72UL, 119 | 0x381c1c24UL, 0x57a6a6f1UL, 0x73b4b4c7UL, 0x97c6c651UL, 120 | 0xcbe8e823UL, 0xa1dddd7cUL, 0xe874749cUL, 0x3e1f1f21UL, 121 | 0x964b4bddUL, 0x61bdbddcUL, 0x0d8b8b86UL, 0x0f8a8a85UL, 122 | 0xe0707090UL, 0x7c3e3e42UL, 0x71b5b5c4UL, 0xcc6666aaUL, 123 | 0x904848d8UL, 0x06030305UL, 0xf7f6f601UL, 0x1c0e0e12UL, 124 | 0xc26161a3UL, 0x6a35355fUL, 0xae5757f9UL, 0x69b9b9d0UL, 125 | 0x17868691UL, 0x99c1c158UL, 0x3a1d1d27UL, 0x279e9eb9UL, 126 | 0xd9e1e138UL, 0xebf8f813UL, 0x2b9898b3UL, 0x22111133UL, 127 | 0xd26969bbUL, 0xa9d9d970UL, 0x078e8e89UL, 0x339494a7UL, 128 | 0x2d9b9bb6UL, 0x3c1e1e22UL, 0x15878792UL, 0xc9e9e920UL, 129 | 0x87cece49UL, 0xaa5555ffUL, 0x50282878UL, 0xa5dfdf7aUL, 130 | 0x038c8c8fUL, 0x59a1a1f8UL, 0x09898980UL, 0x1a0d0d17UL, 131 | 0x65bfbfdaUL, 0xd7e6e631UL, 0x844242c6UL, 0xd06868b8UL, 132 | 0x824141c3UL, 0x299999b0UL, 0x5a2d2d77UL, 0x1e0f0f11UL, 133 | 0x7bb0b0cbUL, 0xa85454fcUL, 0x6dbbbbd6UL, 0x2c16163aUL, 134 | }; 135 | 136 | // round constants 137 | static const uint32 rcon[10] = { 138 | 0x01000000UL, 0x02000000UL, 0x04000000UL, 0x08000000UL, 139 | 0x10000000UL, 0x20000000UL, 0x40000000UL, 0x80000000UL, 140 | 0x1B000000UL, 0x36000000UL 141 | }; 142 | 143 | //encryption 144 | void aes_block_enc(uint8 *data, uint8 *key) 145 | { 146 | uint32 i; 147 | uint32 k0, k1, k2, k3; 148 | uint32 s0, s1, s2, s3; 149 | uint32 t0, t1, t2, t3; 150 | 151 | //load 128-bit message into 32-bit words 152 | LOAD32(data, &s0); 153 | LOAD32(data + 4, &s1); 154 | LOAD32(data + 8, &s2); 155 | LOAD32(data + 12, &s3); 156 | 157 | //load 128-bit key into 32-bit words 158 | LOAD32(key, &k0); 159 | LOAD32(key + 4, &k1); 160 | LOAD32(key + 8, &k2); 161 | LOAD32(key + 12, &k3); 162 | 163 | //add round key 164 | s0 ^= k0; 165 | s1 ^= k1; 166 | s2 ^= k2; 167 | s3 ^= k3; 168 | 169 | //9 regular rounds 170 | for (i = 9; i != 0; i--) 171 | { 172 | k0 ^= rcon[9 - i] ^ Te4_3(byte(k3, 2)) ^ Te4_2(byte(k3, 1)) ^ Te4_1(byte(k3, 0)) ^ Te4_0(byte(k3, 3)); 173 | k1 ^= k0; 174 | k2 ^= k1; 175 | k3 ^= k2; 176 | 177 | t0 = Te0(byte(s0, 0)) ^ Te1(byte(s1, 1)) ^ Te2(byte(s2, 2)) ^ Te3(byte(s3, 3)) ^ k0; 178 | t1 = Te0(byte(s1, 3)) ^ Te1(byte(s2, 2)) ^ Te2(byte(s3, 1)) ^ Te3(byte(s0, 0)) ^ k1; 179 | t2 = Te0(byte(s2, 3)) ^ Te1(byte(s3, 2)) ^ Te2(byte(s0, 1)) ^ Te3(byte(s1, 0)) ^ k2; 180 | t3 = Te0(byte(s3, 3)) ^ Te1(byte(s0, 2)) ^ Te2(byte(s1, 1)) ^ Te3(byte(s2, 0)) ^ k3; 181 | 182 | s0 = t0; 183 | s1 = t1; 184 | s2 = t2; 185 | s3 = t3; 186 | } 187 | 188 | // the last round for the full AES 189 | k0 ^= rcon[9] ^ Te4_3(byte(k3, 2)) ^ Te4_2(byte(k3, 1)) ^ Te4_1(byte(k3, 0)) ^ Te4_0(byte(k3, 3)); 190 | k1 ^= k0; 191 | k2 ^= k1; 192 | k3 ^= k2; 193 | 194 | s0 = Te4_3(byte(t0, 3)) ^ Te4_2(byte(t1, 2)) ^ Te4_1(byte(t2, 1)) ^ Te4_0(byte(t3, 0)) ^ k0; 195 | s1 = Te4_3(byte(t1, 3)) ^ Te4_2(byte(t2, 2)) ^ Te4_1(byte(t3, 1)) ^ Te4_0(byte(t0, 0)) ^ k1; 196 | s2 = Te4_3(byte(t2, 3)) ^ Te4_2(byte(t3, 2)) ^ Te4_1(byte(t0, 1)) ^ Te4_0(byte(t1, 0)) ^ k2; 197 | s3 = Te4_3(byte(t3, 3)) ^ Te4_2(byte(t0, 2)) ^ Te4_1(byte(t1, 1)) ^ Te4_0(byte(t2, 0)) ^ k3; 198 | 199 | STORE32(s0, data); 200 | STORE32(s1, data + 4); 201 | STORE32(s2, data + 8); 202 | STORE32(s3, data + 12); 203 | } -------------------------------------------------------------------------------- /AES128.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 Xinxin Fan 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * - Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * - Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in 12 | * the documentation and/or other materials provided with the 13 | * distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 25 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 | * POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #ifndef __AES128_H__ 30 | #define __AES128_H__ 31 | 32 | /** 33 | * AES-128 encryption interface 34 | * 35 | * @param data 128-bit plaintext/ciphertext 36 | * @param key 128-bit secret key 37 | */ 38 | void aes_block_enc(uint8 *data, uint8 *key); 39 | 40 | #endif /* __AES_H__ */ 41 | -------------------------------------------------------------------------------- /AESCCM.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 Xinxin Fan 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * - Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * - Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in 12 | * the documentation and/or other materials provided with the 13 | * distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 25 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 | * POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #include "OpenECC.h" 30 | #include "AESCCM.h" 31 | #include "AES128.h" 32 | 33 | /* The implementation of the AES-CCM* should combine the input tranformation 34 | * with the authentication transformation, since the Cortex-M3 does not have 35 | * the enough RAM to store the long message. 36 | */ 37 | void ccm_auth_only(uint8 *m, uint8 *a, uint8 *nonce, ccm_parameter param, uint8 *tag) 38 | { 39 | uint8 lm[8]; //byte representation of message length 40 | uint8 la[8]; //byte representation of associate data length 41 | uint8 T[16]; //128-bit message block and AES-CBC-MAC result 42 | uint64 i; 43 | uint32 j; 44 | uint64 blocknum; //number of message blocks 45 | uint32 lastnum; //number of bytes in the last message block 46 | uint32 lastbits; //remaining bits in the last byte 47 | uint64 adatanum; //number of associate data blocks 48 | uint32 alastnum; //number of bytes in the last associate data block 49 | uint32 alastbits; //remaining bits in the last byte of the associate data 50 | 51 | blocknum = param.msg_len >> 7; 52 | lastnum = (param.msg_len >>3) & 0xf; 53 | lastbits = param.msg_len & 0x7; 54 | 55 | for(j = 0; j < 8; j++) 56 | lm[j] = (uint8)(param.msg_len >> (j*8)); 57 | 58 | for(j = 0; j < 8; j++) 59 | la[j] = (uint8)(param.hdr_len>> (j*8)); 60 | 61 | //case 1: l(a) = 0, no associate data 62 | if(param.hdr_len == 0) 63 | { 64 | // Form B0 = curve_ids || Nonce N || l(m), where the byte curve_ids = Reserved || Adata (0) || M || L 65 | if(param.tag_len >= 2) 66 | { 67 | T[0] = (param.tag_len - 2) >> 1; 68 | T[0] = (T[0] << 3) | (param.L - 1); 69 | } 70 | else T[0] = param.L - 1; 71 | // Concatenate nonce 72 | for(i = 0; i < 15 - param.L; i++) 73 | T[i + 1] = *(nonce + i); 74 | // Concatenate l(m) 75 | for(i = 15 - param.L; i < 16; i++) 76 | T[i + 1] = lm[i - (15 - param.L)]; 77 | 78 | // AES-CBC-MAC for B0 79 | aes_block_enc(T, param.k); 80 | } 81 | else 82 | { 83 | // Form B0 = curve_ids || Nonce N || l(m), where the byte curve_ids = Reserved || Adata (1) || M || L 84 | if(param.tag_len >= 2) 85 | { 86 | T[0] = (param.tag_len - 2) >> 1; 87 | T[0] = (0x1 << 6) | (T[0] << 3) | (param.L - 1); 88 | } 89 | else T[0] = (0x1 << 6) | (param.L - 1); 90 | // Concatenate nonce 91 | for(i = 0; i < 15 - param.L; i++) 92 | T[i + 1] = *(nonce + i); 93 | // Concatenate l(m) 94 | for(i = 15 - param.L; i < 15; i++) 95 | T[i + 1] = lm[i - (15 - param.L)]; 96 | 97 | // AES-CBC-MAC for B0 98 | aes_block_enc(T, param.k); 99 | 100 | //case 2: 0 < l(a) < 2^16 - 2^8, the associate data is 2-octet representation of l(a) 101 | if(param.hdr_len > 0 && param.hdr_len < 65280) 102 | { 103 | adatanum = (param.hdr_len + 16) >> 7; 104 | alastnum = ((param.hdr_len + 16) >> 3) & 0xf; 105 | alastbits = (param.hdr_len + 16) & 0x7; 106 | 107 | //Deal with associate data blocks 108 | T[0] = T[0] ^ la[0]; 109 | T[1] = T[1] ^ la[1]; 110 | // Form the associate data = l(a) || a || 00...00 111 | if(adatanum >= 1) 112 | { 113 | for(j = 2; j < 16; j++) 114 | T[j] = T[j] ^ *(a + j - 2); 115 | aes_block_enc(T, param.k); 116 | for(i = 1; i < adatanum; i++) 117 | { 118 | for(j = 0; j < 16; j++) 119 | T[j] = T[j] ^ *(a + 16*i + j - 2); 120 | aes_block_enc(T, param.k); 121 | } 122 | j = 0; 123 | // Deal with the last block of the associate data 124 | if(alastnum != 0) 125 | { 126 | for(j = 0; j < alastnum; j++) 127 | T[j] = T[j] ^ *(a + 16*i + j - 2); 128 | if(alastbits == 0) 129 | { 130 | aes_block_enc(T, param.k); 131 | } 132 | } 133 | // Deal with the last bits of the associated data 134 | if(alastbits != 0) 135 | { 136 | T[j] = T[j] ^ (*(a + 16*i + j - 2) >> (8 - lastbits)); 137 | aes_block_enc(T, param.k); 138 | } 139 | } 140 | else 141 | { 142 | for(j = 2; j < alastnum; j++) 143 | T[j] = T[j] ^ *(a + j - 2); 144 | if(alastbits == 0) 145 | { 146 | aes_block_enc(T, param.k); 147 | } 148 | else 149 | { 150 | // Deal with the last bits of the associated data 151 | T[j] = T[j] ^ (*(a + j - 2) >> (8 - lastbits)); 152 | aes_block_enc(T, param.k); 153 | } 154 | } 155 | } 156 | else if (param.hdr_len >= 65280 && param.hdr_len < 4294967296) //case 3: 2^16 - 2^8 =< l(a) < 2^32, the associate data is the right-concatenation of the octet 0xff, the octet 0xfe, and the 4-octet representation of l(a) 157 | { 158 | adatanum = (param.hdr_len + 48) >> 7; 159 | alastnum = ((param.hdr_len + 48) >> 3) & 0xf; 160 | alastbits = (param.hdr_len + 48) & 0x7; 161 | 162 | //Deal with associate data blocks 163 | T[0] = T[0] ^ 0xff; 164 | T[1] = T[1] ^ 0xfe; 165 | T[2] = T[2] ^ la[0]; 166 | T[3] = T[3] ^ la[1]; 167 | T[4] = T[4] ^ la[2]; 168 | T[5] = T[5] ^ la[3]; 169 | // Form the associate data = 0xff || 0xfe || l(a) || a || 00...00 170 | if(adatanum >= 1) 171 | { 172 | for(j = 6; j < 16; j++) 173 | T[j] = T[j] ^ *(a + j - 6); 174 | aes_block_enc(T, param.k); 175 | for(i = 1; i < adatanum; i++) 176 | { 177 | for(j = 0; j < 16; j++) 178 | T[j] = T[j] ^ *(a + 16*i + j - 6); 179 | aes_block_enc(T, param.k); 180 | } 181 | j = 0; 182 | // Deal with the last block of the associate data 183 | if(alastnum != 0) 184 | { 185 | for(j = 0; j < alastnum; j++) 186 | T[j] = T[j] ^ *(a + 16*i + j - 6); 187 | if(alastbits == 0) 188 | { 189 | aes_block_enc(T, param.k); 190 | } 191 | } 192 | // Deal with the last bits of the associated data 193 | if(alastbits != 0) 194 | { 195 | T[j] = T[j] ^ (*(a + 16*i + j - 6) >> (8 - lastbits)); 196 | aes_block_enc(T, param.k); 197 | } 198 | } 199 | else 200 | { 201 | for(j = 2; j < alastnum; j++) 202 | T[j] = T[j] ^ *(a + j - 6); 203 | if(alastbits == 0) 204 | { 205 | aes_block_enc(T, param.k); 206 | } 207 | else 208 | { 209 | // Deal with the last bits of the associated data 210 | T[j] = T[j] ^ (*(a + j - 6) >> (8 - lastbits)); 211 | aes_block_enc(T, param.k); 212 | } 213 | } 214 | } 215 | else //case 4: 2^32 =< l(a) < 2^64, the associate data is the right-concatenation of the octet 0xff, the octet 0xff, and the 8-octet representation of l(a) 216 | { 217 | adatanum = (param.hdr_len + 80) >> 7; 218 | alastnum = ((param.hdr_len + 80) >> 3) & 0xf; 219 | alastbits = (param.hdr_len + 80) & 0x7; 220 | 221 | //Deal with associate data blocks 222 | T[0] = T[0] ^ 0xff; 223 | T[1] = T[1] ^ 0xfe; 224 | T[2] = T[2] ^ la[0]; 225 | T[3] = T[3] ^ la[1]; 226 | T[4] = T[4] ^ la[2]; 227 | T[5] = T[5] ^ la[3]; 228 | T[6] = T[6] ^ la[4]; 229 | T[7] = T[7] ^ la[5]; 230 | T[8] = T[8] ^ la[6]; 231 | T[9] = T[9] ^ la[7]; 232 | // Form the associate data = 0xff || 0xff || l(a) || a || 00...00 233 | if(adatanum >= 1) 234 | { 235 | for(j = 10; j < 16; j++) 236 | T[j] = T[j] ^ *(a + j - 10); 237 | aes_block_enc(T, param.k); 238 | for(i = 1; i < adatanum; i++) 239 | { 240 | for(j = 0; j < 16; j++) 241 | T[j] = T[j] ^ *(a + 16*i + j - 10); 242 | aes_block_enc(T, param.k); 243 | } 244 | j = 0; 245 | // Deal with the last block of the associate data 246 | if(alastnum != 0) 247 | { 248 | for(j = 0; j < alastnum; j++) 249 | T[j] = T[j] ^ *(a + 16*i + j - 10); 250 | if(alastbits == 0) 251 | { 252 | aes_block_enc(T, param.k); 253 | } 254 | } 255 | // Deal with the last bits of the associated data 256 | if(alastbits != 0) 257 | { 258 | T[j] = T[j] ^ (*(a + 16*i + j - 10) >> (8 - lastbits)); 259 | aes_block_enc(T, param.k); 260 | } 261 | } 262 | else 263 | { 264 | for(j = 2; j < alastnum; j++) 265 | T[j] = T[j] ^ *(a + j - 10); 266 | if(alastbits == 0) 267 | { 268 | aes_block_enc(T, param.k); 269 | } 270 | else 271 | { 272 | // Deal with the last bits of the associated data 273 | T[j] = T[j] ^ (*(a + j - 10) >> (8 - lastbits)); 274 | aes_block_enc(T, param.k); 275 | } 276 | } 277 | } 278 | } 279 | 280 | // Deal with message blocks 281 | for(i = 0; i < blocknum; i++) 282 | { 283 | for(j = 0; j < 16; j++) 284 | T[j] = T[j] ^ *(m + 16*i + j); 285 | aes_block_enc(T, param.k); 286 | } 287 | j = 0; 288 | // Deal with the last block of the message 289 | if(lastnum != 0) 290 | { 291 | for(j = 0; j < lastnum; j++) 292 | T[j] = T[j] ^ *(m + 16*i + j); 293 | if(lastbits == 0) 294 | { 295 | aes_block_enc(T, param.k); 296 | } 297 | } 298 | // Deal with the last bits of the message 299 | if(lastbits != 0) 300 | { 301 | T[j] = T[j] ^ (*(m + 16*i + j) >> (8 - lastbits)); 302 | aes_block_enc(T, param.k); 303 | } 304 | 305 | for(i = 0; i < 16; i++) 306 | *(tag + i) = T[i]; 307 | } 308 | 309 | //CCM* authenticated encryption mode 310 | void ccm_auth_enc(uint8 *m, uint8 *a, uint8 *nonce, ccm_parameter param, uint8 *c, uint8 *authtag) 311 | { 312 | uint8 T[16]; //128-bit AES-CBC-MAC result 313 | uint8 A[16]; //128-bit data block for CTR mode 314 | uint8 Counter[8]; //the maximum number of counter 315 | uint64 i; 316 | uint32 j; 317 | uint64 blocknum; //number of message blocks 318 | uint32 lastnum; //number of bytes in the last message block 319 | uint32 lastbits; //remaining bits in the last byte 320 | 321 | blocknum = param.msg_len >> 7; 322 | lastnum = (param.msg_len >>3) & 0xf; 323 | lastbits = param.msg_len & 0x7; 324 | 325 | // Generate the authentication tag 326 | ccm_auth_only(m, a, nonce, param, T); 327 | 328 | //Forms 128-bit data block A_i = curve_ids || Nonce N || Counter_i 329 | A[0] = param.L - 1; 330 | // Concatenate nonce 331 | for(j = 0; j < (uint32)(15 - param.L); j++) 332 | A[j + 1] = *(nonce + j); 333 | // Concatenate counter_0 334 | for(j = 15 - param.L; j < 15; j++) 335 | A[j + 1] = 0; 336 | aes_block_enc(A, param.k); 337 | // Compute AuthTag as the leftmost tag_len octets of S_0 338 | for(j = 0; j < param.tag_len; j++) 339 | *(authtag + j) = T[j] ^ A[j]; 340 | 341 | // CTR encryption for message blocks M_1, ..., M_(t-1) 342 | for(i = 0; i < blocknum; i++) 343 | { 344 | //Convert counter_i to bytes 345 | for(j = 0; j < 8; j++) 346 | Counter[j] = (uint8)(i >> (j*8)); 347 | //Forms 128-bit data block A_i = curve_ids || Nonce N || Counter_i 348 | A[0] = param.L - 1; 349 | // Concatenate nonce 350 | for(j = 0; j < (uint32)(15 - param.L); j++) 351 | A[j + 1] = *(nonce + j); 352 | // Concatenate counter_i 353 | for(j = 15 - param.L; j < 15; j++) 354 | A[j + 1] = Counter[j - (15 - param.L)]; 355 | aes_block_enc(A, param.k); 356 | for(j = 0; j < 16; j++) 357 | *(c + i*16 + j) = A[j] ^ *(m + i*16 + j); 358 | } 359 | 360 | //CTR encryption for the last message block M_t 361 | if(lastnum != 0 || lastbits != 0) 362 | { 363 | //Convert counter_t to bytes 364 | for(j = 0; j < 8; j++) 365 | Counter[j] = (uint8)((blocknum + 1) >> (j*8)); 366 | //Forms 128-bit data block A_i = curve_ids || Nonce N || Counter_i 367 | A[0] = param.L - 1; 368 | // Concatenate nonce 369 | for(j = 0; j < (uint32)(15 - param.L); j++) 370 | A[j + 1] = *(nonce + j); 371 | // Concatenate counter_i 372 | for(j = 15 - param.L; j < 15; j++) 373 | A[j + 1] = Counter[j - (15 - param.L)]; 374 | aes_block_enc(A, param.k); 375 | for(j = 0; j < lastnum; j++) 376 | *(c + blocknum*16 + j) = A[j] ^ *(m + blocknum*16 + j); 377 | if(lastbits != 0) 378 | { 379 | T[0] = A[lastnum] ^ *(m + blocknum*16 + lastnum); 380 | *(c + blocknum*16 + lastnum) = T[0] >> (8 - lastbits); 381 | } 382 | } 383 | } 384 | 385 | //CCM* authenticated decryption mode 386 | void ccm_auth_dec(uint8 *c, uint8 *authtag, uint8 *nonce, ccm_parameter param, uint8 *m, uint8 *u) 387 | { 388 | uint8 A[16]; //128-bit data block for CTR mode 389 | uint8 Counter[8]; //the maximum number of counter 390 | uint64 i; 391 | uint32 j; 392 | uint64 blocknum; //number of message blocks 393 | uint32 lastnum; //number of bytes in the last message block 394 | uint32 lastbits; //remaining bits in the last byte 395 | 396 | blocknum = param.msg_len >> 7; 397 | lastnum = (param.msg_len >>3) & 0xf; 398 | lastbits = param.msg_len & 0x7; 399 | 400 | //Forms 128-bit data block A_i = curve_ids || Nonce N || Counter_i 401 | A[0] = param.L - 1; 402 | // Concatenate nonce 403 | for(j = 0; j < (uint32)(15 - param.L); j++) 404 | A[j + 1] = *(nonce + j); 405 | // Concatenate counter_0 406 | for(j = 15 - param.L; j < 15; j++) 407 | A[j + 1] = 0; 408 | aes_block_enc(A, param.k); 409 | // Compute u 410 | for(j = 0; j < param.tag_len; j++) 411 | *(u + j) = A[j] ^ *(authtag + j); 412 | 413 | // CTR decryption for ciphertext blocks C_1, ..., C_(t-1) 414 | for(i = 0; i < blocknum; i++) 415 | { 416 | //Convert counter_i to bytes 417 | for(j = 0; j < 8; j++) 418 | Counter[j] = (uint8)(i >> (j*8)); 419 | //Forms 128-bit data block A_i = curve_ids || Nonce N || Counter_i 420 | A[0] = param.L - 1; 421 | // Concatenate nonce 422 | for(j = 0; j < (uint32)(15 - param.L); j++) 423 | A[j + 1] = *(nonce + j); 424 | // Concatenate counter_i 425 | for(j = 15 - param.L; j < 15; j++) 426 | A[j + 1] = Counter[j - (15 - param.L)]; 427 | aes_block_enc(A, param.k); 428 | for(j = 0; j < 16; j++) 429 | *(m + i*16 + j) = A[j] ^ *(c + i*16 + j); 430 | } 431 | 432 | //CTR decryption for the last message block M_t 433 | if(lastnum != 0 || lastbits != 0) 434 | { 435 | //Convert counter_t to bytes 436 | for(j = 0; j < 8; j++) 437 | Counter[j] = (uint8)((blocknum + 1) >> (j*8)); 438 | //Forms 128-bit data block A_i = curve_ids || Nonce N || Counter_i 439 | A[0] = param.L - 1; 440 | // Concatenate nonce 441 | for(j = 0; j < (uint32)(15 - param.L); j++) 442 | A[j + 1] = *(nonce + j); 443 | // Concatenate counter_i 444 | for(j = 15 - param.L; j < 15; j++) 445 | A[j + 1] = Counter[j - (15 - param.L)]; 446 | aes_block_enc(A, param.k); 447 | for(j = 0; j < lastnum; j++) 448 | *(m + blocknum*16 + j) = A[j] ^ *(c + blocknum*16 + j); 449 | if(lastbits != 0) 450 | { 451 | A[0] = A[lastnum] ^ *(c + blocknum*16 + lastnum); 452 | *(m + blocknum*16 + lastnum) = A[0] >> (8 - lastbits); 453 | } 454 | } 455 | } 456 | 457 | 458 | //CCM* verification mode 459 | uint8 ccm_veri_only(uint8 *m, uint8 *a, uint8 *nonce, ccm_parameter param, uint8 *u) 460 | { 461 | uint8 T[16]; //128-bit AES-CBC-MAC result 462 | uint32 i; 463 | 464 | // Generate the authentication tag 465 | ccm_auth_only(m, a, nonce, param, T); 466 | 467 | for(i = 0; i < param.tag_len; i++) 468 | { 469 | if(*(u + i) != T[i]) 470 | return 0; //Authentication tag is invalid! 471 | } 472 | return 1; //Authentication tag is valid! 473 | } -------------------------------------------------------------------------------- /AESCCM.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 Xinxin Fan 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * - Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * - Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in 12 | * the documentation and/or other materials provided with the 13 | * distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 25 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 | * POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #ifndef __AESCCM_H__ 30 | #define __AESCCM_H__ 31 | 32 | /** 33 | * the parameter of the CCM* 34 | */ 35 | typedef struct 36 | { 37 | uint8 L; /* an integer 1 < L < 9*/ 38 | uint8 nonce_len; /* the nonce length in bytes */ 39 | uint8 tag_len; /* the authentication tag length in bytes */ 40 | uint8 k[16]; /* a 128-bit symmetric key k */ 41 | uint64 msg_len; /* message data length in bits: 0 <= msg_len < 2^(8*L) */ 42 | uint64 hdr_len; /* the associated data length in bits: 0 <= hdr_len < 2^64*/ 43 | } ccm_parameter; 44 | 45 | /** 46 | * authentication only mode in CCM* 47 | * 48 | * @param m an octet message m of length msg_len bits 49 | * @param a an octet associate data a of length hdr_len bits 50 | * @param nonce an octet string of length nonce_len bytes 51 | * @param param the parameters of the CCM* 52 | * @param tag a 128-bit authentication tag 53 | */ 54 | void ccm_auth_only(uint8 *m, uint8 *a, uint8 *nonce, ccm_parameter param, uint8 *tag); 55 | 56 | /** 57 | * authenticated encryption mode in CCM* 58 | * 59 | * @param m an octet message m of length msg_len bits 60 | * @param a an octet associate data of length hdr_len bits 61 | * @param nonce an octet string of length nonce_len bytes 62 | * @param param the parameters of the CCM* 63 | * @param c a ciphertext of length msg_len bits 64 | * @param authtag an authentication tag of tag_len bytes 65 | */ 66 | void ccm_auth_enc(uint8 *m, uint8 *a, uint8 *nonce, ccm_parameter param, uint8 *c, uint8 *authtag); 67 | 68 | /** 69 | * authenticated decryption mode in CCM* 70 | * 71 | * @param c a ciphertext of length msg_len bits 72 | * @param authtag an authentication tag of tag_len bytes 73 | * @param nonce an octet string of length nonce_len bytes 74 | * @param param the parameters of the CCM* 75 | * @param m an octet message m of length msg_len bits 76 | * @param u an authenticator of length tag_len bytes 77 | */ 78 | void ccm_auth_dec(uint8 *c, uint8 *authtag, uint8 *nonce, ccm_parameter param, uint8 *m, uint8 *u); 79 | 80 | /** 81 | * verification mode in CCM* 82 | * 83 | * @param m an octet message m of length msg_len bits 84 | * @param a an octet associate data a of length hdr_len bits 85 | * @param nonce an octet string of length nonce_len bytes 86 | * @param param the parameters of the CCM* 87 | * @param u an authenticator of length tag_len bytes 88 | */ 89 | uint8 ccm_veri_only(uint8 *m, uint8 *a, uint8 *nonce, ccm_parameter param, uint8 *u); 90 | 91 | #endif /* __AESCCM_H__ */ 92 | -------------------------------------------------------------------------------- /AESMMO.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 Xinxin Fan 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * - Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * - Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in 12 | * the documentation and/or other materials provided with the 13 | * distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 25 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 | * POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #include "OpenECC.h" 30 | #include "AESMMO.h" 31 | #include "AES128.h" 32 | 33 | //AES MMO construction 34 | uint32 AES_MMO(uint8 *M, uint64 Mlen, uint8 *h) 35 | { 36 | 37 | uint32 j; 38 | uint64 i, Mlenp; 39 | uint8 T[16]; //128-bit message block 40 | uint8 S[16]; //128-bit message block 41 | uint64 blocknum; //number of message blocks 42 | uint32 lastnum; //number of bytes in the last message block 43 | uint32 lastbits; //remaining bits in the last byte 44 | uint8 k[16] = {0x0}; 45 | 46 | 47 | if(Mlen == 0) return 0; 48 | 49 | Mlenp = Mlen + 128; 50 | 51 | //Process the first 128-bit message block M_0 52 | //Prefix-free encoding 53 | T[0] = (uint8)Mlen; 54 | T[1] = (uint8)(Mlen >> 8); 55 | T[2] = (uint8)(Mlen >> 16); 56 | T[3] = (uint8)(Mlen >> 24); 57 | T[4] = (uint8)(Mlen >> 32); 58 | T[5] = (uint8)(Mlen >> 40); 59 | T[6] = (uint8)(Mlen >> 48); 60 | T[7] = (uint8)(Mlen >> 56); 61 | S[0] = T[0]; 62 | S[1] = T[1]; 63 | S[2] = T[2]; 64 | S[3] = T[3]; 65 | S[4] = T[4]; 66 | S[5] = T[5]; 67 | S[6] = T[6]; 68 | S[7] = T[7]; 69 | for(j = 8; j < 16; j++) 70 | { 71 | T[j] = 0x0; 72 | S[j] = 0x0; 73 | } 74 | aes_block_enc(T, k); 75 | for(j = 0; j < 16; j++) 76 | k[j] = T[j] ^ S[j]; 77 | 78 | blocknum = Mlen >> 7; 79 | lastnum = (Mlen >> 3) & 0xf; 80 | lastbits = Mlen & 0x7; 81 | 82 | //Process a number of 128-bit blocks 83 | for(i = 0; i < blocknum; i++) 84 | { 85 | for(j = 0; j < 16; j++) 86 | { 87 | T[j] = *(M + 16*i + j); 88 | S[j] = T[j]; 89 | } 90 | aes_block_enc(T, k); 91 | for(j = 0; j < 16; j++) 92 | k[j] = T[j] ^ S[j]; 93 | } 94 | 95 | //Process the remaining bytes 96 | for(j = 0; j < lastnum; j++) 97 | { 98 | T[j] = *(M + 16*blocknum + j); 99 | S[j] = T[j]; 100 | } 101 | 102 | //Deal with remaining bits 103 | if(lastbits == 0) 104 | { 105 | T[lastnum] = 0x80; 106 | S[lastnum] = T[lastnum]; 107 | } 108 | else 109 | { 110 | T[lastnum] = (*(M + 16*blocknum + lastnum) << (8 - lastbits)) | (0x1 << (8 - lastbits - 1)); 111 | S[lastnum] = T[lastnum]; 112 | } 113 | 114 | if(Mlenp < 65536) //MD-strengthening-1 115 | { 116 | //Deal with the last one or two blocks 117 | if((lastnum * 8 + lastbits) >= 112) //two blocks 118 | { 119 | //the second last block 120 | for(j = lastnum + 1; j < 16; j++) 121 | { 122 | T[j] = 0x0; 123 | S[j] = 0x0; 124 | } 125 | aes_block_enc(T, k); 126 | for(j = 0; j < 16; j++) 127 | k[j] = T[j] ^ S[j]; 128 | 129 | //the last block 130 | for(j = 0; j < 14; j++) 131 | { 132 | T[j] = 0x0; 133 | S[j] = 0x0; 134 | } 135 | T[14] = (uint8)(Mlenp >> 8); 136 | S[14] = T[14]; 137 | T[15] = (uint8)Mlenp; 138 | S[15] = T[15]; 139 | aes_block_enc(T, k); 140 | for(j = 0; j < 16; j++) 141 | k[j] = T[j] ^ S[j]; 142 | } 143 | else //one block 144 | { 145 | //the last block 146 | for(j = lastnum + 1; j < 14; j++) 147 | { 148 | T[j] = 0x0; 149 | S[j] = 0x0; 150 | } 151 | T[14] = (uint8)(Mlenp >> 8); 152 | S[14] = T[14]; 153 | T[15] = (uint8)Mlenp; 154 | S[15] = T[15]; 155 | aes_block_enc(T, k); 156 | for(j = 0; j < 16; j++) 157 | k[j] = T[j] ^ S[j]; 158 | } 159 | } 160 | else if(Mlenp >= 65536 && Mlenp < 4294967296) //MD-strengthening-2 161 | { 162 | //Deal with the last one or two blocks 163 | if((lastnum * 8 + lastbits) >= 80) //two blocks 164 | { 165 | //the second last block 166 | for(j = lastnum + 1; j < 16; j++) 167 | { 168 | T[j] = 0x0; 169 | S[j] = 0x0; 170 | } 171 | aes_block_enc(T, k); 172 | for(j = 0; j < 16; j++) 173 | k[j] = T[j] ^ S[j]; 174 | 175 | //the last block 176 | for(j = 0; j < 12; j++) 177 | { 178 | T[j] = 0x0; 179 | S[j] = 0x0; 180 | } 181 | T[12] = (uint8)(Mlenp >> 24); 182 | S[12] = T[12]; 183 | T[13] = (uint8)(Mlenp >> 16); 184 | S[13] = T[13]; 185 | T[14] = (uint8)(Mlenp >> 8); 186 | S[14] = T[14]; 187 | T[15] = (uint8)Mlenp; 188 | S[15] = T[15]; 189 | aes_block_enc(T, k); 190 | for(j = 0; j < 16; j++) 191 | k[j] = T[j] ^ S[j]; 192 | } 193 | else //one block 194 | { 195 | //the last block 196 | for(j = lastnum + 1; j < 12; j++) 197 | { 198 | T[j] = 0x0; 199 | S[j] = 0x0; 200 | } 201 | T[12] = (uint8)(Mlenp >> 24); 202 | S[12] = T[12]; 203 | T[13] = (uint8)(Mlenp >> 16); 204 | S[13] = T[13]; 205 | T[14] = (uint8)(Mlenp >> 8); 206 | S[14] = T[14]; 207 | T[15] = (uint8)Mlenp; 208 | S[15] = T[15]; 209 | aes_block_enc(T, k); 210 | for(j = 0; j < 16; j++) 211 | k[j] = T[j] ^ S[j]; 212 | } 213 | } 214 | else //MD-strengthening-3 215 | { 216 | //Deal with the last one or two blocks 217 | if((lastnum * 8 + lastbits) >= 16) //two blocks 218 | { 219 | //the second last block 220 | for(j = lastnum + 1; j < 16; j++) 221 | { 222 | T[j] = 0x0; 223 | S[j] = 0x0; 224 | } 225 | aes_block_enc(T, k); 226 | for(j = 0; j < 16; j++) 227 | k[j] = T[j] ^ S[j]; 228 | 229 | //the last block 230 | for(j = 0; j < 8; j++) 231 | { 232 | T[j] = 0x0; 233 | S[j] = 0x0; 234 | } 235 | T[8] = (uint8)(Mlen >> 56); 236 | S[8] = T[8]; 237 | T[9] = (uint8)(Mlen >> 48); 238 | S[9] = T[9]; 239 | T[10] = (uint8)(Mlen >> 40); 240 | S[10] = T[10]; 241 | T[11] = (uint8)(Mlen >> 32); 242 | S[11] = T[11]; 243 | T[12] = (uint8)(Mlen >> 24); 244 | S[12] = T[12]; 245 | T[13] = (uint8)(Mlen >> 16); 246 | S[13] = T[13]; 247 | T[14] = (uint8)(Mlen >> 8); 248 | S[14] = T[14]; 249 | T[15] = (uint8)Mlen; 250 | S[15] = T[15]; 251 | aes_block_enc(T, k); 252 | for(j = 0; j < 16; j++) 253 | k[j] = T[j] ^ S[j]; 254 | } 255 | else //one block 256 | { 257 | //the last block 258 | for(j = lastnum + 1; j < 8; j++) 259 | { 260 | T[j] = 0x0; 261 | S[j] = 0x0; 262 | } 263 | T[8] = (uint8)(Mlen >> 56); 264 | S[8] = T[8]; 265 | T[9] = (uint8)(Mlen >> 48); 266 | S[9] = T[9]; 267 | T[10] = (uint8)(Mlen >> 40); 268 | S[10] = T[10]; 269 | T[11] = (uint8)(Mlen >> 32); 270 | S[11] = T[11]; 271 | T[12] = (uint8)(Mlen >> 24); 272 | S[12] = T[12]; 273 | T[13] = (uint8)(Mlen >> 16); 274 | S[13] = T[13]; 275 | T[14] = (uint8)(Mlen >> 8); 276 | S[14] = T[14]; 277 | T[15] = (uint8)Mlen; 278 | S[15] = T[15]; 279 | aes_block_enc(T, k); 280 | for(j = 0; j < 16; j++) 281 | k[j] = T[j] ^ S[j]; 282 | } 283 | } 284 | 285 | for(j = 0; j < 16; j++) 286 | *(h + j) = *(k + j); 287 | 288 | /*for(j = 0; j < 4; j++) 289 | { 290 | *(h + j) = ((uint32)k[4*j] << 24) | ((uint32)k[4*j+1] << 16) | ((uint32)k[4*j+2] << 8) | ((uint32)k[4*j+3]); 291 | *(h + j + 4) = 0x0; 292 | }*/ 293 | 294 | return 1; 295 | } -------------------------------------------------------------------------------- /AESMMO.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 Xinxin Fan 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * - Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * - Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in 12 | * the documentation and/or other materials provided with the 13 | * distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 25 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 | * POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #ifndef __AESMMO_H__ 30 | #define __AESMMO_H__ 31 | 32 | /** 33 | * AES MMO construction 34 | * 35 | * @param M an octet message M 36 | * @param Mlen the length of the message M in bits (Mlen < 2^64) 37 | * @param h the hash value of the message M (128 bits) 38 | * succeed return 1 39 | * fail return 0 40 | */ 41 | uint32 AES_MMO(uint8 *M, uint64 Mlen, uint8 *h); 42 | 43 | #endif /* __AESCCM_H__ */ 44 | -------------------------------------------------------------------------------- /DRNG.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 Xinxin Fan 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * - Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * - Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in 12 | * the documentation and/or other materials provided with the 13 | * distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 25 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 | * POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #include "OpenECC.h" 30 | #include "DRNG.h" 31 | #include "AES128.h" 32 | 33 | ctr_drbg rnd; //a global random number generator 34 | 35 | //Initialize the DRNG 36 | void ctr_init(uint8 *seed) 37 | { 38 | rnd.K[0] = (*seed) ^ 0x58; 39 | rnd.K[1] = *(seed + 1) ^ 0xE2; 40 | rnd.K[2] = *(seed + 2) ^ 0xFC; 41 | rnd.K[3] = *(seed + 3) ^ 0xCE; 42 | rnd.K[4] = *(seed + 4) ^ 0xFA; 43 | rnd.K[5] = *(seed + 5) ^ 0x7E; 44 | rnd.K[6] = *(seed + 6) ^ 0x30; 45 | rnd.K[7] = *(seed + 7) ^ 0x61; 46 | rnd.K[8] = *(seed + 8) ^ 0x36; 47 | rnd.K[9] = *(seed + 9) ^ 0x7F; 48 | rnd.K[10] = *(seed + 10) ^ 0x1D; 49 | rnd.K[11] = *(seed + 11) ^ 0x57; 50 | rnd.K[12] = *(seed + 12) ^ 0xA4; 51 | rnd.K[13] = *(seed + 13) ^ 0xE7; 52 | rnd.K[14] = *(seed + 14) ^ 0x45; 53 | rnd.K[15] = *(seed + 15) ^ 0x5A; 54 | 55 | rnd.V[0] = *(seed + 16) ^ 0x03; 56 | rnd.V[1] = *(seed + 17) ^ 0x88; 57 | rnd.V[2] = *(seed + 18) ^ 0xDA; 58 | rnd.V[3] = *(seed + 19) ^ 0xCE; 59 | rnd.V[4] = *(seed + 20) ^ 0x60; 60 | rnd.V[5] = *(seed + 21) ^ 0xB6; 61 | rnd.V[6] = *(seed + 22) ^ 0xA3; 62 | rnd.V[7] = *(seed + 23) ^ 0x92; 63 | rnd.V[8] = *(seed + 24) ^ 0xF3; 64 | rnd.V[9] = *(seed + 25) ^ 0x28; 65 | rnd.V[10] = *(seed + 26) ^ 0xC2; 66 | rnd.V[11] = *(seed + 27) ^ 0xB9; 67 | rnd.V[12] = *(seed + 28) ^ 0x71; 68 | rnd.V[13] = *(seed + 29) ^ 0xB2; 69 | rnd.V[14] = *(seed + 30) ^ 0xFE; 70 | rnd.V[15] = *(seed + 31) ^ 0x78; 71 | 72 | rnd.counter = 1; 73 | } 74 | 75 | //Update the DRNG 76 | void ctr_update() 77 | { 78 | uint8 temp1[16]; 79 | uint8 temp2[16]; 80 | uint32 i,t,c; 81 | 82 | t = (uint32)(rnd.V[0]) + 0x1; 83 | temp1[0] = (uint8)(t & 0xff); 84 | c = t >> 8; 85 | i = 1; 86 | //V+1 (mod 2^128) 87 | while(c != 0 && i < 16) 88 | { 89 | t = (uint32)(rnd.V[i]) + c; 90 | temp1[i] = (uint8)(t & 0xff); 91 | c = t >> 8; 92 | i++; 93 | } 94 | 95 | t = (uint32)(rnd.V[0]) + 0x2; 96 | temp2[0] = (uint8)(t & 0xff); 97 | c = t >> 8; 98 | i = 1; 99 | //V+2 (mod 2^128) 100 | while(c != 0 && i < 16) 101 | { 102 | t = (uint32)(rnd.V[i]) + c; 103 | temp2[i] = (uint8)(t & 0xff); 104 | c = t >> 8; 105 | i++; 106 | } 107 | 108 | aes_block_enc(temp1, rnd.K); 109 | aes_block_enc(temp2, rnd.K); 110 | 111 | //updated key K 112 | rnd.K[0] = temp1[0]; 113 | rnd.K[1] = temp1[1]; 114 | rnd.K[2] = temp1[2]; 115 | rnd.K[3] = temp1[3]; 116 | rnd.K[4] = temp1[4]; 117 | rnd.K[5] = temp1[5]; 118 | rnd.K[6] = temp1[6]; 119 | rnd.K[7] = temp1[7]; 120 | rnd.K[8] = temp1[8]; 121 | rnd.K[9] = temp1[9]; 122 | rnd.K[10] = temp1[10]; 123 | rnd.K[11] = temp1[11]; 124 | rnd.K[12] = temp1[12]; 125 | rnd.K[13] = temp1[13]; 126 | rnd.K[14] = temp1[14]; 127 | rnd.K[15] = temp1[15]; 128 | 129 | //updated state V 130 | rnd.V[0] = temp2[0]; 131 | rnd.V[1] = temp2[1]; 132 | rnd.V[2] = temp2[2]; 133 | rnd.V[3] = temp2[3]; 134 | rnd.V[4] = temp2[4]; 135 | rnd.V[5] = temp2[5]; 136 | rnd.V[6] = temp2[6]; 137 | rnd.V[7] = temp2[7]; 138 | rnd.V[8] = temp2[8]; 139 | rnd.V[9] = temp2[9]; 140 | rnd.V[10] = temp2[10]; 141 | rnd.V[11] = temp2[11]; 142 | rnd.V[12] = temp2[12]; 143 | rnd.V[13] = temp2[13]; 144 | rnd.V[14] = temp2[14]; 145 | rnd.V[15] = temp2[15]; 146 | } 147 | 148 | //Generate a random number and update the internal state 149 | uint32 ctr_generate(uint32 rlen, uint8 *rndnum) 150 | { 151 | uint8 temp[16]; 152 | uint32 i,j,t,c; 153 | uint32 blocknum; //number of AES-128 calls 154 | uint32 lastnum; //number of bytes in the last random number block 155 | uint32 lastbits; //remaining bits in the last byte 156 | 157 | if(rnd.counter > 281474976710656) return 0; //If counter > 2^48, return ERROR 158 | if(rlen > 65536 || rlen == 0) return 0; //If rlen > 2^16, return ERROR 159 | 160 | blocknum = rlen >> 7; 161 | lastnum = (rlen >> 3) & 0xf; 162 | lastbits = rlen & 0x7; 163 | 164 | for(i = 0; i < blocknum; i++) 165 | { 166 | t = (uint32)(rnd.V[0]) + 0x1; 167 | temp[0] = (uint8)(t & 0xff); 168 | rnd.V[0] = temp[0]; 169 | c = t >> 8; 170 | j = 1; 171 | //V+1 (mod 2^128) 172 | while(c != 0 && j < 16) 173 | { 174 | t = (uint32)(rnd.V[j]) + c; 175 | temp[j] = (uint8)(t & 0xff); 176 | rnd.V[j] = temp[j]; 177 | c = t >> 8; 178 | j++; 179 | } 180 | aes_block_enc(temp,rnd.K); 181 | for(j = 0; j < 16; j++) 182 | *(rndnum + i*16 + j) = temp[j]; 183 | } 184 | 185 | if(lastnum != 0 || lastbits != 0) //need one more AES-128 call 186 | { 187 | t = (uint32)(rnd.V[0]) + 0x1; 188 | temp[0] = (uint8)(t & 0xff); 189 | rnd.V[0] = temp[0]; 190 | c = t >> 8; 191 | j = 1; 192 | //V+1 (mod 2^128) 193 | while(c != 0 && j < 16) 194 | { 195 | t = (uint32)(rnd.V[j]) + c; 196 | temp[j] = (uint8)(t & 0xff); 197 | rnd.V[j] = temp[j]; 198 | c = t >> 8; 199 | j++; 200 | } 201 | aes_block_enc(temp,rnd.K); 202 | for(j = 0; j < lastnum; j++) 203 | *(rndnum + blocknum*16 + j) = temp[j]; 204 | if(lastbits != 0) 205 | { 206 | *(rndnum + blocknum*16 + lastnum) = (temp[lastnum] >> (8 - lastbits)); 207 | } 208 | } 209 | 210 | //update the DRNG 211 | ctr_update(); 212 | rnd.counter++; 213 | 214 | return 1; //SUCCESS 215 | } -------------------------------------------------------------------------------- /DRNG.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 Xinxin Fan 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * - Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * - Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in 12 | * the documentation and/or other materials provided with the 13 | * distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 25 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 | * POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #ifndef __DRNG_H__ 30 | #define __DRNG_H__ 31 | 32 | //the state of the CTR_DRBG 33 | typedef struct 34 | { 35 | uint8 V[16]; /* 128-bit state */ 36 | uint8 K[16]; /* 128-bit key */ 37 | uint64 counter; /* 64-bit counter */ 38 | }ctr_drbg; 39 | 40 | extern ctr_drbg rnd; 41 | 42 | /** 43 | * random number generator initialization 44 | * 45 | * @param seed 128-bit seed 46 | */ 47 | void ctr_init(uint8 *seed); 48 | 49 | /** 50 | * random number generation 51 | * 52 | * @param rlen the length of random number in bits 53 | * @param rndnum store the generated random number 54 | */ 55 | uint32 ctr_generate(uint32 rlen, uint8 *rndnum); 56 | 57 | #endif /* __DRNG_H__ */ 58 | -------------------------------------------------------------------------------- /ECCK.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 Xinxin Fan 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * - Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * - Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in 12 | * the documentation and/or other materials provided with the 13 | * distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 25 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 | * POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #include "stdio.h" 30 | #include "OpenECC.h" 31 | #include "GF2n.h" 32 | #include "ECCK.h" 33 | 34 | //Base point G 35 | ec_point_aff G[2] = {{{0x5C94EEE8UL,0xDE4E6D5EUL,0xAA07D793UL,0x7BBC11ACUL,0xFE13C053UL,0x2UL,0x0UL,0x0UL}, 36 | {0xCCDAA3D9UL,0x0536D538UL,0x321F2E80UL,0x5D38FF58UL,0x89070FB0UL,0x2UL,0x0UL,0x0UL}}, 37 | {{0xEFAD6126UL,0x0A4C9D6EUL,0x19C26BF5UL,0x149563A4UL,0x29F22FF4UL,0x7E731AF1UL,0x32BA853AUL,0x172UL}, 38 | {0x56FAE6A3UL,0x56E0C110UL,0xF18AEB9BUL,0x27A8CD9BUL,0x555A67C4UL,0x19B7F70FUL,0x537DECE8UL,0x1DBUL}}}; 39 | //Precomputation points 40 | ec_point_aff G3[2] = {{{0xCA10CE8CUL,0xB3F21EBEUL,0x9DED1294UL,0x07BD695DUL,0xB169733EUL,0x7UL,0x0UL,0x0UL}, 41 | {0x4A46E566UL,0x40CF0940UL,0x5596317AUL,0xB3FA22D8UL,0xEA6C3F7AUL,0x2UL,0x0UL,0x0UL}}, 42 | {{0x35B25BE6UL,0x89382387UL,0x731F5E3EUL,0x6B7069F0UL,0x195489BBUL,0xF5A0FFE9UL,0x310F0F79UL,0x12CUL}, 43 | {0xE628C820UL,0x64B993B6UL,0x28632097UL,0x236B0F48UL,0x2C3A6BE1UL,0x6BBD39C3UL,0x5FF84152UL,0x183UL}}}; 44 | ec_point_aff G5[2] = {{{0xC68A1031UL,0x8BC0046DUL,0x536B5A45UL,0x8FE46728UL,0xC1428F6AUL,0x4UL,0x0UL,0x0UL}, 45 | {0xB8914834UL,0xF440E165UL,0xDD5562F1UL,0x7DD8530CUL,0x6187D5FFUL,0x4UL,0x0UL,0x0UL}}, 46 | {{0x32077AC0UL,0xA21C78A5UL,0x00A4D4A1UL,0x43B18CDAUL,0x4C7796F2UL,0x854EF6B6UL,0x8B9DF3EAUL,0x09EUL}, 47 | {0x7EDFB6FDUL,0x39AF846FUL,0xDE0568EBUL,0xA3DDD6BFUL,0x45F163A8UL,0xE1760EE5UL,0x7ABB1ED2UL,0x18CUL}}}; 48 | ec_point_aff G7[2] = {{{0x29CE13DFUL,0x92A33027UL,0x4A538869UL,0x6B74501DUL,0x8343C0D1UL,0x3UL,0x0UL,0x0UL}, 49 | {0xCB2EC5AAUL,0xCADD67F0UL,0xB9A997F6UL,0xF90D1502UL,0x0D1B30B0UL,0x3UL,0x0UL,0x0UL}}, 50 | {{0x68CA9EF4UL,0x32051179UL,0x22EDA6B8UL,0xDB9391ECUL,0x17F88440UL,0x3A514032UL,0xC1A39AB0UL,0x061UL}, 51 | {0x49314A3EUL,0x983B92C2UL,0x737B8FABUL,0xBF314919UL,0x5A01A0BCUL,0xD2F10F5BUL,0x4D4FDF13UL,0x0BEUL}}}; 52 | ec_point_aff G9[2] = {{{0x57394F5CUL,0x23D642E3UL,0x02FF0DDFUL,0x1993B9C9UL,0xFC3309ABUL,0x5UL,0x0UL,0x0UL}, 53 | {0x07DD78C9UL,0x8544EE5BUL,0x89E8C5C9UL,0x8B0253B6UL,0xA6C19961UL,0x4UL,0x0UL,0x0UL}}, 54 | {{0xA2046507UL,0x2D75F8EBUL,0xECC6183EUL,0x02374E1DUL,0x9C93CEEFUL,0x860B4C66UL,0x07861FE6UL,0x179UL}, 55 | {0x76EFC4A5UL,0xDFCDCCC1UL,0x52F6CA04UL,0x1AA40CEAUL,0xED2B1ACCUL,0xFE93521FUL,0x00254BDDUL,0x021UL}}}; 56 | ec_point_aff G11[2] = {{{0x5C534041UL,0x86217FDEUL,0xCE11A2B9UL,0x5727F0B7UL,0xC1722273UL,0x1UL,0x0UL,0x0UL}, 57 | {0x71A22148UL,0x7B870045UL,0x68F71342UL,0x41B0C99DUL,0x9BCB6731UL,0x4UL,0x0UL,0x0UL}}, 58 | {{0xF6090701UL,0x2C8A5469UL,0x48905717UL,0xDA1B1809UL,0xE45A3F40UL,0x7901EB9DUL,0x1D2E7C27UL,0x177UL}, 59 | {0xF2CF2426UL,0x501870BEUL,0x3985CC0AUL,0xF9EF9CDDUL,0x67D57436UL,0x71E708A8UL,0x10570BFDUL,0x1F5UL}}}; 60 | ec_point_aff G13[2] = {{{0x151346BBUL,0xEC1470B5UL,0xDAB99B8AUL,0x180B46D0UL,0xD51336A7UL,0x6UL,0x0UL,0x0UL}, 61 | {0xDDFB23FEUL,0x2A08EDA0UL,0x2A0721B1UL,0x6A21A61AUL,0x24037BDAUL,0x7UL,0x0UL,0x0UL}}, 62 | {{0x671660EAUL,0x4DFE234DUL,0xD54523CAUL,0x691C1256UL,0x02F90B6CUL,0xB29699FFUL,0x44924BD3UL,0x06DUL}, 63 | {0x7DD20370UL,0xDDCAF165UL,0x4A3F2621UL,0x99C5A435UL,0x43E06E7DUL,0x9B0D9641UL,0xF45D7BDEUL,0x02BUL}}}; 64 | ec_point_aff G15[2] = {{{0x5FDE2A56UL,0xC7EEF084UL,0x7764A39AUL,0xEEF24A99UL,0xA595788AUL,0x1UL,0x0UL,0x0UL}, 65 | {0xC41F467AUL,0x08922A85UL,0x514F8790UL,0xBF784D56UL,0x95D86326UL,0x5UL,0x0UL,0x0UL}}, 66 | {{0x94DD6F83UL,0x0199617BUL,0x55134A2CUL,0x4C74E5F6UL,0xFC6493FAUL,0x7DB601D9UL,0x3B30EE91UL,0x175UL}, 67 | {0x345CBEAFUL,0x20024B93UL,0xF705982CUL,0xF9197A73UL,0x7669FFE3UL,0x7600877FUL,0x89C093A4UL,0x1FCUL}}}; 68 | //Constants for partial reduction 69 | uint32 ec_s0[2][4] = {{0x73BDCB51UL,0xD1AD2426UL,0x22234UL,0x0UL},{0x10C103ABUL,0x3C775348UL,0xFFAFD49CUL,0x55D96UL}}; //s0 70 | uint32 ec_s1[2][4] = {{0x40112ADAUL,0x26B17BFCUL,0x09FF4UL,0x0UL},{0xCB36BEE6UL,0x16AA143CUL,0x2D7AE36EUL,0x882D7UL}}; //s1 71 | uint32 ec_s2[2][4] = {{0x802255B4UL,0x4D62F7F8UL,0x13FE8UL,0x0UL},{0x966D7DCCUL,0x2D542879UL,0x5AF5C6DCUL,0x1105AEUL}}; //s2=2*s1 72 | uint32 ec_s[2][4] = {{0x33ACA077UL,0xAAFBA82AUL,0x18240UL,0x0UL},{0xBA75BB3BUL,0xDA32C0F4UL,0x2DCB0ED1UL,0x32540UL}}; //s=s1-s0 73 | uint32 ec_Vm[2][4] = {{0x33F14BDDUL,0x45C1981BUL,0x40211UL,0x0UL},{0xC5CEAF7BUL,0xBBEC6B57UL,0xE456F351UL,0x1A756EUL}}; //Vm=2^m+1-#E_a(F_2^m) 74 | 75 | /******************************************************************************************** 76 | Point compression 77 | ********************************************************************************************/ 78 | void point_compression(ec_point_aff *P, uint32 *Pc, uint32 curve_id) 79 | { 80 | uint32 z[N], Num; 81 | 82 | switch(curve_id){ 83 | case sect163k1: 84 | if(IF0_163(P->x)) 85 | { 86 | if(IF0_163(P->y)) //P is infinity point 87 | { 88 | XIS0(Pc, 6); 89 | return; 90 | } 91 | *z = 0; 92 | } 93 | Num = 6; 94 | break; 95 | case sect233k1: 96 | if(IF0_233(P->x)) 97 | { 98 | if(IF0_233(P->y)) //P is infinity point 99 | { 100 | XIS0(Pc, 8); 101 | return; 102 | } 103 | *z = 0; 104 | } 105 | Num = 8; 106 | break; 107 | default: return; 108 | } 109 | 110 | modinv(P->x, z, curve_id); 111 | modmul(P->y, z, z, curve_id); 112 | 113 | XTOY(Pc, P->x, Num); 114 | 115 | if((*z & 0x1) == 0x0) 116 | { 117 | switch(curve_id){ 118 | case sect163k1: 119 | *(Pc + 5) |= 0x200; 120 | break; 121 | case sect233k1: 122 | *(Pc + 7) |= 0x20000; 123 | break; 124 | default: return; 125 | } 126 | } 127 | else 128 | { 129 | switch(curve_id){ 130 | case sect163k1: 131 | *(Pc + 5) |= 0x300; 132 | break; 133 | case sect233k1: 134 | *(Pc + 7) |= 0x30000; 135 | break; 136 | default: return; 137 | } 138 | } 139 | } 140 | 141 | /******************************************************************************************** 142 | Point decompression 143 | ********************************************************************************************/ 144 | uint32 point_decompression(uint32 *Pc, ec_point_aff *P, uint32 curve_id) 145 | { 146 | uint32 yp, Num, t; 147 | uint32 beta[N]; 148 | uint32 z[N]; 149 | 150 | switch(curve_id){ 151 | case sect163k1: 152 | Num = 6; 153 | XTOY(z, Pc, 6); 154 | if((*(z + 5) >> 8) == 0x2) yp = 0; 155 | else if((*(z + 5) >> 8) == 0x3) yp = 1; 156 | else return 0; 157 | *(z + 5) &= 0xff; 158 | t = IF0_163(Pc); 159 | break; 160 | case sect233k1: 161 | Num = 8; 162 | XTOY(z, Pc, 8); 163 | if((*(z + 7) >> 16) == 0x2) yp = 0; 164 | else if((*(z + 7) >> 16) == 0x3) yp = 1; 165 | else return 0; 166 | *(z + 7) &= 0xffff; 167 | t = IF0_233(Pc); 168 | break; 169 | default: return 0; 170 | } 171 | 172 | if(t) 173 | { 174 | XIS0(P->x, Num); 175 | XIS1(P->y, Num); 176 | return 1; 177 | } 178 | else 179 | { 180 | modinv(z,beta, curve_id); 181 | modsq(beta, beta, curve_id); 182 | modadd(z, beta, beta, curve_id); 183 | 184 | switch(curve_id){ 185 | case sect163k1: 186 | *beta ^= 0x1; 187 | if((*beta & 0x1) == ((*(beta + 4) >> 29) & 0x1)) //trace(c) = c0 + c157 188 | { 189 | halftrace(beta, beta, curve_id); 190 | if((*beta & 0x1) == yp) 191 | modmul(z, beta, P->y, curve_id); 192 | else 193 | { 194 | *beta ^= 0x1; 195 | modmul(z, beta, P->y, curve_id); 196 | } 197 | XTOY(P->x, z, Num); 198 | return 1; 199 | } 200 | else return 0; 201 | break; 202 | case sect233k1: 203 | if((*beta & 0x1) == (*(beta + 4) >> 31)) //trace(c) = c0 + c159 204 | { 205 | halftrace(beta, beta, curve_id); 206 | if((*beta & 0x1) == yp) 207 | modmul(z, beta, P->y, curve_id); 208 | else 209 | { 210 | *beta ^= 0x1; 211 | modmul(z, beta, P->y, curve_id); 212 | } 213 | XTOY(P->x, z, Num); 214 | return 1; 215 | } 216 | else return 0; 217 | break; 218 | default: return 0; 219 | } 220 | } 221 | } 222 | 223 | /******************************************************************************************** 224 | Point negation 225 | ********************************************************************************************/ 226 | void point_negation(ec_point_aff *P, ec_point_aff *negP, uint32 curve_id) 227 | { 228 | uint32 i, Num, t; 229 | 230 | switch(curve_id){ 231 | case sect163k1: 232 | Num = 6; 233 | t = (IF0_163(P->x) && IF0_163(P->y)); 234 | break; 235 | case sect233k1: 236 | Num = 8; 237 | t = (IF0_233(P->x) && IF0_233(P->y)); 238 | break; 239 | default: return; 240 | } 241 | 242 | if(t) 243 | { 244 | XIS0(negP->x, Num); 245 | XIS0(negP->y, Num); 246 | return; 247 | } 248 | 249 | XTOY(negP->x, P->x, Num); 250 | 251 | for(i = Num - 1; i != 0; i--) 252 | negP->y[i] = P->x[i]^ P->y[i]; 253 | negP->y[0] = P->x[0]^ P->y[0]; 254 | } 255 | 256 | /******************************************************************************************** 257 | Coordinate Transformation: LD to Affine 258 | ********************************************************************************************/ 259 | void project_to_affine(ec_point_pro *Qp, ec_point_aff *Qa, uint32 curve_id) 260 | { 261 | uint32 Zinv[N], Num, t; 262 | 263 | switch(curve_id){ 264 | case sect163k1: 265 | Num = 6; 266 | t = IF0_163(Qp->Z); 267 | break; 268 | case sect233k1: 269 | Num = 8; 270 | t = IF0_233(Qp->Z); 271 | break; 272 | default: return; 273 | } 274 | 275 | if(t) 276 | { 277 | XIS0(Qa->x, Num); 278 | XIS0(Qa->y, Num); 279 | return; 280 | } 281 | 282 | modinv(Qp->Z, Zinv, curve_id); 283 | modmul(Qp->X, Zinv, Qa->x, curve_id); 284 | modsq(Zinv, Zinv, curve_id); 285 | modmul(Qp->Y, Zinv, Qa->y, curve_id); 286 | } 287 | 288 | /******************************************************************************************* 289 | Coordinate Transformation: Affine to LD 290 | *******************************************************************************************/ 291 | void affine_to_project(ec_point_aff *Qa, ec_point_pro *Qp, uint32 curve_id) 292 | { 293 | uint32 Num; 294 | 295 | switch(curve_id){ 296 | case sect163k1: Num = 6; 297 | break; 298 | case sect233k1: Num = 8; 299 | break; 300 | default: return; 301 | } 302 | 303 | XTOY(Qp->X, Qa->x, Num); 304 | XTOY(Qp->Y, Qa->y, Num); 305 | XIS1(Qp->Z, Num); 306 | } 307 | 308 | /******************************************************************************************** 309 | Mixed-addition on Koblitz curve with LD coordinates 310 | *********************************************************************************************/ 311 | void mixed_addition(ec_point_pro *P, ec_point_aff *Q, ec_point_pro *R, uint32 curve_id) 312 | { 313 | uint32 T1[N], T2[N], T3[N]; 314 | uint32 Num, t1, t2; 315 | 316 | switch(curve_id){ 317 | case sect163k1: 318 | Num = 6; 319 | t1 = (IF0_163(Q->x) && IF0_163(Q->y)); 320 | t2 = IF0_163(P->Z); 321 | break; 322 | case sect233k1: 323 | Num = 8; 324 | t1 = (IF0_233(Q->x) && IF0_233(Q->y)); 325 | t2 = IF0_233(P->Z); 326 | break; 327 | default: return; 328 | } 329 | 330 | // If Q = infinity then return P 331 | if(t1) 332 | { 333 | XTOY(R->X, P->X, Num); 334 | XTOY(R->Y, P->Y, Num); 335 | XTOY(R->Z, P->Z, Num); 336 | return; 337 | } 338 | 339 | // If P = infinity then return (x2 : y2 : 1) 340 | if(t2) 341 | { 342 | XTOY(R->X, Q->x, Num); 343 | XTOY(R->Y, Q->y, Num); 344 | XIS1(R->Z, Num); 345 | return; 346 | } 347 | 348 | modmul(P->Z, Q->x, T1, curve_id); 349 | modsq(P->Z, T2, curve_id); 350 | modadd(P->X, T1, R->X, curve_id); 351 | modmul(P->Z, R->X, T1, curve_id); 352 | modmul(T2, Q->y, T3, curve_id); 353 | modadd(P->Y, T3, R->Y, curve_id); 354 | 355 | switch(curve_id){ 356 | case sect163k1: 357 | t1 = IF0_163(R->X); 358 | t2 = IF0_163(R->Y); 359 | break; 360 | case sect233k1: 361 | t1 = IF0_233(R->X); 362 | t2 = IF0_233(R->Y); 363 | break; 364 | default: return; 365 | } 366 | 367 | if(t1) 368 | { 369 | if(t2) 370 | { 371 | affine_to_project(Q, P, curve_id); 372 | point_doubling(P, R, curve_id); 373 | return; 374 | } 375 | else 376 | { 377 | XIS1(R->X, Num); 378 | XIS0(R->Y, Num); 379 | XIS0(R->Z, Num); 380 | return; 381 | } 382 | } 383 | modsq(T1, R->Z, curve_id); 384 | modmul(T1, R->Y, T3, curve_id); 385 | if(curve_id == sect163k1) 386 | modadd(T1, T2, T1, curve_id); 387 | modsq(R->X, T2, curve_id); 388 | modmul(T2, T1, R->X, curve_id); 389 | modsq(R->Y, T2, curve_id); 390 | modadd(R->X, T2, R->X, curve_id); 391 | modadd(R->X, T3, R->X, curve_id); 392 | modmul(Q->x, R->Z, T2,curve_id); 393 | modadd(T2, R->X, T2, curve_id); 394 | modsq(R->Z, T1, curve_id); 395 | modadd(T3, R->Z, T3, curve_id); 396 | modmul(T3, T2, R->Y, curve_id); 397 | modadd(Q->x, Q->y, T2, curve_id); 398 | modmul(T1, T2, T3, curve_id); 399 | modadd(R->Y, T3, R->Y, curve_id); 400 | } 401 | 402 | /********************************************************************************************* 403 | Doubling on Koblitz curves with LD coordinates 404 | *********************************************************************************************/ 405 | void point_doubling(ec_point_pro *P, ec_point_pro *Q, uint32 curve_id) 406 | { 407 | uint32 T1[N], T2[N]; 408 | uint32 Num, t; 409 | 410 | switch(curve_id){ 411 | case sect163k1: 412 | Num = 6; 413 | t = IF0_163(P->Z); 414 | break; 415 | case sect233k1: 416 | Num = 8; 417 | t = IF0_233(P->Z); 418 | break; 419 | default: return; 420 | } 421 | 422 | // If P = infinity then return infinity 423 | if(t) 424 | { 425 | XIS1(Q->X, Num); 426 | XIS0(Q->Y, Num); 427 | XIS0(Q->Z, Num); 428 | return; 429 | } 430 | 431 | modsq(P->Z, T1, curve_id); 432 | modsq(P->X, T2, curve_id); 433 | modmul(T1, T2, Q->Z, curve_id); 434 | modsq(T2, Q->X, curve_id); 435 | modsq(T1, T1, curve_id); 436 | modadd(Q->X, T1, Q->X, curve_id); 437 | modsq(P->Y, T2, curve_id); 438 | if(curve_id == sect163k1) 439 | modadd(T2, Q->Z, T2, curve_id); 440 | modadd(T1, T2, T2, curve_id); 441 | modmul(Q->X, T2, Q->Y, curve_id); 442 | modmul(T1, Q->Z, T2, curve_id); 443 | modadd(Q->Y, T2, Q->Y, curve_id); 444 | } 445 | 446 | /******************************************************************************************** 447 | Frobenius endomorphism on Koblitz curves 448 | ********************************************************************************************/ 449 | void point_frobenius(ec_point_pro *P, uint32 curve_id) 450 | { 451 | uint32 Num, t; 452 | 453 | switch(curve_id){ 454 | case sect163k1: 455 | Num = 6; 456 | t = IF0_163(P->Z); 457 | break; 458 | case sect233k1: 459 | Num = 8; 460 | t = IF0_233(P->Z); 461 | break; 462 | default: return; 463 | } 464 | 465 | if(t) 466 | { 467 | XIS1(P->X, Num); 468 | XIS0(P->Y, Num); 469 | return; 470 | } 471 | modsq(P->X, P->X, curve_id); 472 | modsq(P->Y, P->Y, curve_id); 473 | modsq(P->Z, P->Z, curve_id); 474 | } 475 | 476 | /******************************************************************************************** 477 | Compute the partial modular reduction of an element in Z[t] 478 | ********************************************************************************************/ 479 | void partial_mod(uint32 *k, uint32 *r0, uint32 *r1, uint32 curve_id) 480 | { 481 | uint32 kp[5] = {0x0}; 482 | uint32 gp[8] = {0x0}; 483 | uint32 jp[5] = {0x0}; 484 | uint32 fp[5] = {0x0}; 485 | uint64 T1, T2, T3; 486 | uint32 lamda0i[4], lamda1i[4]; //integer part of lamda0 and lamda1 487 | sint32 lamda0f, lamda1f; //fraction part of lamda0 and lamda1 488 | sint32 h0, h1, lamda; 489 | uint32 i, j, t, u, v, w, Num; 490 | 491 | //k' = [k/2^(a - C + (m - 9)/2)] 492 | switch(curve_id){ 493 | case sect163k1: 494 | Num = 6; 495 | t = 3; //t = Num/2 496 | u = 3; 497 | v = 0x80000; // + 2^83 498 | w = 0x0; 499 | break; 500 | case sect233k1: 501 | Num = 8; 502 | t = 4; //t = Num/2 503 | u = 9; 504 | v = 0x0; 505 | w = 0x400000; // + 2^118 506 | break; 507 | default: return; 508 | } 509 | for(i = t; i != 0; i--) 510 | *(kp + i) = *(k + i + (t - 1)); 511 | *kp = *(k + (t - 1)); 512 | 513 | //g' = s0 * k' 514 | T1 = (uint64)(*(ec_s0[curve_id])) * (*kp); 515 | *gp = (uint32)T1; 516 | T1 = T1 >> 32; 517 | 518 | for(i = 1; i < Num - 1; i++) 519 | { 520 | T3 = 0; 521 | for(j = (i <= t ? 0 : (i - t)); j <= (i < t ? i : (t - 1)); j++) 522 | { 523 | T2 = (uint64)(*(ec_s0[curve_id] + j)) * (*(kp + (i - j))); 524 | T1 += (uint32)T2; 525 | T3 += (T2 >> 32); 526 | } 527 | *(gp + i) = (uint32)T1; 528 | T1 = (T1 >> 32) + T3; 529 | } 530 | 531 | *(gp + (Num - 1)) = (uint32)T1 + (*(ec_s0[curve_id] + (t - 1))) * (*(kp + t)); 532 | 533 | //j'=Vm*[g'/2^m] 534 | T1 = (uint64)(*(gp + (Num - 1)) >> u); 535 | 536 | if(T1 != 0) 537 | { 538 | T2 = T1 * (*(ec_Vm[curve_id])); 539 | *jp = (uint32)T2; 540 | T2 = T2 >> 32; 541 | 542 | T3 = T1 * (*(ec_Vm[curve_id] + 1)); 543 | T2 += (uint32)T3; 544 | *(jp + 1) = (uint32)T2; 545 | T2 = (T2 >> 32) + (T3 >> 32); 546 | 547 | T3 = T1 * (*(ec_Vm[curve_id] + 2)); 548 | T2 += (uint32)T3; 549 | *(jp + 2) = (uint32)T2; 550 | 551 | switch(curve_id){ 552 | case sect163k1: 553 | *(jp + 3) = (uint32)(T2 >> 32) + (uint32)(T3 >> 32); 554 | break; 555 | case sect233k1: 556 | T2 = (T2 >> 32) + (T3 >> 32); 557 | 558 | T3 = T1 * (*(ec_Vm[curve_id] + 3)); 559 | T2 += (uint32)T3; 560 | *(jp + 3) = (uint32)T2; 561 | *(jp + 4) = (uint32)(T2 >> 32) + (uint32)(T3 >> 32); 562 | break; 563 | default: return; 564 | } 565 | } 566 | 567 | //Rounding off in Z[t] 568 | T1 = (uint64)(*gp) + ~(*jp) + 0x1; 569 | T2 = T1 >> 32; 570 | *gp = (uint32)T1; 571 | 572 | T1 = T2 + (*(gp + 1)) + ~(*(jp + 1)); 573 | T2 = T1 >> 32; 574 | *(gp + 1) = (uint32)T1; 575 | 576 | T1 = T2 + (*(gp + 2)) + ~(*(jp + 2)) + v; 577 | T2 = T1 >> 32; 578 | *(gp + 2) = (uint32)T1; 579 | 580 | T1 = T2 + (*(gp + 3)) + ~(*(jp + 3)) + w; 581 | T2 = T1 >> 32; 582 | *(gp + 3) = (uint32)T1; 583 | 584 | switch(curve_id){ 585 | case sect163k1: 586 | T1 = T2 + (*(gp + 4)) + 0xffffffff; 587 | T2 = T1 >> 32; 588 | *(gp + 4) = (uint32)T1; 589 | *(gp + 5) += (uint32)T2 + 0xffffffff; 590 | 591 | //Obtain the fraction part of lamda0 592 | lamda0f = (sint32)((*(gp + 2) >> 20) | ((*(gp + 3) & 0x3) << 12)); //the faction of lamda0 is 14 bits 593 | v = 2; 594 | w = 30; 595 | break; 596 | case sect233k1: 597 | T1 = T2 + (*(gp + 4)) + ~(*(jp + 4)); 598 | T2 = T1 >> 32; 599 | *(gp + 4) = (uint32)T1; 600 | 601 | T1 = T2 + (*(gp + 5)) + 0xffffffff; 602 | T2 = T1 >> 32; 603 | *(gp + 5) = (uint32)T1; 604 | 605 | T1 = T2 + (*(gp + 6)) + 0xffffffff; 606 | T2 = T1 >> 32; 607 | *(gp + 6) = (uint32)T1; 608 | *(gp + 7) += (uint32)T2 + 0xffffffff; 609 | 610 | //Obtain the fraction part of lamda0 611 | lamda0f = (sint32)((*(gp + 3) >> 23) | ((*(gp + 4) & 0x7f) << 9)); //the faction of lamda0 is 16 bits 612 | v = 7; 613 | w = 25; 614 | break; 615 | default: return; 616 | } 617 | 618 | //Obtain the integer part of lamda0 619 | *(lamda0i + (t - 1)) = *(gp + (Num - 1)) >> v; 620 | for(i = t - 2; i != 0; i--) 621 | *(lamda0i + i) = (*(gp + i + t) >> v) | (*(gp + i + t + 1) << w); 622 | *(lamda0i) = (*(gp + t) >> v) | (*(gp + t + 1) << w); 623 | 624 | //round(lamda0) 625 | switch(curve_id){ 626 | case sect163k1: 627 | if((lamda0f & 0x2000) == 0x2000) 628 | { 629 | for(j = 0; j < 3; j++) 630 | { 631 | if(*(lamda0i + j) == 0xffffffff) *(lamda0i + j) = 0; 632 | else 633 | { 634 | lamda0i[j]++; 635 | break; 636 | } 637 | } 638 | lamda0f = lamda0f - 0x4000; 639 | } 640 | v = 0x80000; // + 2^83 641 | w = 0x0; 642 | break; 643 | case sect233k1: 644 | if((lamda0f & 0x8000) == 0x8000) 645 | { 646 | for(j = 0; j < t; j++) 647 | { 648 | if(*(lamda0i + j) == 0xffffffff) *(lamda0i + j) = 0; 649 | else 650 | { 651 | lamda0i[j]++; 652 | break; 653 | } 654 | } 655 | lamda0f = 0x10000 - lamda0f; 656 | } 657 | else 658 | { 659 | lamda0f = -lamda0f; 660 | } 661 | v = 0x0; 662 | w = 0x400000; // + 2^118 663 | break; 664 | default: return; 665 | } 666 | 667 | //g' = s1 * k' 668 | T1 = (uint64)(*(ec_s1[curve_id])) * (*kp); 669 | *gp = (uint32)T1; 670 | T1 = T1 >> 32; 671 | 672 | for(i = 1; i < Num - 1; i++) 673 | { 674 | T3 = 0; 675 | for(j = (i <= t ? 0 : (i - t)); j <= (i < t ? i : (t - 1)); j++) 676 | { 677 | T2 = (uint64)(*(ec_s1[curve_id] + j)) * (*(kp + (i - j))); 678 | T1 += (uint32)T2; 679 | T3 += (T2 >> 32); 680 | } 681 | *(gp + i) = (uint32)T1; 682 | T1 = (T1 >> 32) + T3; 683 | } 684 | 685 | *(gp + (Num - 1)) = (uint32)T1 + (*(ec_s1[curve_id] + (t - 1))) * (*(kp + t)); 686 | 687 | //j'=Vm*[g'/2^m], sign: +, 136 bits 688 | T1 = (uint64)(*(gp + (Num - 1)) >> u); 689 | 690 | if(T1 != 0) 691 | { 692 | T2 = T1 * (*(ec_Vm[curve_id])); 693 | *jp = (uint32)T2; 694 | T2 = T2 >> 32; 695 | 696 | T3 = T1 * (*(ec_Vm[curve_id] + 1)); 697 | T2 += (uint32)T3; 698 | *(jp + 1) = (uint32)T2; 699 | T2 = (T2 >> 32) + (T3 >> 32); 700 | 701 | T3 = T1 * (*(ec_Vm[curve_id] + 2)); 702 | T2 += (uint32)T3; 703 | *(jp + 2) = (uint32)T2; 704 | 705 | switch(curve_id){ 706 | case sect163k1: 707 | *(jp + 3) = (uint32)(T2 >> 32) + (uint32)(T3 >> 32); 708 | break; 709 | case sect233k1: 710 | T2 = (T2 >> 32) + (T3 >> 32); 711 | 712 | T3 = T1 * (*(ec_Vm[0] + curve_id * 4 + 3)); 713 | T2 += (uint32)T3; 714 | *(jp + 3) = (uint32)T2; 715 | *(jp + 4) = (uint32)(T2 >> 32) + (uint32)(T3 >> 32); 716 | break; 717 | default: return; 718 | } 719 | } 720 | 721 | //Rounding off in Z[t] 722 | T1 = (uint64)(*gp) + ~(*jp) + 0x1; 723 | T2 = T1 >> 32; 724 | *gp = (uint32)T1; 725 | 726 | T1 = T2 + (*(gp + 1)) + ~(*(jp + 1)); 727 | T2 = T1 >> 32; 728 | *(gp + 1) = (uint32)T1; 729 | 730 | T1 = T2 + (*(gp + 2)) + ~(*(jp + 2)) + v; 731 | T2 = T1 >> 32; 732 | *(gp + 2) = (uint32)T1; 733 | 734 | T1 = T2 + (*(gp + 3)) + ~(*(jp + 3)) + w; 735 | T2 = T1 >> 32; 736 | *(gp + 3) = (uint32)T1; 737 | 738 | switch(curve_id){ 739 | case sect163k1: 740 | T1 = T2 + (*(gp + 4)) + 0xffffffff; 741 | T2 = T1 >> 32; 742 | *(gp + 4) = (uint32)T1; 743 | *(gp + 5) += (uint32)T2 + 0xffffffff; 744 | 745 | //Obtain the fraction part of lamda1 746 | lamda1f = (sint32)((*(gp + 2) >> 20) | ((*(gp + 3) & 0x3) << 12)); //the faction of lamda0 is 14 bits 747 | v = 2; 748 | w = 30; 749 | break; 750 | case sect233k1: 751 | T1 = T2 + (*(gp + 4)) + ~(*(jp + 4)); 752 | T2 = T1 >> 32; 753 | *(gp + 4) = (uint32)T1; 754 | 755 | T1 = T2 + (*(gp + 5)) + 0xffffffff; 756 | T2 = T1 >> 32; 757 | *(gp + 5) = (uint32)T1; 758 | 759 | T1 = T2 + (*(gp + 6)) + 0xffffffff; 760 | T2 = T1 >> 32; 761 | *(gp + 6) = (uint32)T1; 762 | *(gp + 7) += (uint32)T2 + 0xffffffff; 763 | 764 | //Obtain the fraction part of lamda1 765 | lamda1f = (sint32)((*(gp + 3) >> 23) | ((*(gp + 4) & 0x7f) << 9)); //the faction of lamda0 is 16 bits 766 | v = 7; 767 | w = 25; 768 | break; 769 | default: return; 770 | } 771 | 772 | //Obtain the integer part of lamda1 773 | *(lamda1i + (t - 1)) = *(gp + (Num - 1)) >> v; 774 | for(i = t - 2; i != 0; i--) 775 | *(lamda1i + i) = (*(gp + i + t) >> v) | (*(gp + i + t + 1) << w); 776 | *(lamda1i) = (*(gp + t) >> v) | (*(gp + t + 1) << w); 777 | 778 | h0 = 0; 779 | h1 = 0; 780 | 781 | //round(lamda1) 782 | switch(curve_id){ 783 | case sect163k1: 784 | if((lamda1f & 0x2000) == 0x2000) 785 | { 786 | for(j = 0; j < 3; j++) 787 | { 788 | if(*(lamda1i + j) == 0xffffffff) *(lamda1i + j) = 0; 789 | else 790 | { 791 | lamda1i[j]++; 792 | break; 793 | } 794 | } 795 | lamda1f = 0x4000 - lamda1f; 796 | } 797 | else 798 | { 799 | lamda1f = -lamda1f; 800 | } 801 | 802 | //eta=2*eta0+eta1 803 | lamda = 2*lamda0f + lamda1f; 804 | 805 | if(lamda >= 0x4000) 806 | { 807 | if((lamda0f - 3*lamda1f) < -0x4000) h1 = 1; 808 | else h0 = 1; 809 | } 810 | else 811 | { 812 | if((lamda0f + 4*lamda1f) >= 0x8000) h1 = 1; 813 | } 814 | 815 | if(lamda < -0x4000) 816 | { 817 | if((lamda0f - 3*lamda1f) >= 0x4000) h1 = -1; 818 | else h0 = -1; 819 | } 820 | else 821 | { 822 | if((lamda0f + 4*lamda1f) < -0x8000) h1 = -1; 823 | } 824 | break; 825 | case sect233k1: 826 | if((lamda1f & 0x8000) == 0x8000) 827 | { 828 | for(j = 0; j < 4; j++) 829 | { 830 | if(*(lamda1i + j) == 0xffffffff) *(lamda1i + j) = 0; 831 | else 832 | { 833 | lamda1i[j]++; 834 | break; 835 | } 836 | } 837 | lamda1f = 0x10000 - lamda1f; 838 | } 839 | else 840 | { 841 | lamda1f = -lamda1f; 842 | } 843 | 844 | //eta = 2*eta0 + eta1 845 | lamda = 2*lamda0f - lamda1f; 846 | 847 | if(lamda >= 0x10000) 848 | { 849 | if((lamda0f + 3*lamda1f) < -0x10000) h1 = -1; 850 | else h0 = 1; 851 | } 852 | else 853 | { 854 | if((lamda0f - 4*lamda1f) >= 0x20000) h1 = -1; 855 | } 856 | 857 | if(lamda < -0x10000) 858 | { 859 | if((lamda0f + 3*lamda1f) >= 0x10000) h1 = 1; 860 | else h0 = -1; 861 | } 862 | else 863 | { 864 | if((lamda0f - 4*lamda1f) < -0x20000) h1 = 1; 865 | } 866 | break; 867 | default: return; 868 | } 869 | 870 | //q0 = f0 + h0 871 | if(h0 != 0) 872 | { 873 | if(h0 == 1) 874 | { 875 | switch(curve_id){ 876 | case sect163k1: 877 | for(j = 0; j < 3; j++) 878 | { 879 | if(*(lamda0i + j) == 0xffffffff) *(lamda0i + j) = 0; 880 | else 881 | { 882 | lamda0i[j]++; 883 | break; 884 | } 885 | } 886 | break; 887 | case sect233k1: 888 | T1 = (uint64)(*lamda0i) + 0xffffffff; 889 | T2 = T1 >> 32; 890 | *lamda0i = (uint32)T1; 891 | 892 | T1 = T2 + (*(lamda0i + 1)) + 0xffffffff; 893 | T2 = T1 >> 32; 894 | *(lamda0i + 1) = (uint32)T1; 895 | 896 | T1 = T2 + (*(lamda0i + 2)) + 0xffffffff; 897 | T2 = T1 >> 32; 898 | *(lamda0i + 2) = (uint32)T1; 899 | 900 | *(lamda0i + 3) += (uint32)T2 + 0xffffffff; 901 | break; 902 | default: return; 903 | } 904 | } 905 | else 906 | { 907 | switch(curve_id){ 908 | case sect163k1: 909 | T1 = (uint64)(*lamda0i) + 0xffffffff; 910 | T2 = T1 >> 32; 911 | *lamda0i = (uint32)T1; 912 | 913 | T1 = T2 + (*(lamda0i + 1)) + 0xffffffff; 914 | T2 = T1 >> 32; 915 | *(lamda0i + 1) = (uint32)T1; 916 | 917 | *(lamda0i + 2) += (uint32)T2 + 0xffffffff; 918 | break; 919 | case sect233k1: 920 | for(j = 0; j < 4; j++) 921 | { 922 | if(*(lamda0i + j) == 0xffffffff) *(lamda0i + j) = 0; 923 | else 924 | { 925 | lamda0i[j]++; 926 | break; 927 | } 928 | } 929 | break; 930 | default: return; 931 | } 932 | } 933 | } 934 | 935 | //q1 = f1 + h1 936 | if(h1 != 0) 937 | { 938 | if(h1 == 1) 939 | { 940 | switch(curve_id){ 941 | case sect163k1: 942 | T1 = (uint64)(*lamda1i) + 0xffffffff; 943 | T2 = T1 >> 32; 944 | *lamda1i = (uint32)T1; 945 | 946 | T1 = T2 + (*(lamda1i + 1)) + 0xffffffff; 947 | T2 = T1 >> 32; 948 | *(lamda1i + 1) = (uint32)T1; 949 | 950 | *(lamda1i + 2) += (uint32)T2 + 0xffffffff; 951 | break; 952 | case sect233k1: 953 | for(j = 0; j < 4; j++) 954 | { 955 | if(*(lamda1i + j) == 0xffffffff) *(lamda1i + j) = 0; 956 | else 957 | { 958 | lamda1i[j]++; 959 | break; 960 | } 961 | } 962 | break; 963 | default: return; 964 | } 965 | } 966 | else 967 | { 968 | switch(curve_id){ 969 | case sect163k1: 970 | for(j = 0; j < 3; j++) 971 | { 972 | if(*(lamda1i + j) == 0xffffffff) *(lamda1i + j) = 0; 973 | else 974 | { 975 | lamda1i[j]++; 976 | break; 977 | } 978 | } 979 | break; 980 | case sect233k1: 981 | T1 = (uint64)(*lamda1i) + 0xffffffff; 982 | T2 = T1 >> 32; 983 | *lamda1i = (uint32)T1; 984 | 985 | T1 = T2 + (*(lamda1i + 1)) + 0xffffffff; 986 | T2 = T1 >> 32; 987 | *(lamda1i + 1) = (uint32)T1; 988 | 989 | T1 = T2 + (*(lamda1i + 2)) + 0xffffffff; 990 | T2 = T1 >> 32; 991 | *(lamda1i + 2) = (uint32)T1; 992 | 993 | *(lamda1i + 3) += (uint32)T2 + 0xffffffff; 994 | break; 995 | default: return; 996 | } 997 | } 998 | } 999 | 1000 | //s * f0 1001 | T1 = (uint64)(*(ec_s[curve_id])) * (*lamda0i); 1002 | *fp = (uint32)T1; 1003 | T1 = T1 >> 32; 1004 | 1005 | for(i = 1; i < t; i++) 1006 | { 1007 | T3 = 0; 1008 | for(j = 0; j <= i; j++) 1009 | { 1010 | T2 = (uint64)(*(ec_s[curve_id] + j)) * (*(lamda0i + (i - j))); 1011 | T1 += (uint32)T2; 1012 | T3 += (T2 >> 32); 1013 | } 1014 | *(fp + i) = (uint32)T1; 1015 | T1 = (T1 >> 32) + T3; 1016 | } 1017 | 1018 | switch(curve_id){ 1019 | case sect163k1: 1020 | T2 = (uint64)(*(ec_s[curve_id] + 1)) * (*(lamda0i + 2)); 1021 | T1 = T1 + (uint32)T2; 1022 | *(fp + 3) = (uint32)T1 + (*(ec_s[curve_id] + 2)) * (*(lamda0i + 1)); 1023 | break; 1024 | case sect233k1: 1025 | T2 = (uint64)(*(ec_s[curve_id] + 1)) * (*(lamda0i + 3)); 1026 | T1 = T1 + (uint32)T2; 1027 | T2 = (uint64)(*(ec_s[curve_id] + 2)) * (*(lamda0i + 2)); 1028 | T1 = T1 + (uint32)T2; 1029 | *(fp + 4) = (uint32)T1 + (*(ec_s[curve_id] + 3)) * (*(lamda0i + 1)); 1030 | break; 1031 | default: return; 1032 | } 1033 | 1034 | //s2 * f1 1035 | T1 = (uint64)(*(ec_s2[curve_id])) * (*lamda1i); 1036 | *gp = (uint32)T1; 1037 | T1 = T1 >> 32; 1038 | 1039 | for(i = 1; i < t; i++) 1040 | { 1041 | T3 = 0; 1042 | for(j = 0; j <= i; j++) 1043 | { 1044 | T2 = (uint64)(*(ec_s2[curve_id] + j)) * (*(lamda1i + (i - j))); 1045 | T1 += (uint32)T2; 1046 | T3 += (T2 >> 32); 1047 | } 1048 | *(gp + i) = (uint32)T1; 1049 | T1 = (T1 >> 32) + T3; 1050 | } 1051 | 1052 | switch(curve_id){ 1053 | case sect163k1: 1054 | T2 = (uint64)(*(ec_s2[curve_id] + 1)) * (*(lamda1i + 2)); 1055 | T1 = T1 + (uint32)T2; 1056 | *(gp + 3) = (uint32)T1 + (*(ec_s2[curve_id] + 2)) * (*(lamda1i + 1)); 1057 | 1058 | //r0 = k - (|fp| + |gp|) 1059 | T1 = (uint64)(*fp) + (*gp); 1060 | T2 = T1 >> 32; 1061 | *fp = (uint32)T1; 1062 | 1063 | T1 = T2 + (*(fp + 1)) + (*(gp + 1)); 1064 | T2 = T1 >> 32; 1065 | *(fp + 1) = (uint32)T1; 1066 | 1067 | T1 = T2 + (*(fp + 2)) + (*(gp + 2)); 1068 | T2 = T1 >> 32; 1069 | *(fp + 2) = (uint32)T1; 1070 | 1071 | *(fp + 3) = (uint32)T2 + (*(fp + 3)) + (*(gp + 3)); 1072 | 1073 | if(compare(k, fp, 4) == 1) 1074 | { 1075 | T1 = (uint64)(*k) + ~(*fp) + 0x1; 1076 | T2 = T1 >> 32; 1077 | *r0 = (uint32)T1; 1078 | 1079 | T1 = T2 + (*(k + 1)) + ~(*(fp + 1)); 1080 | j = (uint32)(T1 >> 32); 1081 | *(r0 + 1) = (uint32)T1; 1082 | *(r0 + 2) = (*(k + 2)) + ~(*(fp + 2)) + j; 1083 | *(r0 + 3) = 1; 1084 | } 1085 | else if(compare(k, fp, 4) == -1) 1086 | { 1087 | T1 = (uint64)(*fp) + ~(*k) + 0x1; 1088 | T2 = T1 >> 32; 1089 | *r0 = (uint32)T1; 1090 | 1091 | T1 = T2 + (*(fp + 1)) + ~(*(k + 1)); 1092 | j = (uint32)(T1 >> 32); 1093 | *(r0 + 1) = (uint32)T1; 1094 | *(r0 + 2) = (*(fp + 2)) + ~(*(k + 2)) + j; 1095 | *(r0 + 3) = 2; 1096 | } 1097 | else 1098 | { 1099 | for(i = 0; i < 4; i++) 1100 | *(r0 + i) = 0; 1101 | } 1102 | break; 1103 | case sect233k1: 1104 | T2 = (uint64)(*(ec_s2[curve_id] + 1)) * (*(lamda1i + 3)); 1105 | T1 = T1 + (uint32)T2; 1106 | T2 = (uint64)(*(ec_s2[curve_id] + 2)) * (*(lamda1i + 2)); 1107 | T1 = T1 + (uint32)T2; 1108 | *(gp + 4) = (uint32)T1 + (*(ec_s2[curve_id] + 3)) * (*(lamda1i + 1)); 1109 | 1110 | //r0 = (k + |fp|) - |gp| 1111 | T1 = (uint64)(*k) + (*fp); 1112 | T2 = T1 >> 32; 1113 | *fp = (uint32)T1; 1114 | 1115 | for(i = 1; i < 4; i++) 1116 | { 1117 | T1 = T2 + (*(k + i)) + (*(fp + i)); 1118 | T2 = T1 >> 32; 1119 | *(fp + i) = (uint32)T1; 1120 | } 1121 | 1122 | *(fp + 4) = (uint32)T2 + *(k + 4) + *(fp + 4); 1123 | 1124 | if(compare(fp, gp, 5) == 1) 1125 | { 1126 | T1 = (uint64)(*fp) + ~(*gp) + 0x1; 1127 | T2 = T1 >> 32; 1128 | *r0 = (uint32)T1; 1129 | 1130 | T1 = T2 + (*(fp + 1)) + ~(*(gp + 1)); 1131 | T2 = T1 >> 32; 1132 | *(r0 + 1) = (uint32)T1; 1133 | 1134 | T1 = T2 + (*(fp + 2)) + ~(*(gp + 2)); 1135 | j = (uint32)(T1 >> 32); 1136 | *(r0 + 2) = (uint32)T1; 1137 | *(r0 + 3) = (*(fp + 3)) + ~(*(gp + 3)) + j; 1138 | *(r0 + 4) = 1; 1139 | } 1140 | else if(compare(fp, gp, 5) == -1) 1141 | { 1142 | T1 = (uint64)(*gp) + ~(*fp) + 0x1; 1143 | T2 = T1 >> 32; 1144 | *r0 = (uint32)T1; 1145 | 1146 | T1 = T2 + (*(gp + 1)) + ~(*(fp + 1)); 1147 | T2 = T1 >> 32; 1148 | *(r0 + 1) = (uint32)T1; 1149 | 1150 | T1 = T2 + (*(gp + 2)) + ~(*(fp + 2)); 1151 | j = (uint32)(T1 >> 32); 1152 | *(r0 + 2) = (uint32)T1; 1153 | *(r0 + 3) = (*(gp + 3)) + ~(*(fp + 3)) + j; 1154 | *(r0 + 4) = 2; 1155 | } 1156 | else 1157 | { 1158 | for(i = 0; i < 5; i++) 1159 | *(r0 + i) = 0; 1160 | } 1161 | break; 1162 | default: return; 1163 | } 1164 | 1165 | //|s0|*f1 1166 | T1 = (uint64)(*(ec_s0[curve_id])) * (*lamda1i); 1167 | *fp = (uint32)T1; 1168 | T1 = T1 >> 32; 1169 | 1170 | for(i = 1; i < t; i++) 1171 | { 1172 | T3 = 0; 1173 | for(j = 0; j <= i; j++) 1174 | { 1175 | T2 = (uint64)(*(ec_s0[curve_id] + j)) * (*(lamda1i + (i - j))); 1176 | T1 += (uint32)T2; 1177 | T3 += (T2 >> 32); 1178 | } 1179 | *(fp + i) = (uint32)T1; 1180 | T1 = (T1 >> 32) + T3; 1181 | } 1182 | 1183 | switch(curve_id){ 1184 | case sect163k1: 1185 | T2 = (uint64)(*(ec_s0[curve_id] + 1)) * (*(lamda1i + 2)); 1186 | T1 = T1 + (uint32)T2; 1187 | *(fp + 3) = (uint32)T1 + (*(ec_s0[curve_id] + 2)) * (*(lamda1i + 1)); 1188 | break; 1189 | case sect233k1: 1190 | T2 = (uint64)(*(ec_s0[curve_id] + 1)) * (*(lamda1i + 3)); 1191 | T1 = T1 + (uint32)T2; 1192 | T2 = (uint64)(*(ec_s0[curve_id] + 2)) * (*(lamda1i + 2)); 1193 | T1 = T1 + (uint32)T2; 1194 | *(fp + 4) = (uint32)T1 + (*(ec_s0[curve_id] + 3)) * (*(lamda1i + 1)); 1195 | break; 1196 | default: return; 1197 | } 1198 | 1199 | //|s1|*f0 1200 | T1 = (uint64)(*(ec_s1[curve_id])) * (*lamda0i); 1201 | *gp = (uint32)T1; 1202 | T1 = T1 >> 32; 1203 | 1204 | for(i = 1; i < t; i++) 1205 | { 1206 | T3 = 0; 1207 | for(j = 0; j <= i; j++) 1208 | { 1209 | T2 = (uint64)(*(ec_s1[curve_id] + j)) * (*(lamda0i + (i - j))); 1210 | T1 += (uint32)T2; 1211 | T3 += (T2 >> 32); 1212 | } 1213 | *(gp + i) = (uint32)T1; 1214 | T1 = (T1 >> 32) + T3; 1215 | } 1216 | 1217 | switch(curve_id){ 1218 | case sect163k1: 1219 | T2 = (uint64)(*(ec_s1[0] + curve_id * 4 + 1)) * (*(lamda0i + 2)); 1220 | T1 = T1 + (uint32)T2; 1221 | *(gp + 3) = (uint32)T1 + (*(ec_s1[0] + curve_id * 4 + 2)) * (*(lamda0i + 1)); 1222 | 1223 | //r1 = fp - gp 1224 | if(compare(fp, gp, 4) == 1) 1225 | { 1226 | T1 = (uint64)(*fp) + ~(*gp) + 0x1; 1227 | T2 = T1 >> 32; 1228 | *r1 = (uint32)T1; 1229 | 1230 | T1 = T2 + (*(fp + 1)) + ~(*(gp + 1)); 1231 | j = (uint32)(T1 >> 32); 1232 | *(r1 + 1) = (uint32)T1; 1233 | *(r1 + 2) = (*(fp + 2)) + ~(*(gp + 2)) + j; 1234 | *(r1 + 3) = 1; 1235 | } 1236 | else if(compare(fp, gp, 4) == -1) 1237 | { 1238 | T1 = (uint64)(*gp) + ~(*fp) + 0x1; 1239 | T2 = T1 >> 32; 1240 | *r1 = (uint32)T1; 1241 | 1242 | T1 = T2 + (*(gp + 1)) + ~(*(fp + 1)); 1243 | j = (uint32)(T1 >> 32); 1244 | *(r1 + 1) = (uint32)T1; 1245 | *(r1 + 2) = (*(gp + 2)) + ~(*(fp + 2)) + j; 1246 | *(r1 + 3) = 2; 1247 | } 1248 | else 1249 | { 1250 | for(i = 0; i < 4; i++) 1251 | *(r1 + i) = 0; 1252 | } 1253 | break; 1254 | case sect233k1: 1255 | T2 = (uint64)(*(ec_s1[curve_id] + 1)) * (*(lamda0i + 3)); 1256 | T1 = T1 + (uint32)T2; 1257 | T2 = (uint64)(*(ec_s1[curve_id] + 2)) * (*(lamda0i + 2)); 1258 | T1 = T1 + (uint32)T2; 1259 | *(gp + 4) = (uint32)T1 + (*(ec_s1[curve_id] + 3)) * (*(lamda0i + 1)); 1260 | 1261 | //r1 = gp - fp 1262 | if(compare(gp, fp, 5) == 1) 1263 | { 1264 | T1 = (uint64)(*gp) + ~(*fp) + 0x1; 1265 | T2 = T1 >> 32; 1266 | *r1 = (uint32)T1; 1267 | 1268 | T1 = T2 + (*(gp + 1)) + ~(*(fp + 1)); 1269 | T2 = T1 >> 32; 1270 | *(r1 + 1) = (uint32)T1; 1271 | 1272 | T1 = T2 + (*(gp + 2)) + ~(*(fp + 2)); 1273 | j = (uint32)(T1 >> 32); 1274 | *(r1 + 2) = (uint32)T1; 1275 | *(r1 + 3) = (*(gp + 3)) + ~(*(fp + 3)) + j; 1276 | *(r1 + 4) = 1; 1277 | } 1278 | else if(compare(gp, fp, 5) == -1) 1279 | { 1280 | T1 = (uint64)(*fp) + ~(*gp) + 0x1; 1281 | T2 = T1 >> 32; 1282 | *r1 = (uint32)T1; 1283 | 1284 | T1 = T2 + (*(fp + 1)) + ~(*(gp + 1)); 1285 | T2 = T1 >> 32; 1286 | *(r1 + 1) = (uint32)T1; 1287 | 1288 | T1 = T2 + (*(fp + 2)) + ~(*(gp + 2)); 1289 | j = (uint32)(T1 >> 32); 1290 | *(r1 + 2) = (uint32)T1; 1291 | *(r1 + 3) = (*(fp + 3)) + ~(*(gp + 3)) + j; 1292 | *(r1 + 4) = 2; 1293 | } 1294 | else 1295 | { 1296 | for(i = 0; i < 5; i++) 1297 | *(r1 + i) = 0; 1298 | } 1299 | break; 1300 | default: return; 1301 | } 1302 | } 1303 | 1304 | /******************************************************************************************* 1305 | Compute a width-5 TNAF of an element in Z[t] 1306 | ********************************************************************************************/ 1307 | void TNAF5_expansion(uint32 *r0, uint32 *r1, char *u, uint32 curve_id) 1308 | { 1309 | char t; 1310 | uint32 i, j, r, c, v, Num; 1311 | uint64 T; 1312 | uint32 s0[4], s1[4], s2[4]; 1313 | sint32 flags0, flags0p, flags1, s, sbeta, sgama; 1314 | sint32 beta[8] = {1, -3, -1, 1, -3, -1, 1, 1}; 1315 | sint32 gama[2][8] = {{0, 1, 1, 1, 2, 2, 2, -3},{0, -1, -1, -1, -2, -2, -2, 3}}; 1316 | 1317 | switch(curve_id){ 1318 | case sect163k1: 1319 | Num = 6; 1320 | v = 3; //j = Num/2 1321 | break; 1322 | case sect233k1: 1323 | Num = 8; 1324 | v = 4; //j = Num/2 1325 | break; 1326 | default: return; 1327 | } 1328 | 1329 | for(i = v - 1; i != 0; i--) 1330 | { 1331 | *(s0 + i) = *(r0 + i); 1332 | *(s1 + i) = *(r1 + i); 1333 | } 1334 | *s0 = *r0; 1335 | *s1 = *r1; 1336 | 1337 | if(*(r0 + v) == 2) flags0 = -1; 1338 | else if(*(r0 + v) == 1) flags0 = 1; 1339 | else flags0 = 0; 1340 | 1341 | if(*(r1 + v) == 2) flags1 = -1; 1342 | else if(*(r1 + v) == 1) flags1 = 1; 1343 | else flags1 = 0; 1344 | 1345 | i = 0; 1346 | 1347 | while(!(flags0 == 0 && flags1 == 0)) 1348 | { 1349 | if((*s0 & 0x1) == 0x1) //r0 is not equal to 0 1350 | { 1351 | //compute r0+tw*r1 1352 | if(flags0 > 0 && flags1 >= 0) 1353 | { 1354 | //compute the lowest 32 bits of r0+tw*r1 1355 | switch(curve_id){ 1356 | case sect163k1: 1357 | r = *s0 + 6*(*s1); 1358 | break; 1359 | case sect233k1: 1360 | r = *s0 + 26*(*s1); 1361 | break; 1362 | default: return; 1363 | } 1364 | 1365 | //get the lowest 5 bits of r0+tw*r1 1366 | r = r & 0x1f; 1367 | 1368 | if(r >= 0 && r <= 16) t = (char)r; 1369 | else t = (char)r - 32; 1370 | 1371 | *(u + i) = t; 1372 | } 1373 | else if(flags0 < 0 && flags1 <= 0) 1374 | { 1375 | //compute the lowest 32 bits of r0+tw*r1 1376 | switch(curve_id){ 1377 | case sect163k1: 1378 | r = *s0 + 6*(*s1); 1379 | break; 1380 | case sect233k1: 1381 | r = *s0 + 26*(*s1); 1382 | break; 1383 | default: return; 1384 | } 1385 | 1386 | //get the lowest 5 bits of r0+tw*r1 1387 | r = r & 0x1f; 1388 | 1389 | if(r >= 0 && r <= 16) t = -(char)r; 1390 | else t = 32 - (char)r; 1391 | 1392 | *(u + i) = t; 1393 | } 1394 | else if (flags0 >= 0 && flags1 < 0) 1395 | { 1396 | //compute the lowest 32 bits of r0-tw*r1=r0+(32+tw)*|r1| 1397 | switch(curve_id){ 1398 | case sect163k1: 1399 | r = *s0 + 26*(*s1); 1400 | break; 1401 | case sect233k1: 1402 | r = *s0 + 6*(*s1); 1403 | break; 1404 | default: return; 1405 | } 1406 | 1407 | //take out the lowest 5 bits of r0+(32+tw)*|r1| 1408 | r = r & 0x1f; 1409 | 1410 | if(r >= 0 && r <= 16) t = (char)r; 1411 | else t = (char)r - 32; 1412 | 1413 | *(u + i) = t; 1414 | } 1415 | else // curve_ids0 <= 0 && curve_ids1 > 0 1416 | { 1417 | //compute the lowest 32 bits of r0-tw*r1=-(|r0|+(32+tw)*r1) 1418 | switch(curve_id){ 1419 | case sect163k1: 1420 | r = *s0 + 26*(*s1); 1421 | break; 1422 | case sect233k1: 1423 | r = *s0 + 6*(*s1); 1424 | break; 1425 | default: return; 1426 | } 1427 | 1428 | //take out the lowest 5 bits of -(|r0|+(32+tw)*r1) 1429 | r = r & 0x1f; 1430 | 1431 | if(r >= 0 && r <= 16) t = -(char)r; 1432 | else t = 32 - (char)r; 1433 | 1434 | *(u + i) = t; 1435 | } 1436 | 1437 | if(t > 0) s = 1; 1438 | else 1439 | { 1440 | s = -1; 1441 | t = -t; 1442 | } 1443 | 1444 | //compute r0 = r0 - s*beta_u 1445 | sbeta = s * (*(beta + ((t - 1) >> 1))); 1446 | if(sbeta > 0) r = (uint32)(sbeta); 1447 | else r = (uint32)(-sbeta); 1448 | 1449 | if(flags0 == 0) 1450 | { 1451 | *s0 = r; 1452 | if(sbeta > 0) flags0 = -1; 1453 | else flags0 = 1; 1454 | } 1455 | else 1456 | { 1457 | if((flags0 < 0 && sbeta > 0) || (flags0 > 0 && sbeta < 0)) //addition 1458 | { 1459 | T = (uint64)(*s0) + r; 1460 | *s0 = (uint32)T; 1461 | c = (uint32)(T >> 32); 1462 | j = 1; 1463 | while(c != 0 && j < v) 1464 | { 1465 | T = (uint64)(*(s0 + j)) + c; 1466 | *(s0 + j) = (uint32)T; 1467 | c = (uint32)(T >> 32); 1468 | j++; 1469 | } 1470 | } 1471 | else //subtraction 1472 | { 1473 | switch(curve_id){ 1474 | case sect163k1: 1475 | if(*(s0 + 2) == 0 && *(s0 + 1) == 0 && *s0 == r) 1476 | { 1477 | *s0 = 0; 1478 | flags0 = 0; 1479 | } 1480 | else if(*(s0 + 2) == 0 && *(s0 + 1) == 0 && *s0 < r) 1481 | { 1482 | *s0 = r - (*s0); 1483 | flags0 = -flags0; 1484 | } 1485 | else 1486 | { 1487 | T = (uint64)(*s0) + ~r + 0x1; 1488 | *s0 = (uint32)T; 1489 | c = (uint32)(T >> 32); 1490 | for(j = 1; j < 3; j++) 1491 | { 1492 | T = (uint64)(*(s0 + j)) + 0xffffffff + c; 1493 | *(s0 + j) = (uint32)T; 1494 | c = (uint32)(T >> 32); 1495 | } 1496 | } 1497 | break; 1498 | case sect233k1: 1499 | if(*(s0 + 3) == 0 && *(s0 + 2) == 0 && *(s0 + 1) == 0 && *s0 == r) 1500 | { 1501 | *s0 = 0; 1502 | flags0 = 0; 1503 | } 1504 | else if(*(s0 + 3) == 0 && *(s0 + 2) == 0 && *(s0 + 1) == 0 && *s0 < r) 1505 | { 1506 | *s0 = r - (*s0); 1507 | flags0 = -flags0; 1508 | } 1509 | else 1510 | { 1511 | T = (uint64)(*s0) + ~r + 0x1; 1512 | *s0 = (uint32)T; 1513 | c = (uint32)(T >> 32); 1514 | for(j = 1; j < 4; j++) 1515 | { 1516 | T = (uint64)(*(s0 + j)) + 0xffffffff + c; 1517 | *(s0 + j) = (uint32)T; 1518 | c = (uint32)(T >> 32); 1519 | } 1520 | } 1521 | break; 1522 | default: return; 1523 | } 1524 | } 1525 | } 1526 | 1527 | //compute r1 = r1 - s*gama_u 1528 | sgama = s * (*(gama[0] + curve_id* 8 + ((t - 1) >> 1))); 1529 | if(sgama >= 0) r = (uint32)(sgama); 1530 | else r = (uint32)(-sgama); 1531 | 1532 | if(flags1 == 0) 1533 | { 1534 | *s1 = r; 1535 | if(sgama > 0) flags1 = -1; 1536 | if(sgama < 0) flags1 = 1; 1537 | } 1538 | else 1539 | { 1540 | if((flags1 < 0 && sgama > 0) || (flags1 > 0 && sgama < 0)) //addition 1541 | { 1542 | T = (uint64)(*s1) + r; 1543 | *s1 = (uint32)T; 1544 | c = (uint32)(T >> 32); 1545 | j = 1; 1546 | while(c != 0 && j < v) 1547 | { 1548 | T = (uint64)(*(s1 + j)) + c; 1549 | *(s1 + j) = (uint32)T; 1550 | c = (uint32)(T >> 32); 1551 | j++; 1552 | } 1553 | } 1554 | else //subtraction 1555 | { 1556 | switch(curve_id){ 1557 | case sect163k1: 1558 | if(*(s1 + 2) == 0 && *(s1 + 1) == 0 && *s1 == r) 1559 | { 1560 | *s1 = 0; 1561 | flags1 = 0; 1562 | } 1563 | else if(*(s1 + 2) == 0 && *(s1 + 1) == 0 && *s1 < r) 1564 | { 1565 | *s1 = r - (*s1); 1566 | flags1 = -flags1; 1567 | } 1568 | else 1569 | { 1570 | T = (uint64)(*s1) + ~r + 0x1; 1571 | *s1 = (uint32)T; 1572 | c = (uint32)(T >> 32); 1573 | for(j = 1; j < 3; j++) 1574 | { 1575 | T = (uint64)(*(s1 + j)) + 0xffffffff + c; 1576 | *(s1 + j) = (uint32)T; 1577 | c = (uint32)(T >> 32); 1578 | } 1579 | } 1580 | break; 1581 | case sect233k1: 1582 | if(*(s1 + 3) == 0 && *(s1 + 2) == 0 && *(s1 + 1) == 0 && *s1 == r) 1583 | { 1584 | *s1 = 0; 1585 | flags1 = 0; 1586 | } 1587 | else if(*(s1 + 3) == 0 && *(s1 + 2) == 0 && *(s1 + 1) == 0 && *s1 < r) 1588 | { 1589 | *s1 = r - (*s1); 1590 | flags1 = -flags1; 1591 | } 1592 | else 1593 | { 1594 | T = (uint64)(*s1) + ~r + 0x1; 1595 | *s1 = (uint32)T; 1596 | c = (uint32)(T >> 32); 1597 | for(j = 1; j < 4; j++) 1598 | { 1599 | T = (uint64)(*(s1 + j)) + 0xffffffff + c; 1600 | *(s1 + j) = (uint32)T; 1601 | c = (uint32)(T >> 32); 1602 | } 1603 | } 1604 | break; 1605 | default: return; 1606 | } 1607 | } 1608 | } 1609 | } 1610 | else *(u + i) = 0; 1611 | 1612 | //compute r0/2 1613 | for(j = 0; j < v - 1; j++) 1614 | *(s2 + j) = (*(s0 + j) >> 1) | (*(s0 + j + 1) << 31); 1615 | *(s2 + (v - 1)) = *(s0 + (v - 1)) >> 1; 1616 | flags0p = flags0; 1617 | 1618 | switch(curve_id){ 1619 | case sect163k1: 1620 | //r0 = r1 + r0/2 1621 | if(flags0 == 0 || flags1 == 0) 1622 | { 1623 | if(flags0 == 0) 1624 | { 1625 | *s0 = *s1; 1626 | *(s0 + 1) = *(s1 + 1); 1627 | *(s0 + 2) = *(s1 + 2); 1628 | flags0 = flags1; 1629 | } 1630 | else 1631 | { 1632 | *s0 = *s2; 1633 | *(s0 + 1) = *(s2 + 1); 1634 | *(s0 + 2) = *(s2 + 2); 1635 | } 1636 | } 1637 | else if(flags0 == flags1) //addition (curve_ids0 > 0 && curve_ids1 > 0) || (curve_ids0 < 0 && curve_ids1 < 0) 1638 | { 1639 | T = (uint64)(*s1) + (*s2); 1640 | *s0 = (uint32)T; 1641 | c = (uint32)(T >> 32); 1642 | T = (uint64)(*(s1 + 1)) + (*(s2 + 1)) + c; 1643 | *(s0 + 1) = (uint32)T; 1644 | c = (uint32)(T >> 32); 1645 | *(s0 + 2) = (*(s1 + 2)) + (*(s2 + 2)) + c; 1646 | } 1647 | else 1648 | { 1649 | if(compare(s1, s2, 3) == 1) //r0 = |r1| - |r0|/2 1650 | { 1651 | T = (uint64)(*s1) + ~(*s2) + 0x1; 1652 | *s0 = (uint32)T; 1653 | c = (uint32)(T >> 32); 1654 | T = (uint64)(*(s1 + 1)) + ~(*(s2 + 1)) + c; 1655 | *(s0 + 1) = (uint32)T; 1656 | c = (uint32)(T >> 32); 1657 | *(s0 + 2) = (*(s1 + 2)) + ~(*(s2 + 2)) + c; 1658 | flags0 = flags1; 1659 | } 1660 | else if(compare(s1, s2, 3) == -1) //r0 = |r0|/2 - |r1| 1661 | { 1662 | T = (uint64)(*s2) + ~(*s1) + 0x1; 1663 | *s0 = (uint32)T; 1664 | c = (uint32)(T >> 32); 1665 | T = (uint64)(*(s2 + 1)) + ~(*(s1 + 1)) + c; 1666 | *(s0 + 1) = (uint32)T; 1667 | c = (uint32)(T >> 32); 1668 | *(s0 + 2) = (*(s2 + 2)) + ~(*(s1 + 2)) + c; 1669 | } 1670 | else //r0 = 0 1671 | { 1672 | *s0 = 0; 1673 | *(s0 + 1) = 0; 1674 | *(s0 + 2) = 0; 1675 | flags0 = 0; 1676 | } 1677 | } 1678 | break; 1679 | case sect233k1: 1680 | //r0 = r1 - r0/2 1681 | if(flags0 == 0 || flags1 == 0) 1682 | { 1683 | if(flags0 == 0) 1684 | { 1685 | for(j = 3; j != 0; j--) 1686 | *(s0 + j) = *(s1 + j); 1687 | *s0 = *s1; 1688 | flags0 = flags1; 1689 | } 1690 | else 1691 | { 1692 | for(j = 3; j != 0; j--) 1693 | *(s0 + j) = *(s2 + j); 1694 | *s0 = *s2; 1695 | flags0 = -flags0; 1696 | } 1697 | } 1698 | else if(flags0 != flags1) //addition (curve_ids0 < 0 && curve_ids1 > 0) || (curve_ids0 > 0 && curve_ids1 < 0) 1699 | { 1700 | T = (uint64)(*s1) + (*s2); 1701 | *s0 = (uint32)T; 1702 | c = (uint32)(T >> 32); 1703 | T = (uint64)(*(s1 + 1)) + (*(s2 + 1)) + c; 1704 | *(s0 + 1) = (uint32)T; 1705 | c = (uint32)(T >> 32); 1706 | T = (uint64)(*(s1 + 2)) + (*(s2 + 2)) + c; 1707 | *(s0 + 2) = (uint32)T; 1708 | c = (uint32)(T >> 32); 1709 | *(s0 + 3) = (*(s1 + 3)) + (*(s2 + 3)) + c; 1710 | flags0 = flags1; 1711 | } 1712 | else 1713 | { 1714 | if(compare(s1, s2, 4) == 1) //r0 = |r1| - |r0|/2 1715 | { 1716 | T = (uint64)(*s1) + ~(*s2) + 0x1; 1717 | *s0 = (uint32)T; 1718 | c = (uint32)(T >> 32); 1719 | T = (uint64)(*(s1 + 1)) + ~(*(s2 + 1)) + c; 1720 | *(s0 + 1) = (uint32)T; 1721 | c = (uint32)(T >> 32); 1722 | T = (uint64)(*(s1 + 2)) + ~(*(s2 + 2)) + c; 1723 | *(s0 + 2) = (uint32)T; 1724 | c = (uint32)(T >> 32); 1725 | *(s0 + 3) = (*(s1 + 3)) + ~(*(s2 + 3)) + c; 1726 | } 1727 | else if(compare(s1, s2, 4) == -1) //r0 = |r0|/2 - |r1| 1728 | { 1729 | T = (uint64)(*s2) + ~(*s1) + 0x1; 1730 | *s0 = (uint32)T; 1731 | c = (uint32)(T >> 32); 1732 | T = (uint64)(*(s2 + 1)) + ~(*(s1 + 1)) + c; 1733 | *(s0 + 1) = (uint32)T; 1734 | c = (uint32)(T >> 32); 1735 | T = (uint64)(*(s2 + 2)) + ~(*(s1 + 2)) + c; 1736 | *(s0 + 2) = (uint32)T; 1737 | c = (uint32)(T >> 32); 1738 | *(s0 + 3) = (*(s2 + 3)) + ~(*(s1 + 3)) + c; 1739 | flags0 = -flags0; 1740 | } 1741 | else //r0 = 0 1742 | { 1743 | for(j = 3; j != 0; j--) 1744 | *(s0 + j) = 0; 1745 | *s0 = 0; 1746 | flags0 = 0; 1747 | } 1748 | } 1749 | break; 1750 | default: return; 1751 | } 1752 | 1753 | //r1 = -r0/2 1754 | for(j = v - 1; j != 0; j--) 1755 | *(s1 + j) = *(s2 + j); 1756 | *s1 = *s2; 1757 | flags1 = -flags0p; 1758 | 1759 | i++; 1760 | } 1761 | } 1762 | 1763 | /************************************************************************************************** 1764 | Compute the scalar multiplication with the TNAF5 method (fixed point) 1765 | *************************************************************************************************/ 1766 | void TNAF5_fixed_scalarmul(uint32 *k, ec_point_aff *Q, uint32 curve_id) 1767 | { 1768 | char a[236] = {0x0}; 1769 | uint32 i, Num, BitLen; 1770 | uint32 lamda0[5]; 1771 | uint32 lamda1[5]; 1772 | ec_point_aff T; 1773 | ec_point_pro R; 1774 | 1775 | switch(curve_id){ 1776 | case sect163k1: 1777 | Num = 6; 1778 | BitLen = 163; 1779 | break; 1780 | case sect233k1: 1781 | Num = 8; 1782 | BitLen = 233; 1783 | break; 1784 | default: return; 1785 | } 1786 | 1787 | partial_mod(k, lamda0, lamda1, curve_id); 1788 | TNAF5_expansion(lamda0, lamda1, a, curve_id); 1789 | 1790 | //R = infinity 1791 | XIS1(R.X, Num); 1792 | XIS0(R.Y, Num); 1793 | XIS0(R.Z, Num); 1794 | 1795 | for(i = BitLen + 3; i != 0; i--) 1796 | { 1797 | point_frobenius(&R, curve_id); 1798 | 1799 | switch(a[i - 1]){ 1800 | case 0: break; 1801 | case 1: mixed_addition(&R, &G[curve_id], &R, curve_id); 1802 | break; 1803 | case -1: point_negation(&G[curve_id], &T, curve_id); 1804 | mixed_addition(&R, &T, &R, curve_id); 1805 | break; 1806 | case 3: mixed_addition(&R, &G3[curve_id], &R, curve_id); 1807 | break; 1808 | case -3: point_negation(&G3[curve_id], &T, curve_id); 1809 | mixed_addition(&R, &T, &R, curve_id); 1810 | break; 1811 | case 5: mixed_addition(&R, &G5[curve_id], &R, curve_id); 1812 | break; 1813 | case -5: point_negation(&G5[curve_id], &T, curve_id); 1814 | mixed_addition(&R, &T, &R, curve_id); 1815 | break; 1816 | case 7: mixed_addition(&R, &G7[curve_id], &R, curve_id); 1817 | break; 1818 | case -7: point_negation(&G7[curve_id], &T, curve_id); 1819 | mixed_addition(&R, &T, &R, curve_id); 1820 | break; 1821 | case 9: mixed_addition(&R, &G9[curve_id], &R, curve_id); 1822 | break; 1823 | case -9: point_negation(&G9[curve_id], &T, curve_id); 1824 | mixed_addition(&R, &T, &R, curve_id); 1825 | break; 1826 | case 11: mixed_addition(&R, &G11[curve_id], &R, curve_id); 1827 | break; 1828 | case -11: point_negation(&G11[curve_id], &T, curve_id); 1829 | mixed_addition(&R, &T, &R, curve_id); 1830 | break; 1831 | case 13: mixed_addition(&R, &G13[curve_id], &R, curve_id); 1832 | break; 1833 | case -13: point_negation(&G13[curve_id], &T, curve_id); 1834 | mixed_addition(&R, &T, &R, curve_id); 1835 | break; 1836 | case 15: mixed_addition(&R, &G15[curve_id], &R, curve_id); 1837 | break; 1838 | case -15: point_negation(&G15[curve_id], &T, curve_id); 1839 | mixed_addition(&R, &T, &R, curve_id); 1840 | break; 1841 | default: return; //Error 1842 | } 1843 | } 1844 | project_to_affine(&R, Q, curve_id); 1845 | } 1846 | 1847 | /************************************************************************************************** 1848 | Compute the scalar multiplication with the TNAF5 method (random point) 1849 | *************************************************************************************************/ 1850 | void TNAF5_random_scalarmul(uint32 *k, ec_point_aff *P, ec_point_aff *Q, uint32 curve_id) 1851 | { 1852 | char a[236] = {0x0}; 1853 | uint32 i, Num, BitLen; 1854 | uint32 lamda0[5]; 1855 | uint32 lamda1[5]; 1856 | ec_point_aff P3, P5, P7, P9, P11, P13, P15, T; 1857 | ec_point_pro R, S; 1858 | 1859 | switch(curve_id){ 1860 | case sect163k1: 1861 | Num = 6; 1862 | BitLen = 163; 1863 | 1864 | //pre-computation 1865 | affine_to_project(P, &R, sect163k1); 1866 | point_frobenius(&R, sect163k1); 1867 | point_negation(P, &P3, sect163k1); 1868 | mixed_addition(&R, &P3, &S, sect163k1); 1869 | project_to_affine(&S, &P5, sect163k1); 1870 | mixed_addition(&R, P, &S, sect163k1); 1871 | project_to_affine(&S, &P7, sect163k1); 1872 | point_frobenius(&R, sect163k1); 1873 | mixed_addition(&R, &P3, &S, sect163k1); 1874 | project_to_affine(&S, &P3, sect163k1); 1875 | point_frobenius(&R, sect163k1); 1876 | point_negation(&P3, &P11, sect163k1); 1877 | mixed_addition(&R, &P11, &S, sect163k1); 1878 | project_to_affine(&S, &P11, sect163k1); 1879 | point_negation(&P11, &P11, sect163k1); 1880 | point_negation(&P5, &P13, sect163k1); 1881 | mixed_addition(&R, &P13, &S, sect163k1); 1882 | project_to_affine(&S, &P13, sect163k1); 1883 | point_negation(&P13, &P13, sect163k1); 1884 | point_frobenius(&R, sect163k1); 1885 | mixed_addition(&R, &P7, &S, sect163k1); 1886 | project_to_affine(&S, &P9, sect163k1); 1887 | point_negation(&P9, &P9, sect163k1); 1888 | affine_to_project(P, &R, sect163k1); 1889 | point_frobenius(&R, sect163k1); 1890 | mixed_addition(&R, &P11, &S, sect163k1); 1891 | project_to_affine(&S, &P15, sect163k1); 1892 | point_negation(&P15, &P15, sect163k1); 1893 | break; 1894 | case sect233k1: 1895 | Num = 8; 1896 | BitLen = 233; 1897 | 1898 | //pre-computation 1899 | affine_to_project(P, &R, sect233k1); 1900 | point_frobenius(&R, sect233k1); 1901 | mixed_addition(&R, P, &S, sect233k1); 1902 | project_to_affine(&S, &P5, sect233k1); 1903 | point_negation(&P5, &P5, sect233k1); 1904 | point_negation(P, &P3, sect233k1); 1905 | mixed_addition(&R, &P3, &S, sect233k1); 1906 | project_to_affine(&S, &P7, sect233k1); 1907 | point_negation(&P7, &P7, sect233k1); 1908 | point_frobenius(&R, sect233k1); 1909 | mixed_addition(&R, &P3, &S, sect233k1); 1910 | project_to_affine(&S, &P3, sect233k1); 1911 | point_frobenius(&R, sect233k1); 1912 | mixed_addition(&R, &P3, &S, sect233k1); 1913 | project_to_affine(&S, &P11, sect233k1); 1914 | mixed_addition(&R, &P5, &S, sect233k1); 1915 | project_to_affine(&S, &P13, sect233k1); 1916 | point_frobenius(&R, sect233k1); 1917 | mixed_addition(&R, &P7, &S, sect233k1); 1918 | project_to_affine(&S, &P9, sect233k1); 1919 | point_negation(&P9, &P9, sect233k1); 1920 | affine_to_project(P, &R, sect233k1); 1921 | point_frobenius(&R, sect233k1); 1922 | point_negation(&P11,&P15, sect233k1); 1923 | mixed_addition(&R, &P15, &S, sect233k1); 1924 | project_to_affine(&S, &P15, sect233k1); 1925 | break; 1926 | default: return; 1927 | } 1928 | 1929 | //tau-adic expansion 1930 | partial_mod(k, lamda0, lamda1, curve_id); 1931 | TNAF5_expansion(lamda0, lamda1, a, curve_id); 1932 | 1933 | //R = infinity 1934 | XIS1(R.X, Num); 1935 | XIS0(R.Y, Num); 1936 | XIS0(R.Z, Num); 1937 | 1938 | for(i = BitLen + 3; i != 0; i--) 1939 | { 1940 | point_frobenius(&R, curve_id); 1941 | 1942 | switch(a[i - 1]){ 1943 | case 0: break; 1944 | case 1: mixed_addition(&R, P, &R, curve_id); 1945 | break; 1946 | case -1: point_negation(P, &T, curve_id); 1947 | mixed_addition(&R, &T, &R, curve_id); 1948 | break; 1949 | case 3: mixed_addition(&R, &P3, &R, curve_id); 1950 | break; 1951 | case -3: point_negation(&P3, &T, curve_id); 1952 | mixed_addition(&R, &T, &R, curve_id); 1953 | break; 1954 | case 5: mixed_addition(&R, &P5, &R, curve_id); 1955 | break; 1956 | case -5: point_negation(&P5, &T, curve_id); 1957 | mixed_addition(&R, &T, &R, curve_id); 1958 | break; 1959 | case 7: mixed_addition(&R, &P7, &R, curve_id); 1960 | break; 1961 | case -7: point_negation(&P7, &T, curve_id); 1962 | mixed_addition(&R, &T, &R, curve_id); 1963 | break; 1964 | case 9: mixed_addition(&R, &P9, &R, curve_id); 1965 | break; 1966 | case -9: point_negation(&P9, &T, curve_id); 1967 | mixed_addition(&R, &T, &R, curve_id); 1968 | break; 1969 | case 11: mixed_addition(&R, &P11, &R, curve_id); 1970 | break; 1971 | case -11: point_negation(&P11, &T, curve_id); 1972 | mixed_addition(&R, &T, &R, curve_id); 1973 | break; 1974 | case 13: mixed_addition(&R, &P13, &R, curve_id); 1975 | break; 1976 | case -13: point_negation(&P13, &T, curve_id); 1977 | mixed_addition(&R, &T, &R, curve_id); 1978 | break; 1979 | case 15: mixed_addition(&R, &P15, &R, curve_id); 1980 | break; 1981 | case -15: point_negation(&P15, &T, curve_id); 1982 | mixed_addition(&R, &T, &R, curve_id); 1983 | break; 1984 | default: return; //Error 1985 | } 1986 | } 1987 | project_to_affine(&R, Q, curve_id); 1988 | } 1989 | 1990 | 1991 | 1992 | -------------------------------------------------------------------------------- /ECCK.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 Xinxin Fan 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * - Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * - Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in 12 | * the documentation and/or other materials provided with the 13 | * distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 25 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 | * POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #ifndef __ECCK_H__ 30 | #define __ECCK_H__ 31 | 32 | /** 33 | * Koblitz curve sect233k1: y^2 + xy = x^3 + x^2 + 1 34 | * Finite Field: GF(2^163) = F_2[x]/(x^163 + x^7 + x^6 + x^3 + 1) 35 | * 36 | * Koblitz curve sect233k1: y^2 + xy = x^3 + 1 37 | * Finite Field: GF(2^233) = F_2[x]/(x^233 + x^74 + 1) 38 | */ 39 | 40 | /** 41 | * Point compression 42 | */ 43 | void point_compression(ec_point_aff *P, uint32 *Pc, uint32 curve_id); 44 | 45 | /** 46 | * Point decompression 47 | */ 48 | uint32 point_decompression(uint32 *Pc, ec_point_aff *P, uint32 curve_id); 49 | 50 | /** 51 | * Point negation 52 | */ 53 | void point_negation(ec_point_aff *P, ec_point_aff *negP, uint32 curve_id); 54 | 55 | /** 56 | * Point conversion from project coordinate to affine coordinate 57 | */ 58 | void project_to_affine(ec_point_pro *Qp, ec_point_aff *Qa, uint32 curve_id); 59 | 60 | /** 61 | * Point conversion from affine coordinate to projective coordinate 62 | */ 63 | void affine_to_project(ec_point_aff *Qa, ec_point_pro *Qp, uint32 curve_id); 64 | 65 | /** 66 | * Point addition 67 | */ 68 | void mixed_addition(ec_point_pro *P, ec_point_aff *Q, ec_point_pro *R, uint32 curve_id); 69 | 70 | /** 71 | * Point doubling 72 | */ 73 | void point_doubling(ec_point_pro *P, ec_point_pro *Q, uint32 curve_id); 74 | 75 | /** 76 | * Frobenius mapping 77 | */ 78 | void point_frobenius(ec_point_pro *P, uint32 curve_id); 79 | 80 | /** 81 | * Partial reduction 82 | */ 83 | void partial_mod(uint32 *k, uint32 *r0, uint32 *r1, uint32 curve_id); 84 | 85 | /** 86 | * Width-5 TNAF expansion 87 | */ 88 | void TNAF5_expansion(uint32 *r0, uint32 *r1, char *u, uint32 curve_id); 89 | 90 | /** 91 | * Scalar multiplication with the width-5 TNAF (fixed point) 92 | */ 93 | void TNAF5_fixed_scalarmul(uint32 *k, ec_point_aff *Q, uint32 curve_id); 94 | 95 | /** 96 | * Scalar multiplication with the width-5 TNAF (random point) 97 | */ 98 | void TNAF5_random_scalarmul(uint32 *k, ec_point_aff *P, ec_point_aff *Q, uint32 curve_id); 99 | 100 | #endif /* __ECCK_H__ */ -------------------------------------------------------------------------------- /ECDSA.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 Xinxin Fan 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * - Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * - Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in 12 | * the documentation and/or other materials provided with the 13 | * distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 25 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 | * POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #include "OpenECC.h" 30 | #include "ECDSA.h" 31 | #include "GF2n.h" 32 | #include "ECCK.h" 33 | #include "GFp.h" 34 | #include "AES128.h" 35 | #include "AESMMO.h" 36 | 37 | /************************************************************************************** 38 | modpmul(.): Modular multiplication over GF(p) 39 | **************************************************************************************/ 40 | void modpmul(uint32 *a, uint32 *b, uint32 *amulb, uint32 curve_id) 41 | { 42 | uint32 i, j, Num; 43 | uint32 c[2*N-1], p[N+1], q[N+1]; 44 | uint64 T1, T2, T3; 45 | 46 | switch(curve_id){ 47 | case sect163k1: Num = 6; 48 | break; 49 | case sect233k1: Num = 8; 50 | break; 51 | default: return; 52 | } 53 | 54 | //c = a * b 55 | T1 = (uint64)(*a) * (*b); 56 | *c = (uint32)T1; 57 | T1 = T1 >> 32; 58 | 59 | for(i = 1; i < 2*(Num - 1); i++) 60 | { 61 | T3 = 0; 62 | for(j = (i < Num ? 0 : (i - Num + 1)); j <= (i < Num ? i : (Num - 1)); j++) 63 | { 64 | T2 = (uint64)(*(a + j)) * (*(b + (i - j))); 65 | T1 += (uint32)T2; 66 | T3 += (T2 >> 32); 67 | } 68 | *(c + i) = (uint32)T1; 69 | T1 = (T1 >> 32) + T3; 70 | } 71 | 72 | *(c + 2*(Num - 1)) = (uint32)T1 + (*(a + (Num - 1))) * (*(b + (Num - 1))); 73 | 74 | //Barrett Modular Reduction 75 | T1 = (uint64)(*(c + Num - 1)) * (*(eccu[curve_id])); 76 | T1 = T1 >> 32; 77 | 78 | for(i = Num; i < Num * 2; i++) 79 | { 80 | T3 = 0; 81 | for(j = Num - 1; j <= (i < (2*Num - 1) ? i : 2*(Num - 1)); j++) 82 | { 83 | T2 = (uint64)(*(c + j)) * (*(eccu[curve_id] + (i - j))); 84 | T1 += (uint32)T2; 85 | T3 += (T2 >> 32); 86 | } 87 | T1 = (T1 >> 32) + T3; 88 | } 89 | 90 | for(i = 0; i < Num - 1; i++) 91 | { 92 | T3 = 0; 93 | for(j = i + Num; j <= 2*(Num - 1); j++) 94 | { 95 | T2 = (uint64)(*(c + j)) * (*(eccu[curve_id] + (Num * 2 + i - j))); 96 | T1 += (uint32)T2; 97 | T3 += (T2 >> 32); 98 | } 99 | *(p + i) = (uint32)T1; 100 | T1 = (T1 >> 32) + T3; 101 | } 102 | 103 | *(p + (Num - 1)) = (uint32)T1; 104 | 105 | //q = p * eccn 106 | T1 = (uint64)(*p) * (*(eccn[curve_id])); 107 | *q = (uint32)T1; 108 | T1 = T1 >> 32; 109 | 110 | for(i = 1; i < Num - 1; i++) 111 | { 112 | T3 = 0; 113 | for(j = (i < (Num/2) ? 0 : (i - Num/2 + 1)); j <= i; j++) 114 | { 115 | T2 = (uint64)(*(p + j)) * (*(eccn[curve_id] + (i - j))); 116 | T1 += (uint32)T2; 117 | T3 += (T2 >> 32); 118 | } 119 | *(q + i) = (uint32)T1; 120 | T1 = (T1 >> 32) + T3; 121 | } 122 | 123 | T2 = (uint64)(*p) * (*(eccn[curve_id] + (Num - 1))); 124 | T1 += (uint32)T2; 125 | T3 = T2 >> 32; 126 | for(j = Num/2; j <= Num - 1; j++) 127 | { 128 | T2 = (uint64)(*(p + j)) * (*(eccn[curve_id] + (Num - 1 - j))); 129 | T1 += (uint32)T2; 130 | T3 += (T2 >> 32); 131 | } 132 | *(q + Num - 1) = (uint32)T1; 133 | T1 = (T1 >> 32) + T3; 134 | 135 | T2 = (uint64)*(p + 1) * (*(eccn[curve_id] + (Num - 1))); 136 | T1 += (uint32)T2; 137 | for(j = Num/2 + 1; j <= Num - 1; j++) 138 | { 139 | T2 = (uint64)(*(p + j)) * (*(eccn[curve_id] + (Num - j))); 140 | T1 += (uint32)T2; 141 | } 142 | *(q + Num) = (uint32)T1; 143 | 144 | for(i = Num - 1; i != 0; i--) 145 | *(p + i) = *(eccn[curve_id] + i); 146 | *p = *(eccn[curve_id]); 147 | *(p + Num) = 0; 148 | 149 | if(sub(c, q, q, Num + 1) == 1) 150 | { 151 | for(i = Num - 1; i != 0; i--) 152 | *(amulb + i) = *(q + i); 153 | *amulb = *q; 154 | return; 155 | } 156 | 157 | while(compare(q, p, Num + 1) != -1) 158 | sub(q, p, q, Num + 1); 159 | for(i = Num - 1; i != 0; i--) 160 | *(amulb + i) = *(q + i); 161 | *amulb = *q; 162 | } 163 | 164 | /************************************************************************************** 165 | modpinv(.): Modular inversion over GF(p) 166 | **************************************************************************************/ 167 | void modpinv(uint32 *a, uint32 *b, uint32 curve_id) 168 | { 169 | uint32 g1[N] = {0x1}; 170 | uint32 g2[N] = {0x0}; 171 | uint32 u[N]; 172 | uint32 v[N]; 173 | uint32 p[N] = {0x0}; 174 | uint32 i, Num, uv, t; 175 | 176 | switch(curve_id){ 177 | case sect163k1: 178 | Num = 6; 179 | XTOY(u, a, 6); 180 | XTOY(v, eccn[0], 6); 181 | uv = (IFN1_163(u)) && (IFN1_163(v)); 182 | break; 183 | case sect233k1: 184 | Num = 8; 185 | XTOY(u, a, 8); 186 | XTOY(v, eccn[1], 8); 187 | uv = (IFN1_233(u)) && (IFN1_233(v)); 188 | break; 189 | default: return; 190 | } 191 | 192 | sub(p, eccn[curve_id], p, Num); 193 | 194 | while(uv) 195 | { 196 | while((u[0] & 0x1) == 0) 197 | { 198 | for(i = 0; i < Num - 1; i++) 199 | *(u + i) = (*(u + i) >> 1) | (*(u + i + 1) << 31); 200 | *(u + Num - 1) = *(u + Num - 1) >> 1; 201 | 202 | if((g1[0] & 0x1) != 0) 203 | add(g1, eccn[curve_id], g1, curve_id); 204 | 205 | for(i = 0; i < Num - 1; i++) 206 | *(g1 + i) = (*(g1 + i) >> 1) | (*(g1 + i + 1) << 31); 207 | *(g1 + Num - 1) = *(g1 + Num - 1) >> 1; 208 | } 209 | 210 | while((v[0] & 0x1) == 0) 211 | { 212 | for(i = 0; i < Num - 1; i++) 213 | *(v + i) = (*(v + i) >> 1) | (*(v + i + 1) << 31); 214 | *(v + Num - 1) = *(v + Num - 1) >> 1; 215 | 216 | if((g2[0] & 0x1) != 0) 217 | add(g2, eccn[curve_id], g2, curve_id); 218 | 219 | for(i = 0; i < Num - 1; i++) 220 | *(g2 + i) = (*(g2 + i) >> 1) | (*(g2 + i + 1) << 31); 221 | *(g2 + Num - 1) = *(g2 + Num - 1) >> 1; 222 | } 223 | 224 | if(compare(u, v, Num) != -1) 225 | { 226 | sub(u, v, u, Num); 227 | if(sub(g1, g2, g1, Num) == 1) 228 | sub(g1, p, g1, Num); 229 | } 230 | else 231 | { 232 | sub(v, u, v, Num); 233 | if(sub(g2, g1, g2, Num) == 1) 234 | sub(g2, p, g2, Num); 235 | } 236 | 237 | switch(curve_id){ 238 | case sect163k1: 239 | uv = (IFN1_163(u)) && (IFN1_163(v)); 240 | break; 241 | case sect233k1: 242 | uv = (IFN1_233(u)) && (IFN1_233(v)); 243 | break; 244 | default: return; 245 | } 246 | } 247 | 248 | switch(curve_id){ 249 | case sect163k1: 250 | t = IF1_163(u); 251 | break; 252 | case sect233k1: 253 | t = IF1_233(u); 254 | break; 255 | default: return; 256 | } 257 | 258 | if(t) 259 | { 260 | for(i = Num - 1; i != 0; i--) 261 | *(b + i) = *(g1 + i); 262 | *b = *g1; 263 | } 264 | else 265 | { 266 | for(i = Num - 1; i != 0; i--) 267 | *(b + i) = *(g2 + i); 268 | *b = *g2; 269 | } 270 | } 271 | 272 | /*************************************************************************************************** 273 | ECDSA signature generation 274 | **************************************************************************************************/ 275 | uint32 ECDSA_sign(uint32 *d, uint8 *rnd, uint8 *msg, uint32 mlen, uint32 *r, uint32 *s, uint32 curve_id) 276 | { 277 | uint8 t[16]; 278 | uint32 k[N], e[N]; 279 | uint32 i, Num, u; 280 | ec_point_aff R; 281 | 282 | switch(curve_id){ 283 | case sect163k1: 284 | Num = 6; 285 | 286 | *(k + 5) = (uint32)(*(rnd + 20)) & 0x7; 287 | break; 288 | case sect233k1: 289 | Num = 8; 290 | 291 | *(k + 7) = (*(k + 7) << 8) | (uint32)(*(rnd + 29)); 292 | *(k + 7) = (*(k + 7) << 8) | (uint32)(*(rnd + 28)); 293 | *(k + 7) = *(k + 7) & 0xff; 294 | break; 295 | default: return 0; 296 | } 297 | 298 | for(i = 0; i < Num - 1; i++) 299 | { 300 | *(k + i) = (uint32)(*(rnd + 4*i + 3)); 301 | *(k + i) = (*(k + i) << 8) | (uint32)(*(rnd + 4*i + 2)); 302 | *(k + i) = (*(k + i) << 8) | (uint32)(*(rnd + 4*i + 1)); 303 | *(k + i) = (*(k + i) << 8) | (uint32)(*(rnd + 4*i)); 304 | } 305 | 306 | if(compare(k, eccn[curve_id], Num) != -1) 307 | sub(k, eccn[curve_id], k, Num); 308 | 309 | TNAF5_fixed_scalarmul(k, &R, curve_id); 310 | XTOY(r, R.x, Num); 311 | while(compare(r, eccn[curve_id], Num) != -1) 312 | sub(r, eccn[curve_id], r, Num); 313 | 314 | AES_MMO(msg, mlen*4, t); 315 | 316 | for(i = 0; i < 4; i++) 317 | { 318 | *(e + i) = ((uint32)*(t+4*i) << 24) | ((uint32)*(t+4*i+1) << 16) | ((uint32)*(t+4*i+1) << 8) | ((uint32)*(t+4*i+3)); 319 | *(e + i + 4) = 0x0; 320 | } 321 | 322 | modpmul(r, d, s, curve_id); 323 | modpadd(s, e, s, curve_id); 324 | modpinv(k, e, curve_id); 325 | modpmul(s, e, s, curve_id); 326 | 327 | switch(curve_id){ 328 | case sect163k1: 329 | u = IF0_163(s); 330 | break; 331 | case sect233k1: 332 | u = IF0_233(s); 333 | break; 334 | default: return 0; 335 | } 336 | 337 | if(u) return 0; 338 | 339 | return 1; 340 | } 341 | 342 | /*************************************************************************************************** 343 | ECDSA signature generation 344 | **************************************************************************************************/ 345 | uint32 ECDSA_verify(uint32 *Qx, uint8 *msg, uint32 mlen, uint32 *r, uint32 *s, uint32 curve_id) 346 | { 347 | uint8 t[16]; 348 | uint32 si[8], u[8], e[8]; 349 | uint32 i, Num, v; 350 | ec_point_aff R, S, Q; 351 | ec_point_pro Rp; 352 | 353 | switch(curve_id){ 354 | case sect163k1: Num = 6; 355 | break; 356 | case sect233k1: Num = 8; 357 | break; 358 | default: return 0; 359 | } 360 | 361 | if(compare(r, eccn[curve_id], Num) != -1 || compare(s, eccn[curve_id], Num) != -1) 362 | return 0; 363 | 364 | AES_MMO(msg, mlen*4, t); 365 | 366 | for(i = 0; i < 4; i++) 367 | { 368 | *(e + i) = ((uint32)*(t+4*i) << 24) | ((uint32)*(t+4*i+1) << 16) | ((uint32)*(t+4*i+1) << 8) | ((uint32)*(t+4*i+3)); 369 | *(e + i + 4) = 0x0; 370 | } 371 | 372 | modpinv(s, si, curve_id); 373 | modpmul(e, si, e, curve_id); 374 | modpmul(r, si, u, curve_id); 375 | TNAF5_fixed_scalarmul(e, &R, curve_id); 376 | if(point_decompression(Qx, &Q, curve_id) == 0) 377 | return 0; 378 | TNAF5_random_scalarmul(u, &Q, &S, curve_id); 379 | affine_to_project(&R, &Rp, curve_id); 380 | mixed_addition(&Rp, &S, &Rp, curve_id); 381 | project_to_affine(&Rp, &R, curve_id); 382 | 383 | switch(curve_id){ 384 | case sect163k1: 385 | v = (IF0_163(R.x)) && (IF0_163(R.y)); 386 | break; 387 | case sect233k1: 388 | v = (IF0_233(R.x)) && (IF0_233(R.y)); 389 | break; 390 | default: return 0; 391 | } 392 | 393 | if(v) return 0; 394 | 395 | XTOY(e, R.x, Num); 396 | while(compare(e, eccn[curve_id], Num) != -1) 397 | sub(e, eccn[curve_id], e, Num); 398 | 399 | if(compare(e, r, Num) == 0) 400 | return 1; 401 | else return 0; 402 | } 403 | 404 | 405 | 406 | -------------------------------------------------------------------------------- /ECDSA.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 Xinxin Fan 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * - Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * - Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in 12 | * the documentation and/or other materials provided with the 13 | * distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 25 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 | * POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #ifndef __ECDSA_H__ 30 | #define __ECDSA_H__ 31 | 32 | /** 33 | * Modular multiplication over GF(p) 34 | */ 35 | void modpmul(uint32 *a, uint32 *b, uint32 *amulb, uint32 curve_id); 36 | 37 | /** 38 | * Modular inversion over GF(p) 39 | */ 40 | void modpinv(uint32 *a, uint32 *b, uint32 curve_id); 41 | 42 | /** 43 | * ECDSA signature generation 44 | * 45 | * @param d the private key of a signer 46 | * @param rnd a random number (21-byte for sect163k1 and 30-byte for sect233k1) 47 | * @param msg a message 48 | * @param mlen message length in bytes 49 | * @param r, s the signature pair (r, s) 50 | * succeed return 1 51 | * fail return 0 52 | */ 53 | uint32 ECDSA_sign(uint32 *d, uint8 *rnd, uint8 *msg, uint32 mlen, uint32 *r, uint32 *s, uint32 curve_id); 54 | 55 | /** 56 | * ECDSA signature verification 57 | * 58 | * @param Qx the public key of a signer in compressed form 59 | * @param msg a message 60 | * @param mlen message length in bytes 61 | * @param r, s the signature pair (r, s) 62 | * succeed return 1 63 | * fail return 0 64 | */ 65 | uint32 ECDSA_verify(uint32 *Qx, uint8 *msg, uint32 mlen, uint32 *r, uint32 *s, uint32 curve_id); 66 | 67 | #endif /* __ECDSA_H__ */ 68 | -------------------------------------------------------------------------------- /GF2n.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 Xinxin Fan 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * - Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * - Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in 12 | * the documentation and/or other materials provided with the 13 | * distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 25 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 | * POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #include "OpenECC.h" 30 | #include "GF2n.h" 31 | 32 | /**************************************************************** 33 | Modular Addition Function: 34 | ****************************************************************/ 35 | void modadd(uint32 *a, uint32 *b, uint32 *c, uint32 curve_id) 36 | { 37 | uint32 i; 38 | uint32 Num; 39 | 40 | switch(curve_id){ 41 | case sect163k1: Num = 6; 42 | break; 43 | case sect233k1: Num = 8; 44 | break; 45 | default: return; 46 | } 47 | 48 | for(i = Num - 1; i != 0; i--) 49 | *(c + i) = *(a + i) ^ *(b + i); 50 | *c = (*a) ^ (*b); 51 | } 52 | 53 | /********************************************************************** 54 | Modular Multiplication Function: 55 | ************************************************************************/ 56 | void modmul(uint32 *a, uint32 *b, uint32 *c, uint32 curve_id) 57 | { 58 | uint32 P[15][N]; //store the precomputation results 59 | uint32 R[2*N-1] = {0x0}; //store the intermediate result 60 | uint32 u, i, j, k, Num; 61 | uint32 *p; 62 | 63 | p = P[0]; 64 | 65 | switch(curve_id){ 66 | case sect163k1: Num = 6; 67 | break; 68 | case sect233k1: Num = 8; 69 | break; 70 | default: return; 71 | } 72 | 73 | //precomputation 74 | for(j = Num - 1; j != 0; j--) 75 | *(p + j) = *(a + j); 76 | *p = *a; 77 | 78 | for(j = Num - 1; j != 0; j--) 79 | { 80 | *(p + 8 + j) = (*(p + j) << 1) | (*(p + j - 1) >> 31); 81 | *(p + 16 + j) = *(p + 8 + j) ^ *(p + j); 82 | *(p + 24 + j) = (*(p + j) << 2) | (*(p + j - 1) >> 30); 83 | *(p + 32 + j) = *(p + 24 + j) ^ *(p + j); 84 | *(p + 40 + j) = *(p + 24 + j) ^ *(p + 8 + j); 85 | *(p + 48 + j) = *(p + 40 + j) ^ *(p + j); 86 | *(p + 56 + j) = (*(p + j) << 3) | (*(p + j - 1) >> 29); 87 | *(p + 64 + j) = *(p + 56 + j) ^ *(p + j); 88 | *(p + 72 + j) = *(p + 56 + j) ^ *(p + 8 + j); 89 | *(p + 80 + j) = *(p + 72 + j) ^ *(p + j); 90 | *(p + 88 + j) = *(p + 56 + j) ^ *(p + 24 + j); 91 | *(p + 96 + j) = *(p + 88 + j) ^ *(p + j); 92 | *(p + 104 + j) = *(p + 88 + j) ^ *(p + 8 + j); 93 | *(p + 112 + j) = *(p + 104 + j) ^ *(p + j); 94 | } 95 | *(p + 8) = *p << 1; 96 | *(p + 16) = *(p + 8) ^ *p; 97 | *(p + 24) = *p << 2; 98 | *(p + 32) = *(p + 24) ^ *p; 99 | *(p + 40) = *(p + 24) ^ *(p + 8); 100 | *(p + 48) = *(p + 40) ^ *p; 101 | *(p + 56) = *p << 3; 102 | *(p + 64) = *(p + 56) ^ *p; 103 | *(p + 72) = *(p + 56) ^ *(p + 8); 104 | *(p + 80) = *(p + 72) ^ *p; 105 | *(p + 88) = *(p + 56) ^ *(p + 24); 106 | *(p + 96) = *(p + 88) ^ *p; 107 | *(p + 104) = *(p + 88) ^ *(p + 8); 108 | *(p + 112) = *(p + 104) ^ *p; 109 | 110 | //main loop 111 | for(i = 7; i != 0; i--) 112 | { 113 | for(j = Num - 1; j != 0; j--) 114 | { 115 | u = (*(b + j) >> (i * 4)) & 0xf; 116 | if(u != 0) 117 | { 118 | u--; 119 | for(k = Num - 1; k != 0; k--) 120 | *(R + j + k) ^= *(p + 8 * u + k); 121 | *(R + j) ^= *(p + 8 * u); 122 | } 123 | } 124 | u = ((*b) >> (i * 4)) & 0xf; 125 | if(u != 0) 126 | { 127 | u--; 128 | for(k = Num - 1; k != 0; k--) 129 | *(R + k) ^= *(p + 8 * u + k); 130 | *R ^= *(p + 8 * u); 131 | } 132 | 133 | //R <- x^4*R 134 | switch(curve_id){ 135 | case sect163k1: 136 | if(i == 1) 137 | *(R + 10) = *(R + 9) >> 28; 138 | for(j = 9; j != 0 ; j--) 139 | *(R + j) = (*(R + j) << 4) | (*(R + j - 1) >> 28); 140 | break; 141 | case sect233k1: 142 | if((i == 2) || (i == 1)) 143 | *(R + 14) = (*(R + 14) << 4) | (*(R + 13) >> 28); 144 | for(j = 13; j != 0 ; j--) 145 | *(R + j) = (*(R + j) << 4) | (*(R + j - 1) >> 28); 146 | break; 147 | default: return; 148 | } 149 | *R = *R << 4; 150 | } 151 | 152 | //last loop 153 | for(j = Num - 1; j != 0; j--) 154 | { 155 | u = *(b + j) & 0xf; 156 | if(u != 0) 157 | { 158 | u--; 159 | for(k = Num - 1; k != 0; k--) 160 | *(R + j + k) ^= *(p + 8 * u + k); 161 | *(R + j) ^= *(p + 8 * u); 162 | } 163 | } 164 | u = (*b) & 0xf; 165 | if(u != 0) 166 | { 167 | u--; 168 | for(k = Num - 1; k != 0; k--) 169 | *(R + k) ^= *(p + 8 * u + k); 170 | *R ^= *(p + 8 * u); 171 | } 172 | 173 | //fast modular reduction, one word at a time 174 | switch(curve_id){ 175 | case sect163k1: 176 | *(R + 4) ^= (*(R + 10) << 29); 177 | *(R + 5) ^= *(R + 10) ^ (*(R + 10) << 3) ^ (*(R + 10) << 4) ^ (*(R + 10) >> 3); 178 | 179 | for(j = 5; j != 1; j--) 180 | { 181 | *(R + j) ^= (*(R + j + 4) >> 29) ^ (*(R + j + 4) >> 28); 182 | *(R + j - 1) ^= *(R + j + 4) ^ (*(R + j + 4) << 3) ^ (*(R + j + 4) << 4) ^ (*(R + j + 4) >> 3); 183 | *(R + j - 2) ^= (*(R + j + 4) << 29); 184 | } 185 | 186 | u = *(R + 5) >> 3; 187 | *R ^= u ^ (u << 3) ^ (u << 6) ^ (u << 7); 188 | *(R + 1) ^= (u >> 25) ^ (u >> 26); 189 | 190 | *(c + 5) = *(R + 5) & 0x7; 191 | break; 192 | case sect233k1: 193 | *(R + 6) ^= (*(R + 14) << 23); 194 | *(R + 7) ^= (*(R + 14) >> 9); 195 | *(R + 9) ^= (*(R + 14) << 1); 196 | 197 | for(j = 9; j != 3; j--) 198 | { 199 | *(R + j) ^= (*(R + j + 4) >> 31); 200 | *(R + j - 1) ^= (*(R + j + 4) << 1); 201 | *(R + j - 3) ^= (*(R + j + 4) >> 9); 202 | *(R + j - 4) ^= (*(R + j + 4) << 23); 203 | } 204 | 205 | u = *(R + 7) >> 9; 206 | *R ^= u; 207 | *(R + 2) ^= (u << 10); 208 | *(R + 3) ^= (u >> 22); 209 | 210 | *(c + 7) = *(R + 7) & 0x1ff; 211 | break; 212 | default: return; 213 | } 214 | 215 | //store the reduction result 216 | for(j = Num - 2; j != 0; j--) 217 | *(c + j) = *(R +j); 218 | *c = *R; 219 | } 220 | 221 | /**************************************************************** 222 | Square function: 223 | ****************************************************************/ 224 | void modsq(uint32 *a, uint32 *b, uint32 curve_id) 225 | { 226 | uint32 R[2*N-1]; 227 | uint32 i, j, Num; 228 | 229 | //precomputation 230 | uint16 T[256] = {\ 231 | 0,1,4,5,16,17,20,21,64,65,68,69,80,81,84,85,256,257,260,261,272,273,276,277,320,\ 232 | 321,324,325,336,337,340,341,1024,1025,1028,1029,1040,1041,1044,1045,1088,1089,\ 233 | 1092,1093,1104,1105,1108,1109,1280,1281,1284,1285,1296,1297,1300,1301,1344,1345,\ 234 | 1348,1349,1360,1361,1364,1365,4096,4097,4100,4101,4112,4113,4116,4117,4160,4161,\ 235 | 4164,4165,4176,4177,4180,4181,4352,4353,4356,4357,4368,4369,4372,4373,4416,4417,\ 236 | 4420,4421,4432,4433,4436,4437,5120,5121,5124,5125,5136,5137,5140,5141,5184,5185,\ 237 | 5188,5189,5200,5201,5204,5205,5376,5377,5380,5381,5392,5393,5396,5397,5440,5441,\ 238 | 5444,5445,5456,5457,5460,5461,16384,16385,16388,16389,16400,16401,16404,16405,\ 239 | 16448,16449,16452,16453,16464,16465,16468,16469,16640,16641,16644,16645,16656,\ 240 | 16657,16660,16661,16704,16705,16708,16709,16720,16721,16724,16725,17408,17409,\ 241 | 17412,17413,17424,17425,17428,17429,17472,17473,17476,17477,17488,17489,17492,\ 242 | 17493,17664,17665,17668,17669,17680,17681,17684,17685,17728,17729,17732,17733,\ 243 | 17744,17745,17748,17749,20480,20481,20484,20485,20496,20497,20500,20501,20544,\ 244 | 20545,20548,20549,20560,20561,20564,20565,20736,20737,20740,20741,20752,20753,\ 245 | 20756,20757,20800,20801,20804,20805,20816,20817,20820,20821,21504,21505,21508,\ 246 | 21509,21520,21521,21524,21525,21568,21569,21572,21573,21584,21585,21588,21589,\ 247 | 21760,21761,21764,21765,21776,21777,21780,21781,21824,21825,21828,21829,21840,\ 248 | 21841,21844,21845}; 249 | 250 | switch(curve_id){ 251 | case sect163k1: 252 | Num = 6; 253 | if(IF1_163(a)) 254 | { 255 | XIS1(b, 6); 256 | return; 257 | } 258 | break; 259 | case sect233k1: 260 | Num = 8; 261 | if(IF1_233(a)) 262 | { 263 | XIS1(b, 8); 264 | return; 265 | } 266 | break; 267 | default: return; 268 | } 269 | 270 | //compute R[2*Num-2] 271 | for(i = Num - 2; i != 0 ; i--) 272 | { 273 | *(R + 2 * i) = (uint32)*(T + (*(a + i) & 0xff)) | ((uint32)*(T + ((*(a + i) >> 8) & 0xff)) << 16); 274 | *(R + 2 * i + 1) = (uint32)*(T + ((*(a + i) >> 16) & 0xff)) | ((uint32)*(T + ((*(a + i) >> 24) & 0xff)) << 16); 275 | } 276 | *R = (uint32)*(T + (*a & 0xff)) | ((uint32)*(T + ((*a >> 8) & 0xff)) << 16); 277 | *(R + 1) = (uint32)*(T + ((*a >> 16) & 0xff)) | ((uint32)*(T + ((*a >> 24) & 0xff)) << 16); 278 | 279 | //fast modular reduction, one word at a time 280 | switch(curve_id){ 281 | case sect163k1: 282 | *(R + 10) = (uint32)*(T + (*(a + 5) & 0xff)); 283 | 284 | *(R + 4) ^= (*(R + 10) << 29); 285 | *(R + 5) ^= *(R + 10) ^ (*(R + 10) << 3) ^ (*(R + 10) << 4) ^ (*(R + 10) >> 3); 286 | 287 | for(j = 5; j != 1; j--) 288 | { 289 | *(R + j) ^= (*(R + j + 4) >> 29) ^ (*(R + j + 4) >> 28); 290 | *(R + j - 1) ^= *(R + j + 4) ^ (*(R + j + 4) << 3) ^ (*(R + j + 4) << 4) ^ (*(R + j + 4) >> 3); 291 | *(R + j - 2) ^= (*(R + j + 4) << 29); 292 | } 293 | 294 | *(R + 6) = *(R + 5) >> 3; 295 | *R ^= *(R + 6) ^ (*(R + 6) << 3) ^ (*(R + 6) << 6) ^ (*(R + 6) << 7); 296 | *(R + 1) ^= (*(R + 6) >> 25) ^ (*(R + 6) >> 26); 297 | 298 | *(b + 5) = *(R + 5) & 0x7; 299 | break; 300 | case sect233k1: 301 | *(R + 14) = (uint32)*(T + (*(a + 7) & 0xff)) | ((uint32)*(T + ((*(a + 7) >> 8) & 0xff)) << 16); 302 | 303 | *(R + 6) ^= (*(R + 14) << 23); 304 | *(R + 7) ^= (*(R + 14) >> 9); 305 | *(R + 9) ^= (*(R + 14) << 1); 306 | 307 | for(j = 9; j != 3; j--) 308 | { 309 | *(R + j) ^= (*(R + j + 4) >> 31); 310 | *(R + j - 1) ^= (*(R + j + 4) << 1); 311 | *(R + j - 3) ^= (*(R + j + 4) >> 9); 312 | *(R + j - 4) ^= (*(R + j + 4) << 23); 313 | } 314 | 315 | *(R + 8) = *(R + 7) >> 9; 316 | *R ^= *(R + 8); 317 | *(R + 2) ^= (*(R + 8) << 10); 318 | *(R + 3) ^= (*(R + 8) >> 22); 319 | 320 | *(b + 7) = *(R + 7) & 0x1ff; 321 | break; 322 | default: return; 323 | } 324 | 325 | //store the reduction result 326 | for(j = Num - 2; j != 0; j--) 327 | *(b + j) = *(R + j); 328 | *b = *R; 329 | } 330 | 331 | /**************************************************************** 332 | Compare two big integers a and b with m*32 bits 333 | ***************************************************************/ 334 | sint32 compare(uint32 *a, uint32 *b, uint32 m) 335 | { 336 | uint32 i; 337 | 338 | for(i = m; i != 0; i--) 339 | { 340 | if(*(a + i - 1) < *(b + i - 1)) return -1; 341 | if(*(a + i - 1) > *(b + i - 1)) return 1; 342 | } 343 | return 0; 344 | } 345 | 346 | /**************************************************************** 347 | Modular Inversion Function: Binary Extended Euclidean Algorithm 348 | ***************************************************************/ 349 | void modinv(uint32 *a, uint32 *b, uint32 curve_id) 350 | { 351 | uint32 g1[8] = {0x1}; 352 | uint32 g2[8] = {0x0}; 353 | uint32 u[8]; 354 | uint32 v[8] = {0x1}; 355 | uint32 i, Num, uv, t; 356 | 357 | switch(curve_id){ 358 | case sect163k1: 359 | Num = 6; 360 | XTOY(u, a, 6); 361 | //x^163 + x^7 + x^6 + x^3 + 1 362 | v[0] = 0xc9; 363 | v[5] = 0x8; 364 | uv = (IFN1_163(u)) && (IFN1_163(v)); 365 | break; 366 | case sect233k1: 367 | Num = 8; 368 | XTOY(u, a, 8); 369 | //x^233 + x^74 + 1 370 | v[2] = 0x400; 371 | v[7] = 0x200; 372 | uv = (IFN1_233(u)) && (IFN1_233(v)); 373 | break; 374 | default: return; 375 | } 376 | 377 | while(uv) 378 | { 379 | while((u[0] & 0x1) == 0) 380 | { 381 | for(i = 0; i < Num - 1; i++) 382 | *(u + i) = (*(u + i) >> 1) | (*(u + i + 1) << 31); 383 | *(u + Num - 1) = *(u + Num - 1) >> 1; 384 | 385 | if((g1[0] & 0x1) != 0) 386 | { 387 | switch(curve_id){ 388 | case sect163k1: 389 | //x^163 + x^7 + x^6 + x^3 + 1 390 | g1[0] ^= 0xc9; 391 | g1[5] ^= 0x8; 392 | break; 393 | case sect233k1: 394 | //x^233 + x^74 + 1 395 | g1[0] ^= 0x1; 396 | g1[2] ^= 0x400; 397 | g1[7] ^= 0x200; 398 | break; 399 | default: return; 400 | } 401 | } 402 | 403 | for(i = 0; i < Num - 1; i++) 404 | *(g1 + i) = (*(g1 + i) >> 1) | (*(g1 + i + 1) << 31); 405 | *(g1 + Num - 1) = *(g1 + Num - 1) >> 1; 406 | } 407 | 408 | while((v[0] & 0x1) == 0) 409 | { 410 | for(i = 0; i < Num - 1; i++) 411 | *(v + i) = (*(v + i) >> 1) | (*(v + i + 1) << 31); 412 | *(v + Num - 1) = *(v + Num - 1) >> 1; 413 | 414 | if((g2[0] & 0x1) != 0) 415 | { 416 | switch(curve_id){ 417 | case sect163k1: 418 | //x^163 + x^7 + x^6 + x^3 + 1 419 | g2[0] ^= 0xc9; 420 | g2[5] ^= 0x8; 421 | break; 422 | case sect233k1: 423 | //x^233 + x^74 + 1 424 | g2[0] ^= 0x1; 425 | g2[2] ^= 0x400; 426 | g2[7] ^= 0x200; 427 | break; 428 | default: return; 429 | } 430 | } 431 | 432 | for(i = 0; i < Num - 1; i++) 433 | *(g2 + i) = (*(g2 + i) >> 1) | (*(g2 + i + 1) << 31); 434 | *(g2 + Num - 1) = *(g2 + Num - 1) >> 1; 435 | } 436 | 437 | if(compare(u, v, Num) == 1) 438 | { 439 | for(i = Num - 1; i != 0; i--) 440 | { 441 | *(u + i) ^= *(v + i); 442 | *(g1 + i) ^= *(g2 + i); 443 | } 444 | *u ^= *v; 445 | *g1 ^= *g2; 446 | } 447 | else 448 | { 449 | for(i = Num - 1; i != 0; i--) 450 | { 451 | *(v + i) ^= *(u + i); 452 | *(g2 + i) ^= *(g1 + i); 453 | } 454 | *v ^= *u; 455 | *g2 ^= *g1; 456 | } 457 | 458 | switch(curve_id){ 459 | case sect163k1: 460 | uv = (IFN1_163(u)) && (IFN1_163(v)); 461 | break; 462 | case sect233k1: 463 | uv = (IFN1_233(u)) && (IFN1_233(v)); 464 | break; 465 | default: return; 466 | } 467 | } 468 | 469 | switch(curve_id){ 470 | case sect163k1: 471 | t = IF1_163(u); 472 | break; 473 | case sect233k1: 474 | t = IF1_233(u); 475 | break; 476 | default: return; 477 | } 478 | 479 | if(t) 480 | { 481 | for(i = Num - 1; i != 0; i--) 482 | *(b + i) = *(g1 + i); 483 | *b = *g1; 484 | } 485 | else 486 | { 487 | for(i = Num - 1; i != 0; i--) 488 | *(b + i) = *(g2 + i); 489 | *b = *g2; 490 | } 491 | } 492 | 493 | /**************************************************************** 494 | Compute the halftrace over GF(2^n) 495 | ***************************************************************/ 496 | void halftrace(uint32 *a, uint32 *b, uint32 curve_id) 497 | { 498 | uint32 i, j; 499 | uint32 c[8]; 500 | uint32 Num, BitLen; 501 | 502 | switch(curve_id){ 503 | case sect163k1: 504 | Num = 6; 505 | BitLen = 163; 506 | break; 507 | case sect233k1: 508 | Num = 8; 509 | BitLen = 233; 510 | break; 511 | default: return; 512 | } 513 | 514 | XTOY(c, a, Num); 515 | 516 | for(i = 1; i <= (BitLen - 1)/2; i++) 517 | { 518 | modsq(c, c, curve_id); 519 | modsq(c, c, curve_id); 520 | for(j = Num - 1; j != 0; j--) 521 | *(c + j) ^= *(a + j); 522 | *c ^= *a; 523 | } 524 | 525 | XTOY(b, c, Num); 526 | } -------------------------------------------------------------------------------- /GF2n.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 Xinxin Fan 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * - Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * - Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in 12 | * the documentation and/or other materials provided with the 13 | * distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 25 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 | * POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #ifndef __GF2n_H__ 30 | #define __GF2n_H__ 31 | 32 | /** 33 | * Support fast arithmetic for two binary fields 34 | * GF(2^163): F_2[x]/(x^163 + x^7 + x^6 + x^3 + 1) 35 | * GF(2^233): F_2[x]/(x^233 + x^74 + 1) 36 | */ 37 | 38 | /** 39 | * Modular Addition over GF(2^n) 40 | */ 41 | void modadd(uint32 *a, uint32 *b, uint32 *c, uint32 curve_id); 42 | 43 | /** 44 | * Modular Multiplication over GF(2^n) 45 | */ 46 | void modmul(uint32 *a, uint32 *b, uint32 *c, uint32 curve_id); 47 | 48 | /** 49 | * Modular Squaring over GF(2^n) 50 | */ 51 | void modsq(uint32 *a, uint32 *b, uint32 curve_id); 52 | 53 | /** 54 | * Modular Inversion over GF(2^n) 55 | */ 56 | void modinv(uint32 *a, uint32 *b, uint32 curve_id); 57 | 58 | /** 59 | * Compute Halftrace over GF(2^n) 60 | */ 61 | void halftrace(uint32 *a, uint32 *b, uint32 curve_id); 62 | 63 | /** 64 | * Big Integer Comparison 65 | */ 66 | sint32 compare(uint32 *a, uint32 *b, uint32 m); 67 | 68 | #endif /* __GF2n_H__ */ -------------------------------------------------------------------------------- /GFp.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 Xinxin Fan 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * - Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * - Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in 12 | * the documentation and/or other materials provided with the 13 | * distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 25 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 | * POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #include "OpenECC.h" 30 | #include "GF2n.h" 31 | #include "GFp.h" 32 | 33 | //For the curve sect163k1 and sect233k1 34 | uint32 eccn[2][8] = {{0x99F8A5EFUL,0xA2E0CC0DUL,0x20108UL,0x0UL,0x0UL,0x4UL,0x0UL,0x0UL}, 35 | {0xF173ABDFUL,0x6EFB1AD5UL,0xB915BCD4UL,0x69D5BUL,0x0UL,0x0UL,0x0UL,0x80UL}}; 36 | uint32 eccu[2][9] = {{0x4E1DF22EUL,0x20108E74UL,0x266075A1UL,0x75D1F33FUL,0xFFFFDFEFUL,0xFFFFFFFFUL,0x3FFFFFFFUL,0x0UL,0x0UL}, 37 | {0x327734F6UL,0x50855E08UL,0x94A83A31UL,0x0CAE4413UL,0x8A911BA9UL,0xFFFFFFE5UL,0xFFFFFFFFUL,0xFFFFFFFFUL,0x1FFFFFFUL}}; 38 | 39 | /************************************************************************************** 40 | add(.): Multi-precision addition 41 | **************************************************************************************/ 42 | uint32 add(uint32 *a, uint32 *b, uint32 *aplusb, uint32 curve_id) 43 | { 44 | uint32 i, carry, Num; 45 | uint64 T; 46 | 47 | switch(curve_id){ 48 | case sect163k1: Num = 6; 49 | break; 50 | case sect233k1: Num = 8; 51 | break; 52 | default: return 0; 53 | } 54 | 55 | carry = 0; 56 | for(i = 0; i < Num; i++) 57 | { 58 | T = (uint64)*(a + i) + *(b + i) + carry; 59 | *(aplusb + i) = (uint32)T; 60 | carry = (uint32)(T >> 32); 61 | } 62 | if(carry == 1) return 1; 63 | else return 0; 64 | } 65 | 66 | /************************************************************************************** 67 | sub(.): Multi-precision subtraction 68 | **************************************************************************************/ 69 | uint32 sub(uint32 *a, uint32 *b, uint32 *asubb, uint32 m) 70 | { 71 | uint32 i, borrow; 72 | uint64 T; 73 | 74 | borrow = 1; 75 | for(i = 0; i < m; i++) 76 | { 77 | T = (uint64)*(a + i) + ~*(b + i) + borrow; 78 | *(asubb + i) = (uint32)T; 79 | borrow = (uint32)(T >> 32); 80 | } 81 | if(borrow == 0) return 1; 82 | else return 0; 83 | } 84 | 85 | /************************************************************************************** 86 | modadd(.): Modular multi-precision addition 87 | **************************************************************************************/ 88 | void modpadd(uint32 *a, uint32 *b, uint32 *aplusb, uint32 curve_id) 89 | { 90 | uint32 carry, Num; 91 | 92 | switch(curve_id){ 93 | case sect163k1: Num = 6; 94 | break; 95 | case sect233k1: Num = 8; 96 | break; 97 | default: return; 98 | } 99 | 100 | carry = add(a, b, aplusb, curve_id); 101 | 102 | if(carry == 1) 103 | { 104 | sub(aplusb, eccn[curve_id], aplusb, Num); 105 | return; 106 | } 107 | else 108 | { 109 | if(compare(aplusb, eccn[curve_id], Num) != -1) 110 | sub(aplusb, eccn[curve_id], aplusb, Num); 111 | } 112 | } 113 | 114 | /************************************************************************************** 115 | modsub(.): Modular multi-precision subtraction 116 | **************************************************************************************/ 117 | void modpsub(uint32 *a, uint32 *b, uint32 *asubb, uint32 curve_id) 118 | { 119 | uint32 i, carry; 120 | uint32 Num; 121 | 122 | switch(curve_id){ 123 | case sect163k1: Num = 6; 124 | break; 125 | case sect233k1: Num = 8; 126 | break; 127 | default: return; 128 | } 129 | 130 | carry = 0; 131 | for(i = 0;i < Num; i++) 132 | { 133 | if(*(a + i) >= *(b + i)) 134 | { 135 | *(asubb + i) = *(a + i) - *(b + i); 136 | if((*(asubb + i) == 0x0) && (carry == 0x1)) 137 | *(asubb + i) = 0xffffffff; 138 | else 139 | { 140 | *(asubb + i) -= carry; 141 | carry=0x0; 142 | } 143 | } 144 | else 145 | { 146 | *(asubb + i) = *(a + i) + ~*(b + i) + 0x1 - carry; 147 | carry = 0x1; 148 | } 149 | } 150 | 151 | if(carry == 0x1) 152 | add(asubb, eccn[curve_id], asubb, curve_id); 153 | } 154 | 155 | /************************************************************************************** 156 | modpmul128(.): Modular multiplication over GF(p) with one operand 128-bit 157 | **************************************************************************************/ 158 | void modpmul128(uint32 *a, uint32 *b, uint32 *amulb, uint32 curve_id) 159 | { 160 | uint32 i, j, Num; 161 | uint32 c[N+4], p[N+1], q[N+1]; 162 | uint64 T1, T2, T3; 163 | 164 | switch(curve_id){ 165 | case sect163k1: Num = 6; 166 | break; 167 | case sect233k1: Num = 8; 168 | break; 169 | default: return; 170 | } 171 | 172 | //c = a * b 173 | T1 = (uint64)(*a) * (*b); 174 | *c = (uint32)T1; 175 | T1 = T1 >> 32; 176 | 177 | for(i = 1; i < Num + 2; i++) 178 | { 179 | T3 = 0; 180 | for(j = (i < Num ? 0 : (i - Num + 1)); j <= (i < 4 ? i : 3); j++) 181 | { 182 | T2 = (uint64)(*(a + j)) * (*(b + (i - j))); 183 | T1 += (uint32)T2; 184 | T3 += (T2 >> 32); 185 | } 186 | *(c + i) = (uint32)T1; 187 | T1 = (T1 >> 32) + T3; 188 | } 189 | 190 | T2 = (uint64)(*(a + 3)) * (*(b + Num - 1)); 191 | T1 += (uint32)T2; 192 | *(c + Num + 2) = (uint32)T1; 193 | *(c + Num + 3) = (uint32)(T1 >> 32) + (uint32)(T2 >> 32); 194 | 195 | //Barrett Modular Reduction 196 | T1 = (uint64)(*(c + Num - 1)) * (*(eccu[curve_id])); 197 | T1 = T1 >> 32; 198 | 199 | for(i = Num; i < Num * 2; i++) 200 | { 201 | T3 = 0; 202 | for(j = Num - 1; j <= (i < (Num + 4) ? i : (Num + 3)); j++) 203 | { 204 | T2 = (uint64)(*(c + j)) * (*(eccu[curve_id] + (i - j))); 205 | T1 += (uint32)T2; 206 | T3 += (T2 >> 32); 207 | } 208 | T1 = (T1 >> 32) + T3; 209 | } 210 | 211 | for(i = 0; i < 3; i++) 212 | { 213 | T3 = 0; 214 | for(j = i + Num; j <= Num + 3; j++) 215 | { 216 | T2 = (uint64)(*(c + j)) * (*(eccu[curve_id] + (Num * 2 + i - j))); 217 | T1 += (uint32)T2; 218 | T3 += (T2 >> 32); 219 | } 220 | *(p + i) = (uint32)T1; 221 | T1 = (T1 >> 32) + T3; 222 | } 223 | 224 | T2 = (uint64)*(c + Num + 3) * (*(eccu[curve_id] + Num)); 225 | T1 += (uint32)T2; 226 | *(p + 3) = (uint32)T1; 227 | *(p + 4) = (uint32)(T1 >> 32) + (uint32)(T2 >> 32); 228 | 229 | //q = p * eccn 230 | T1 = (uint64)(*p) * (*(eccn[curve_id])); 231 | *q = (uint32)T1; 232 | T1 = T1 >> 32; 233 | 234 | for(i = 1; i < Num - 1; i++) 235 | { 236 | T3 = 0; 237 | for(j = (i < (Num/2) ? 0 : (i - Num/2 + 1)); j <= (i < 5 ? i : 4); j++) 238 | { 239 | T2 = (uint64)(*(p + j)) * (*(eccn[curve_id] + (i - j))); 240 | T1 += (uint32)T2; 241 | T3 += (T2 >> 32); 242 | } 243 | *(q + i) = (uint32)T1; 244 | T1 = (T1 >> 32) + T3; 245 | } 246 | 247 | T2 = (uint64)(*p) * (*(eccn[curve_id] + (Num - 1))); 248 | T1 += (uint32)T2; 249 | T3 = T2 >> 32; 250 | switch(curve_id){ 251 | case sect163k1: 252 | T2 = (uint64)(*(p + 3)) * (*(eccn[0] + 2)); 253 | T1 += (uint32)T2; 254 | T3 += (T2 >> 32); 255 | T2 = (uint64)(*(p + 4)) * (*(eccn[0] + 1)); 256 | T1 += (uint32)T2; 257 | T3 += (T2 >> 32); 258 | break; 259 | case sect233k1: 260 | T2 = (uint64)(*(p + 4)) * (*(eccn[0] + 11)); 261 | T1 += (uint32)T2; 262 | T3 += (T2 >> 32); 263 | break; 264 | default: return; 265 | } 266 | *(q + Num - 1) = (uint32)T1; 267 | T1 = (T1 >> 32) + T3; 268 | 269 | T2 = (uint64)*(p + 1) * (*(eccn[curve_id] + (Num - 1))); 270 | T1 += (uint32)T2; 271 | if(curve_id == sect163k1) 272 | { 273 | T2 = (uint64)*(p + 4) * (*(eccn[0] + 2)); 274 | T1 += (uint32)T2; 275 | } 276 | *(q + Num) = (uint32)T1; 277 | 278 | for(i = Num - 1; i != 0; i--) 279 | *(p + i) = *(eccn[curve_id] + i); 280 | *p = *(eccn[curve_id]); 281 | *(p + Num) = 0; 282 | 283 | if(sub(c, q, q, Num + 1) == 1) 284 | { 285 | for(i = Num - 1; i != 0; i--) 286 | *(amulb + i) = *(q + i); 287 | *amulb = *q; 288 | return; 289 | } 290 | 291 | while(compare(q, p, Num + 1) != -1) 292 | sub(q, p, q, Num + 1); 293 | for(i = Num - 1; i != 0; i--) 294 | *(amulb + i) = *(q + i); 295 | *amulb = *q; 296 | } 297 | 298 | /************************************************************************************** 299 | modpmul96(.): Modular multiplication over GF(p) with one operand 96-bit 300 | This function is only used for the curve sect163k1 301 | **************************************************************************************/ 302 | void modpmul96(uint32 *a, uint32 *b, uint32 *amulb) 303 | { 304 | uint32 i, j; 305 | uint32 c[8], p[7], q[7]; 306 | uint64 T1, T2, T3; 307 | 308 | //c = a * b 309 | T1 = (uint64)(*a) * (*b); 310 | *c = (uint32)T1; 311 | T1 = T1 >> 32; 312 | 313 | for(i = 1; i < 7; i++) 314 | { 315 | T3 = 0; 316 | for(j = (i < 6 ? 0 : (i - 5)); j <= (i < 3 ? i : 2); j++) 317 | { 318 | T2 = (uint64)(*(a + j)) * (*(b + (i - j))); 319 | T1 += (uint32)T2; 320 | T3 += (T2 >> 32); 321 | } 322 | *(c + i) = (uint32)T1; 323 | T1 = (T1 >> 32) + T3; 324 | } 325 | 326 | *(c + 7) = (uint32)T1 + (*(a + 2)) * (*(b + 5)); 327 | 328 | //Barrett Modular Reduction 329 | T1 = (uint64)*(c + 5) * (*eccu[0]); 330 | T1 = T1 >> 32; 331 | 332 | for(i = 6; i < 12; i++) 333 | { 334 | T3 = 0; 335 | for(j = 5; j <= (i < 8 ? i : 7); j++) 336 | { 337 | T2 = (uint64)*(c + j) * (*(eccu[0] + (i - j))); 338 | T1 += (uint32)T2; 339 | T3 += (T2 >> 32); 340 | } 341 | T1 = (T1 >> 32) + T3; 342 | } 343 | 344 | T2 = (uint64)*(c + 6) * (*(eccu[0] + 6)); 345 | T1 += (uint32)T2; 346 | T3 = (T2 >> 32); 347 | T2 = (uint64)*(c + 7) * (*(eccu[0] + 5)); 348 | T1 += (uint32)T2; 349 | T3 += (T2 >> 32); 350 | *p = (uint32)T1; 351 | T1 = (T1 >> 32) + T3; 352 | 353 | T2 = (uint64)*(c + 7) * (*(eccu[0] + 6)); 354 | T1 += (uint32)T2; 355 | *(p + 1) = (uint32)T1; 356 | *(p + 2) = (uint32)(T1 >> 32) + (uint32)(T2 >> 32); 357 | 358 | //q = p * eccn 359 | T1 = (uint64)(*p) * (*eccn[0]); 360 | *q = (uint32)T1; 361 | T1 = T1 >> 32; 362 | 363 | for(i = 1; i < 5; i++) 364 | { 365 | T3 = 0; 366 | for(j = (i < 3 ? 0 : (i - 2)); j <= (i < 3 ? i : 2); j++) 367 | { 368 | T2 = (uint64)*(p + j) * (*(eccn[0] + (i - j))); 369 | T1 += (uint32)T2; 370 | T3 += (T2 >> 32); 371 | } 372 | *(q + i) = (uint32)T1; 373 | T1 = (T1 >> 32) + T3; 374 | } 375 | 376 | T2 = (uint64)(*p) * (*(eccn[0] + 5)); 377 | T1 += (uint32)T2; 378 | *(q + 5) = (uint32)T1; 379 | T1 = (T1 >> 32) + (T2 >> 32); 380 | 381 | *(q + 6) = (uint32)T1 + (*(p + 1)) * (*(eccn[0] + 5)); 382 | 383 | for(i = 5; i != 0; i--) 384 | *(p + i) = *(eccn[0] + i); 385 | *p = *eccn[0]; 386 | *(p + 6) = 0; 387 | 388 | if(sub(c, q, q, 7) == 1) 389 | { 390 | for(i = 5; i != 0; i--) 391 | *(amulb + i) = *(q + i); 392 | *amulb = *q; 393 | return; 394 | } 395 | 396 | while(compare(q, p, 7) != -1) 397 | sub(q, p, q, 7); 398 | for(i = 5; i != 0; i--) 399 | *(amulb + i) = *(q + i); 400 | *amulb = *q; 401 | } 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | -------------------------------------------------------------------------------- /GFp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 Xinxin Fan 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * - Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * - Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in 12 | * the documentation and/or other materials provided with the 13 | * distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 25 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 | * POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #ifndef __GFp_H__ 30 | #define __GFp_H__ 31 | 32 | /** 33 | * Big Integer Addition 34 | */ 35 | uint32 add(uint32 *a, uint32 *b, uint32 *aplusb, uint32 curve_id); 36 | 37 | /** 38 | * Big Integer Subtraction 39 | */ 40 | uint32 sub(uint32 *a, uint32 *b, uint32 *asubb, uint32 m); 41 | 42 | /** 43 | * Modular Addition over GF(p) 44 | */ 45 | void modpadd(uint32 *a, uint32 *b, uint32 *aplusb, uint32 curve_id); 46 | 47 | /** 48 | * Modular Subtraction over GF(p) 49 | */ 50 | void modpsub(uint32 *a, uint32 *b, uint32 *asubb, uint32 curve_id); 51 | 52 | /** 53 | * Modular Multiplication over GF(p) with one operand 128-bit 54 | */ 55 | void modpmul128(uint32 *a, uint32 *b, uint32 *amulb, uint32 curve_id); 56 | 57 | /** 58 | * Modular Multiplication over GF(p) with one operand 96-bit 59 | */ 60 | void modpmul96(uint32 *a, uint32 *b, uint32 *amulb); 61 | 62 | #endif /* __GFp_H__ */ 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /OpenECC.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 Xinxin Fan 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * - Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * - Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in 12 | * the documentation and/or other materials provided with the 13 | * distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 25 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 | * POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #include "stdio.h" 30 | #include "OpenECC.h" 31 | #include "GF2n.h" 32 | #include "ECCK.h" 33 | #include "AES128.h" 34 | #include "AESMMO.h" 35 | #include "GFp.h" 36 | 37 | /********************************************************************* 38 | Public Key Validation Primitive 39 | ********************************************************************/ 40 | uint32 pk_validation(ec_point_aff *Q, uint32 curve_id) 41 | { 42 | uint32 S[N], T[N]; 43 | 44 | switch(curve_id){ 45 | case sect163k1: 46 | //Q is infinity 47 | if(IF0_163(Q->x) && IF0_163(Q->y)) return 0; 48 | 49 | //Check the degree of x_Q and y_Q 50 | if(((Q->x[5] >> 3) != 0x0) || ((Q->y[5] >> 3) != 0x0)) return 0; 51 | break; 52 | case sect233k1: 53 | //Q is infinity 54 | if(IF0_233(Q->x) && IF0_233(Q->y)) return 0; 55 | 56 | //Check the degree of x_Q and y_Q 57 | if(((Q->x[7] >> 9) != 0x0) || ((Q->y[7] >> 9) != 0x0)) return 0; 58 | break; 59 | default: return 0; 60 | } 61 | 62 | //Compute x_Q^3 + 1 63 | modsq(Q->x, S, curve_id); 64 | modmul(Q->x, S, T, curve_id); 65 | if(curve_id == sect163k1) 66 | modadd(T, S, T, curve_id); 67 | T[0] = T[0] ^ 0x1; 68 | 69 | //Compute y_Q^2 + x_Qy_Q 70 | modsq(Q->y, S, curve_id); 71 | modadd(T, S, T, curve_id); 72 | modmul(Q->x, Q->y, S, curve_id); 73 | modadd(T, S, T, curve_id); 74 | 75 | switch(curve_id){ 76 | case sect163k1: 77 | if(IFN0_163(T)) return 0; 78 | 79 | //Check that 2Q is not infinity 80 | if(IF0_163(Q->x)) // Q is a 2-torsion point 81 | return 0; 82 | break; 83 | case sect233k1: 84 | if(IFN0_233(T)) return 0; 85 | 86 | //Check that 2Q or 4Q is not infinity 87 | if(IF0_233(Q->x) || IF1_233(Q->x)) // Q is a 2- or 4-torsion point 88 | return 0; 89 | break; 90 | default: return 0; 91 | } 92 | 93 | return 1; 94 | } 95 | 96 | /********************************************************************* 97 | Key Generation Primitive 98 | ********************************************************************/ 99 | void key_generation(ec_key_pair *key, uint8 *rnd, uint32 curve_id) 100 | { 101 | uint32 c[N]; 102 | uint32 i, Num; 103 | ec_point_aff Q; 104 | 105 | switch(curve_id){ 106 | case sect163k1: 107 | Num = 6; 108 | 109 | *(c + 5) = (uint32)(*(rnd + 20)) & 0x7; 110 | break; 111 | case sect233k1: 112 | Num = 8; 113 | 114 | *(c + 7) = (*(c + 7) << 8) | (uint32)(*(rnd + 29)); 115 | *(c + 7) = (*(c + 7) << 8) | (uint32)(*(rnd + 28)); 116 | *(c + 7) = *(c + 7) & 0xff; 117 | break; 118 | default: return; 119 | } 120 | 121 | for(i = 0; i < Num - 1; i++) 122 | { 123 | *(c + i) = (uint32)(*(rnd + 4*i + 3)); 124 | *(c + i) = (*(c + i) << 8) | (uint32)(*(rnd + 4*i + 2)); 125 | *(c + i) = (*(c + i) << 8) | (uint32)(*(rnd + 4*i + 1)); 126 | *(c + i) = (*(c + i) << 8) | (uint32)(*(rnd + 4*i)); 127 | } 128 | 129 | if(compare(c, eccn[curve_id], Num) != -1) 130 | sub(c, eccn[curve_id], c, Num); 131 | 132 | XTOY(key->d, c, Num); 133 | TNAF5_fixed_scalarmul(c, &Q, curve_id); 134 | point_compression(&Q, key->Qx, curve_id); 135 | } 136 | 137 | /********************************************************************* 138 | ECQV certificate request 139 | ********************************************************************/ 140 | void ECQV_request(ec_key_pair *key, uint8 *rnd, uint32 curve_id) 141 | { 142 | key_generation(key, rnd, curve_id); 143 | } 144 | 145 | /**************************************************************************** 146 | ECQV public key extraction 147 | ***************************************************************************/ 148 | uint32 ECQV_extraction(uint32 *QCAx, uint8 *CertA, uint32 *QAx, uint32 curve_id) 149 | { 150 | uint8 s[16]; 151 | uint32 i; 152 | uint32 e[N], BAx[N]; 153 | ec_point_aff BA, QCA, QA; 154 | ec_point_pro P; 155 | 156 | if((*CertA != 0x2) && (*CertA != 0x3)) return 0; 157 | 158 | //Convert BAS to a public key BA 159 | switch(curve_id){ 160 | case sect163k1: 161 | *(BAx + 5) = ((uint32)*CertA << 8)| ((uint32)*(CertA + 1)); 162 | for(i = 0; i < 5; i++) 163 | *(BAx + (4 - i)) = ((uint32)*(CertA+4*i+2) << 24) | ((uint32)*(CertA+4*i+3) << 16) | ((uint32)*(CertA+4*i+4) << 8) | ((uint32)*(CertA+4*i+5)); 164 | 165 | //Compute hash value of the certificate 166 | AES_MMO(CertA, 384, s); 167 | break; 168 | case sect233k1: 169 | *(BAx + 7) = ((uint32)*CertA << 16)| ((uint32)*(CertA + 1) << 8) | ((uint32)*(CertA + 2)); 170 | for(i = 0; i < 7; i++) 171 | *(BAx + (6 - i)) = ((uint32)*(CertA+4*i+3) << 24) | ((uint32)*(CertA+4*i+4) << 16) | ((uint32)*(CertA+4*i+5) << 8) | ((uint32)*(CertA+4*i+6)); 172 | 173 | //Compute hash value of the certificate 174 | AES_MMO(CertA, 456, s); 175 | break; 176 | default: return 0; 177 | } 178 | 179 | if(point_decompression(BAx, &BA, curve_id) == 0) return 0; 180 | 181 | //Validate the public key BA 182 | if(pk_validation(&BA, curve_id) == 0) return 0; 183 | 184 | for(i = 0; i < 4; i++) 185 | { 186 | *(e + i) = ((uint32)*(s+4*i) << 24) | ((uint32)*(s+4*i+1) << 16) | ((uint32)*(s+4*i+1) << 8) | ((uint32)*(s+4*i+3)); 187 | *(e + i + 4) = 0x0; 188 | } 189 | 190 | //Compute QA = e*BA + QCA 191 | if(point_decompression(QCAx, &QCA, curve_id) == 0) return 0; 192 | TNAF5_random_scalarmul(e, &BA, &QA, curve_id); 193 | affine_to_project(&QA, &P, curve_id); 194 | mixed_addition(&P, &QCA, &P, curve_id); 195 | project_to_affine(&P, &QA, curve_id); 196 | point_compression(&QA, QAx, curve_id); 197 | 198 | return 1; 199 | } 200 | 201 | /************************************************************************************** 202 | ECQV certificate validation 203 | *************************************************************************************/ 204 | uint32 ECQV_validation(uint32 *QCAx, uint32 *RAx, uint8 *CertA, uint32 *r, uint32 curve_id) 205 | { 206 | uint8 s[16]; 207 | uint32 i, t; 208 | uint32 e[N], BAx[N]; 209 | ec_point_aff BA, QCA, RA, R; 210 | ec_point_pro P; 211 | 212 | if(point_decompression(RAx, &RA, curve_id) == 0) return 0; 213 | 214 | //Validate the public key RA 215 | if(pk_validation(&RA, curve_id) == 0) return 0; 216 | 217 | if((*CertA != 0x2) && (*CertA != 0x3)) return 0; 218 | 219 | //Convert BAS to a public key BA 220 | switch(curve_id){ 221 | case sect163k1: 222 | *(BAx + 5) = ((uint32)*CertA << 8)| ((uint32)*(CertA + 1)); 223 | for(i = 0; i < 5; i++) 224 | *(BAx + (4 - i)) = ((uint32)*(CertA+4*i+2) << 24) | ((uint32)*(CertA+4*i+3) << 16) | ((uint32)*(CertA+4*i+4) << 8) | ((uint32)*(CertA+4*i+5)); 225 | 226 | //Compute hash value of the certificate 227 | AES_MMO(CertA, 384, s); 228 | break; 229 | case sect233k1: 230 | *(BAx + 7) = ((uint32)*CertA << 16)| ((uint32)*(CertA + 1) << 8) | ((uint32)*(CertA + 2)); 231 | for(i = 0; i < 7; i++) 232 | *(BAx + (6 - i)) = ((uint32)*(CertA+4*i+3) << 24) | ((uint32)*(CertA+4*i+4) << 16) | ((uint32)*(CertA+4*i+5) << 8) | ((uint32)*(CertA+4*i+6)); 233 | 234 | //Compute hash value of the certificate 235 | AES_MMO(CertA, 456, s); 236 | break; 237 | default: return 0; 238 | } 239 | 240 | if(point_decompression(BAx, &BA, curve_id) == 0) return 0; 241 | 242 | //Validate the public key BA 243 | if(pk_validation(&BA, curve_id) == 0) return 0; 244 | 245 | for(i = 0; i < 4; i++) 246 | { 247 | *(e + i) = ((uint32)*(s+4*i) << 24) | ((uint32)*(s+4*i+1) << 16) | ((uint32)*(s+4*i+1) << 8) | ((uint32)*(s+4*i+3)); 248 | *(e + i + 4) = 0x0; 249 | } 250 | 251 | //Compute e*(BA - RA)+ QCA 252 | point_negation(&RA, &R, curve_id); 253 | affine_to_project(&BA, &P, curve_id); 254 | mixed_addition(&P, &R, &P, curve_id); 255 | project_to_affine(&P, &BA, curve_id); 256 | TNAF5_random_scalarmul(e, &BA, &R, curve_id); 257 | affine_to_project(&R, &P, curve_id); 258 | point_decompression(QCAx, &QCA, curve_id); 259 | mixed_addition(&P, &QCA, &P, curve_id); 260 | project_to_affine(&P, &BA, curve_id); 261 | 262 | //Compute r*G 263 | TNAF5_fixed_scalarmul(r, &R, curve_id); 264 | 265 | switch(curve_id){ 266 | case sect163k1: 267 | t = (IFXeqY_163(BA.x, R.x)) && (IFXeqY_163(BA.y, R.y)); 268 | break; 269 | case sect233k1: 270 | t = (IFXeqY_233(BA.x, R.x)) && (IFXeqY_233(BA.y, R.y)); 271 | break; 272 | default: return 0; 273 | } 274 | 275 | if(t) return 1; 276 | else return 0; 277 | } 278 | 279 | /********************************************************************************************************************* 280 | ECMQV key agreement 281 | ********************************************************************************************************************/ 282 | uint32 ECMQV(ec_key_pair *keyA1, ec_key_pair *keyA2, uint32 *QB1x, uint32 *QB2x, uint32 len, uint8 *skey, uint32 curve_id) 283 | { 284 | uint32 QA2bar[N], QB2bar[N]; 285 | uint32 i, s[N]; 286 | uint32 t, Num; 287 | ec_point_aff P, QB1, QB2; 288 | ec_point_pro Q; 289 | uint8 Z[30]; 290 | 291 | switch(curve_id){ 292 | case sect163k1: 293 | Num = 6; 294 | t = 3; //t = Num/2 295 | 296 | //Compute integers QA2bar and QB2bar from QA2 and QB2 297 | *(QA2bar + 2) = (*(keyA2->Qx + 2) & 0x1ffff) | 0x20000; 298 | *(QB2bar + 2) = (*(QB2x + 2) & 0x1ffff) | 0x20000; 299 | break; 300 | case sect233k1: 301 | Num = 8; 302 | t = 4; //t = Num/2 303 | 304 | //Compute integers QA2bar and QB2bar from QA2 and QB2 305 | *(QA2bar + 3) = (*(keyA2->Qx + 3) & 0xfffff) | 0x100000; 306 | *(QB2bar + 3) = (*(QB2x + 3) & 0xfffff) | 0x100000; 307 | break; 308 | default: return 0; 309 | } 310 | 311 | //Compute integers QA2bar and QB2bar from QA2 and QB2 312 | for(i = Num - 1; i != (t - 1); i--) 313 | { 314 | *(QA2bar + i) = 0; 315 | *(QB2bar + i) = 0; 316 | } 317 | 318 | for(i = t - 2; i != 0; i--) 319 | { 320 | *(QA2bar + i) = *(keyA2->Qx + i); 321 | *(QB2bar + i) = *(QB2x + i); 322 | } 323 | *QA2bar = *keyA2->Qx; 324 | *QB2bar = *QB2x; 325 | 326 | //Compute an integer s = dA2 + QA2bar*dA1 (mod n) 327 | if(curve_id == sect233k1) 328 | modpmul128(QA2bar, keyA1->d, s, curve_id); 329 | else 330 | modpmul96(QA2bar, keyA1->d, s); 331 | modpadd(s, keyA2->d, s, curve_id); 332 | 333 | //Compute 4*s 334 | switch(curve_id){ 335 | case sect163k1: 336 | for(i = 5; i != 0; i--) 337 | *(s + i) = (*(s + i) << 1) | (*(s + (i - 1)) >> 31); 338 | *s = *s << 1; 339 | break; 340 | case sect233k1: 341 | for(i = 7; i != 0; i--) 342 | *(s + i) = (*(s + i) << 2) | (*(s + (i - 1)) >> 30); 343 | *s = *s << 2; 344 | break; 345 | default: return 0; 346 | } 347 | 348 | while(compare(s, eccn[curve_id], Num) != -1) 349 | sub(s, eccn[curve_id], s, Num); 350 | 351 | //Compute 4*s*(QB2 + QB2bar*QB1) 352 | if(point_decompression(QB1x, &QB1, curve_id) == 0) return 0; 353 | if(point_decompression(QB2x, &QB2, curve_id) == 0) return 0; 354 | TNAF5_random_scalarmul(QB2bar, &QB1, &P, curve_id); 355 | affine_to_project(&QB2, &Q, curve_id); 356 | mixed_addition(&Q, &P, &Q, curve_id); 357 | project_to_affine(&Q, &P, curve_id); 358 | TNAF5_random_scalarmul(s, &P, &P, curve_id); 359 | 360 | //If P is infinity, return error 361 | switch(curve_id){ 362 | case sect163k1: 363 | if(IF0_163(P.x) && IF0_163(P.y)) return 0; 364 | 365 | *Z = (uint8)(*(P.x + 5)); 366 | for(i = 1; i < 6; i++) 367 | { 368 | //x coordinate 369 | *(Z+4*(i-1)+1) = (uint8)(*(P.x + (5 - i)) >> 24); 370 | *(Z+4*(i-1)+2) = (uint8)(*(P.x + (5 - i)) >> 16); 371 | *(Z+4*(i-1)+3) = (uint8)(*(P.x + (5 - i)) >> 8); 372 | *(Z+4*(i-1)+4) = (uint8)(*(P.x + (5 - i))); 373 | } 374 | break; 375 | case sect233k1: 376 | if(IF0_233(P.x) && IF0_233(P.y)) return 0; 377 | 378 | *Z = (uint8)(*(P.x + 7) >> 8); 379 | *(Z + 1) = (uint8)*(P.x + 7); 380 | for(i = 1; i < 8; i++) 381 | { 382 | //x coordinate 383 | *(Z+4*(i-1)+2) = (uint8)(*(P.x + (7 - i)) >> 24); 384 | *(Z+4*(i-1)+3) = (uint8)(*(P.x + (7 - i)) >> 16); 385 | *(Z+4*(i-1)+4) = (uint8)(*(P.x + (7 - i)) >> 8); 386 | *(Z+4*(i-1)+5) = (uint8)(*(P.x + (7 - i))); 387 | } 388 | break; 389 | default: return 0; 390 | } 391 | 392 | //Get len bytes from the result as the shared key 393 | for(i = 0; i < len; i++) 394 | *(skey + i) = *(Z + i); 395 | 396 | return 1; 397 | } -------------------------------------------------------------------------------- /OpenECC.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 Xinxin Fan 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * - Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * - Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in 12 | * the documentation and/or other materials provided with the 13 | * distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 25 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 | * POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #ifndef __OpenECC_H__ 30 | #define __OpenECC_H__ 31 | 32 | /** 33 | * Support for both ZigBee Smart Energy 1.x and 1.2 34 | * Use curve sect163k1 for ZigBee Smart Energy 1.x 35 | * Use curve sect233k1 for ZigBee Smart Energy 1.2 36 | * Other koblitz curves defined in SEC 2 will be supported in the future. 37 | */ 38 | #define sect163k1 0 39 | #define sect233k1 1 40 | //#define sect239k1 2 41 | //#define sect283k1 3 42 | //#define sect409k1 4 43 | //#define sect571k1 5 44 | 45 | /** 46 | * Define data type 47 | */ 48 | typedef unsigned char uint8; /* Unsigned 8 bit value */ 49 | typedef unsigned short uint16; /* Unsigned 16 bit value */ 50 | typedef unsigned long uint32; /* Unsigned 32 bit value */ 51 | typedef unsigned long long uint64; /* Unsigned 64 bit value */ 52 | typedef long int sint32; /* Signed 32 bit value */ 53 | 54 | /** 55 | * Define macros 56 | */ 57 | #define XTOY(Y, X, n){\ 58 | uint32 i;\ 59 | for(i = n - 1; i != 0; i--)\ 60 | Y[i] = X[i];\ 61 | Y[0] = X[0];\ 62 | } 63 | #define XIS0(X, n){\ 64 | uint32 i;\ 65 | for(i = n - 1; i != 0; i--)\ 66 | X[i] = 0;\ 67 | X[0] = 0;\ 68 | } 69 | #define XIS1(X, n){\ 70 | uint32 i;\ 71 | for(i = n - 1; i != 0; i--)\ 72 | X[i] = 0;\ 73 | X[0] = 1;\ 74 | } 75 | //For the curve sect163k1 76 | #ifdef sect163k1 77 | #define IF1_163(X) X[0] == 1 && X[1] == 0 && X[2] == 0 && X[3] == 0 && X[4] == 0 && X[5] == 0 78 | #define IFN1_163(X) X[0] != 1 || X[1] != 0 || X[2] != 0 || X[3] != 0 || X[4] != 0 || X[5] != 0 79 | #define IF0_163(X) X[0] == 0 && X[1] == 0 && X[2] == 0 && X[3] == 0 && X[4] == 0 && X[5] == 0 80 | #define IFN0_163(X) X[0] != 0 || X[1] != 0 || X[2] != 0 || X[3] != 0 || X[4] != 0 || X[5] != 0 81 | #define IFXeqY_163(X,Y) X[0] == Y[0] && X[1] == Y[1] && X[2] == Y[2] && X[3] == Y[3] && X[4] == Y[4] && X[5] == Y[5] 82 | #endif 83 | 84 | //For the curve sect233k1 85 | #ifdef sect233k1 86 | #define IF1_233(X) X[0] == 1 && X[1] == 0 && X[2] == 0 && X[3] == 0 && X[4] == 0 && X[5] == 0 && X[6] == 0 && X[7] == 0 87 | #define IFN1_233(X) X[0] != 1 || X[1] != 0 || X[2] != 0 || X[3] != 0 || X[4] != 0 || X[5] != 0 || X[6] != 0 || X[7] != 0 88 | #define IF0_233(X) X[0] == 0 && X[1] == 0 && X[2] == 0 && X[3] == 0 && X[4] == 0 && X[5] == 0 && X[6] == 0 && X[7] == 0 89 | #define IFN0_233(X) X[0] != 0 || X[1] != 0 || X[2] != 0 || X[3] != 0 || X[4] != 0 || X[5] != 0 || X[6] != 0 || X[7] != 0 90 | #define IFXeqY_233(X,Y) X[0] == Y[0] && X[1] == Y[1] && X[2] == Y[2] && X[3] == Y[3] && X[4] == Y[4] && X[5] == Y[5] && X[6] == Y[6] && X[7] == Y[7] 91 | #endif 92 | 93 | #define N 8 94 | 95 | /** 96 | * Define an affine point (x, y) over the curve sect163k1 or sect233k1 97 | * A compressed affine point denoted by h||x, where h = 0x02 if y' = 0, or h = 0x03 if y' = 1 98 | */ 99 | typedef struct 100 | { 101 | uint32 x[N]; /* x coordinate of a point in affine representation */ 102 | uint32 y[N]; /* y coordinate of a point in affine representation */ 103 | }ec_point_aff; 104 | 105 | /** 106 | * Define a projective point (X, Y, Z) over the curve sect163k1 or sect233k1 107 | */ 108 | typedef struct 109 | { 110 | uint32 X[N]; /* X coordinate of a point (x, y) in projective representation */ 111 | uint32 Y[N]; /* Y coordinate of a point (x, y) in projective representation */ 112 | uint32 Z[N]; /* Z coordinate of a point (x, y) in projective representation */ 113 | }ec_point_pro; 114 | 115 | /** 116 | * Define a key pair over the curve sect163k1 or sect233k1 117 | */ 118 | typedef struct 119 | { 120 | uint32 d[N]; /* private key */ 121 | uint32 Qx[N]; /* public key in compressed form */ 122 | }ec_key_pair; 123 | 124 | /** 125 | * Define curve parameters 126 | */ 127 | ec_point_aff G[2]; //base point G for the curve sect163k1 and sect233k1 128 | uint32 eccn[2][N]; //group order n of the curve sect163k1 and sect233k1 129 | uint32 eccu[2][N+1]; //b = 2^32, eccu = [b^(2*Num)/eccn] 130 | 131 | /** 132 | * Public key validation 133 | * 134 | * @param Q a public key 135 | * valid return 1 136 | * invalid return 0 137 | */ 138 | uint32 pk_validation(ec_point_aff *Q, uint32 curve_id); 139 | 140 | /** 141 | * Key generation 142 | * 143 | * @param key a key pair 144 | * @param rnd a random number (21-byte for sect163k1 and 30-byte for sect233k1) 145 | */ 146 | void key_generation(ec_key_pair *key, uint8 *rnd, uint32 curve_id); 147 | 148 | /** 149 | * ECQV certificate request 150 | * 151 | * @param key a key pair 152 | * @param rnd a random number (21-byte for sect163k1 and 30-byte for sect233k1) 153 | */ 154 | void ECQV_request(ec_key_pair *key, uint8 *rnd, uint32 curve_id); 155 | 156 | /** 157 | * ECQV public key extraction 158 | * 159 | * @param QCAx the CA's public key in compressed form 160 | * @param CertA an implicit certificate for user idA 161 | * @param QAx a user A's public key in compressed form 162 | * succeed return 1 163 | * fail return 0 164 | */ 165 | uint32 ECQV_extraction(uint32 *QCAx, uint8 *CertA, uint32 *QAx, uint32 curve_id); 166 | 167 | /** 168 | * ECQV explicit certificate validation 169 | * 170 | * @param QCAx the CA's public key in compressed form 171 | * @param RAx a user A's public key in compressed form 172 | * @param CertA an implicit certificate for user idA 173 | * @param r CA's private key contribution 174 | * succeed return 1 175 | * fail return 0 176 | */ 177 | uint32 ECQV_validation(uint32 *QCAx, uint32 *RAx, uint8 *CertA, uint32 *r, uint32 curve_id); 178 | 179 | /** 180 | * ECMQV key agreement scheme 181 | * 182 | * @param keyA1 A's key pair (dA1, QA1) 183 | * @param keyA2 A's key pair (dA2, QA2) 184 | * @param QB1 B's public key QB1 185 | * @param QB2 B's public key QB2 186 | * @param len the length of shared key in bytes 187 | * @param skey a shared key between A and B 188 | * succeed return 1 189 | * fail return 0 190 | */ 191 | uint32 ECMQV(ec_key_pair *keyA1, ec_key_pair *keyA2, uint32 *QB1, uint32 *QB2, uint32 len, uint8 *skey, uint32 curve_id); 192 | 193 | #endif /* __OpenECC_H__ */ 194 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # OpenECC 2 | 3 | An Open Source Library for Elliptic Curve Cryptosystem (http://openecc.org) 4 | 5 | ## Introduction 6 | 7 | OpenECC is a software package that implements ECC-based protocols for Zigbee Smart Energy 1.x and 1.2 applications. It provides an implicit certificate scheme (ECQV), a key exchange protocol (ECMQV), and a digital signature scheme (ECDSA). 8 | 9 | OpenECC is intended for Zigbee platforms based on ARM Cortex-M3 processors. The current version is implemented in C and takes into account both speed and memory optimization techniques. OpenECC supports SECG recommended 163-bit and 233-bit Koblitz curve sect163k1 and sect233k1. 10 | 11 | For questions please contact Dr. Xinxin Fan at fan@openecc.org. 12 | 13 | ## License 14 | 15 | Copyright 2012 Xinxin Fan 16 | All rights reserved. 17 | 18 | Redistribution and use in source and binary forms, with or without 19 | modification, are permitted provided that the following conditions 20 | are met: 21 | - Redistributions of source code must retain the above copyright 22 | notice, this list of conditions and the following disclaimer. 23 | - Redistributions in binary form must reproduce the above copyright 24 | notice, this list of conditions and the following disclaimer in 25 | the documentation and/or other materials provided with the 26 | distribution. 27 | 28 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 29 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 30 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 31 | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 32 | COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 33 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 34 | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 35 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 36 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 37 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 38 | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 39 | POSSIBILITY OF SUCH DAMAGE. 40 | -------------------------------------------------------------------------------- /TEST163.c: -------------------------------------------------------------------------------- 1 | 2 | //system libraries 3 | #include "stdio.h" 4 | #include "stdlib.h" 5 | #include "math.h" 6 | #include "time.h" 7 | #include "string.h" 8 | //user libraries 9 | #include "OpenECC.h" 10 | #include "GF2n.h" 11 | #include "GFp.h" 12 | #include "ECCK.h" 13 | #include "AES128.h" 14 | #include "AESMMO.h" 15 | #include "DRNG.h" 16 | #include "ECDSA.h" 17 | 18 | // The base point G (extern variable defined in ECCK.c) 19 | extern ec_point_aff G[2]; 20 | 21 | void main() 22 | { 23 | uint8 seed[16]; //seed for DRNG 24 | uint8 rndnum[21]; //163-bit random numbers 25 | uint32 i, r; 26 | ec_key_pair keypair; 27 | uint8 Uid[26] = {0x00,0x0d,0x6f,0x00,0x00,0x06,0x7a,0x1f,0x54,0x45,0x53,0x54,0x53,0x45,0x43,0x41,0x01,0x09,0x00,0x0b,0x00,0x00,0x00,0x00,0x00,0x00}; 28 | //The following are for ECMQV 29 | ec_key_pair keyA1, keyA2, keyB1, keyB2; 30 | uint8 skey[21]; 31 | //The following are for ECDSA 32 | uint32 s[6], t[6]; 33 | 34 | for(i = 0; i < 16; i++) seed[i] = 0x0; 35 | srand((unsigned) time (NULL)); 36 | for(i = 0; i < 8; i++) 37 | { 38 | r = rand(); 39 | seed[2*i] = (uint8)r; 40 | seed[2*i + 1] = (uint8)(r >> 8); 41 | } 42 | printf("Seed = ");for(i = 0; i < 16; i++){printf("%02x ",seed[i]);}printf("\n"); 43 | 44 | //Initialize the DRNG 45 | ctr_init(seed); 46 | for(i = 0; i < 21; i++) rndnum[i] = 0x0; 47 | 48 | //ECMQV testing 49 | if(ctr_generate(163, rndnum) == 1) 50 | key_generation(&keyA1, rndnum, sect163k1); 51 | if(ctr_generate(163, rndnum) == 1) 52 | key_generation(&keyA2, rndnum, sect163k1); 53 | if(ctr_generate(163, rndnum) == 1) 54 | key_generation(&keyB1, rndnum, sect163k1); 55 | if(ctr_generate(163, rndnum) == 1) 56 | key_generation(&keyB2, rndnum, sect163k1); 57 | printf("\nTwo key pairs for the user A...\n"); 58 | printf("The first private key:\n"); 59 | printf(" dA1 = ");for(i = 0; i < 6; i++){printf("%08x ",keyA1.d[5 - i]);}printf("\n"); 60 | printf("The first public key:\n"); 61 | printf(" QA1x = ");for(i = 0; i < 6; i++){printf("%08x ",keyA1.Qx[5 - i]);}printf("\n"); 62 | printf("The second private key:\n"); 63 | printf(" dA2 = ");for(i = 0; i < 6; i++){printf("%08x ",keyA2.d[5 - i]);}printf("\n"); 64 | printf("The second public key:\n"); 65 | printf(" QA2x = ");for(i = 0; i < 6; i++){printf("%08x ",keyA2.Qx[5 - i]);}printf("\n"); 66 | printf("\nTwo key pairs for the user B...\n"); 67 | printf("The first private key:\n"); 68 | printf(" dB1 = ");for(i = 0; i < 6; i++){printf("%08x ",keyB1.d[5 - i]);}printf("\n"); 69 | printf("The first public key:\n"); 70 | printf(" QB1x = ");for(i = 0; i < 6; i++){printf("%08x ",keyB1.Qx[5 - i]);}printf("\n"); 71 | printf("The second private key:\n"); 72 | printf(" dB2 = ");for(i = 0; i < 6; i++){printf("%08x ",keyB2.d[5 - i]);}printf("\n"); 73 | printf("The second public key:\n"); 74 | printf(" QB2x = ");for(i = 0; i < 6; i++){printf("%08x ",keyB2.Qx[5 - i]);}printf("\n"); 75 | printf("\nECMQV Key Agreement..."); 76 | if(ECMQV(&keyA1, &keyA2, keyB1.Qx, keyB2.Qx, 21, skey, sect163k1) == 1) 77 | { 78 | printf("The shared key computed by A:\n"); 79 | printf(" skA = ");for(i = 0; i < 21; i++){printf("%02x",skey[i]);}printf("\n"); 80 | } 81 | else 82 | { 83 | printf("ERROR!\n"); 84 | goto L; 85 | } 86 | if(ECMQV(&keyB1, &keyB2, keyA1.Qx, keyA2.Qx, 21, skey, sect163k1) == 1) 87 | { 88 | printf("The shared key computed by B:\n"); 89 | printf(" skB = ");for(i = 0; i < 21; i++){printf("%02x",skey[i]);}printf("\n"); 90 | } 91 | else printf("ERROR!\n"); 92 | 93 | //ECDSA testing 94 | printf("\nECDSA Signature Generation...\n"); 95 | if(ctr_generate(163, rndnum) == 1) 96 | key_generation(&keypair,rndnum, sect163k1); 97 | printf("Signer's Private key:\n"); 98 | printf(" k = ");for(i = 0; i < 6; i++){printf("%08x ",keypair.d[5 - i]);}printf("\n"); 99 | printf("Signer's Public key:\n"); 100 | printf(" x = ");for(i = 0; i < 6; i++){printf("%08x ",keypair.Qx[5 - i]);}printf("\n"); 101 | printf("Message:\n"); 102 | printf("msg = ");for(i = 0; i < 26; i++){printf("%02x",Uid[i]);}printf("\n"); 103 | ctr_generate(232, rndnum); 104 | if(ECDSA_sign(keypair.d, rndnum, Uid, 26, s, t, sect163k1) == 1) 105 | { 106 | printf("The signature are:\n"); 107 | printf(" r = ");for(i = 0; i < 6; i++){printf("%08x ",s[5 - i]);}printf("\n"); 108 | printf(" s = ");for(i = 0; i < 6; i++){printf("%08x ",t[5 - i]);}printf("\n"); 109 | } 110 | else 111 | { 112 | printf("ERROR!\n"); 113 | goto L; 114 | } 115 | if(ECDSA_verify(keypair.Qx, Uid, 26, s, t, sect163k1) == 1) 116 | printf("The signature is valid!\n"); 117 | else 118 | printf("The signature is invalid!\n"); 119 | L:; 120 | } 121 | -------------------------------------------------------------------------------- /TEST233.c: -------------------------------------------------------------------------------- 1 | 2 | //system libraries 3 | #include "stdio.h" 4 | #include "stdlib.h" 5 | #include "math.h" 6 | #include "time.h" 7 | #include "string.h" 8 | //user libraries 9 | #include "OpenECC.h" 10 | #include "GF2n.h" 11 | #include "GFp.h" 12 | #include "ECCK.h" 13 | #include "AES128.h" 14 | #include "AESMMO.h" 15 | #include "DRNG.h" 16 | #include "ECDSA.h" 17 | 18 | // The base point G (extern variable defined in ECCK233.c) 19 | extern ec_point_aff G[2]; 20 | 21 | void main() 22 | { 23 | uint8 seed[16]; //seed for DRNG 24 | uint8 rndnum[30]; //233-bit random numbers 25 | uint32 i, r; 26 | ec_key_pair keypair; 27 | uint8 Uid[26] = {0x00,0x0d,0x6f,0x00,0x00,0x06,0x7a,0x1f,0x54,0x45,0x53,0x54,0x53,0x45,0x43,0x41,0x01,0x09,0x00,0x0b,0x00,0x00,0x00,0x00,0x00,0x00}; 28 | //The following are for ECMQV 29 | ec_key_pair keyA1, keyA2, keyB1, keyB2; 30 | uint8 skey[30]; 31 | //The following are for ECDSA 32 | uint32 s[8], t[8]; 33 | 34 | for(i = 0; i < 16; i++) seed[i] = 0x0; 35 | srand((unsigned) time (NULL)); 36 | for(i = 0; i < 8; i++) 37 | { 38 | r = rand(); 39 | seed[2*i] = (uint8)r; 40 | seed[2*i + 1] = (uint8)(r >> 8); 41 | } 42 | printf("Seed = ");for(i = 0; i < 16; i++){printf("%02x ",seed[i]);}printf("\n"); 43 | 44 | //Initialize the DRNG 45 | ctr_init(seed); 46 | for(i = 0; i < 30; i++) rndnum[i] = 0x0; 47 | 48 | //ECMQV testing with curve sect233k1 49 | if(ctr_generate(232, rndnum) == 1) 50 | key_generation(&keyA1, rndnum, sect233k1); 51 | if(ctr_generate(232, rndnum) == 1) 52 | key_generation(&keyA2, rndnum, sect233k1); 53 | if(ctr_generate(232, rndnum) == 1) 54 | key_generation(&keyB1, rndnum, sect233k1); 55 | if(ctr_generate(232, rndnum) == 1) 56 | key_generation(&keyB2, rndnum, sect233k1); 57 | printf("\nTwo key pairs for the user A...\n"); 58 | printf("The first private key:\n"); 59 | printf(" dA1 = ");for(i = 0; i < 8; i++){printf("%08x ",keyA1.d[7 - i]);}printf("\n"); 60 | printf("The first public key:\n"); 61 | printf(" QA1x = ");for(i = 0; i < 8; i++){printf("%08x ",keyA1.Qx[7 - i]);}printf("\n"); 62 | printf("The second private key:\n"); 63 | printf(" dA2 = ");for(i = 0; i < 8; i++){printf("%08x ",keyA2.d[7 - i]);}printf("\n"); 64 | printf("The second public key:\n"); 65 | printf(" QA2x = ");for(i = 0; i < 8; i++){printf("%08x ",keyA2.Qx[7 - i]);}printf("\n"); 66 | printf("\nTwo key pairs for the user B...\n"); 67 | printf("The first private key:\n"); 68 | printf(" dB1 = ");for(i = 0; i < 8; i++){printf("%08x ",keyB1.d[7 - i]);}printf("\n"); 69 | printf("The first public key:\n"); 70 | printf(" QB1x = ");for(i = 0; i < 8; i++){printf("%08x ",keyB1.Qx[7 - i]);}printf("\n"); 71 | printf("The second private key:\n"); 72 | printf(" dB2 = ");for(i = 0; i < 8; i++){printf("%08x ",keyB2.d[7 - i]);}printf("\n"); 73 | printf("The second public key:\n"); 74 | printf(" QB2x = ");for(i = 0; i < 8; i++){printf("%08x ",keyB2.Qx[7 - i]);}printf("\n"); 75 | printf("\nECMQV Key Agreement..."); 76 | if(ECMQV(&keyA1, &keyA2, keyB1.Qx, keyB2.Qx, 30, skey, sect233k1) == 1) 77 | { 78 | printf("The shared key computed by A:\n"); 79 | printf(" skA = ");for(i = 0; i < 30; i++){printf("%02x",skey[i]);}printf("\n"); 80 | } 81 | else 82 | { 83 | printf("ERROR!\n"); 84 | goto L; 85 | } 86 | if(ECMQV(&keyB1, &keyB2, keyA1.Qx, keyA2.Qx, 30, skey, sect233k1) == 1) 87 | { 88 | printf("The shared key computed by B:\n"); 89 | printf(" skB = ");for(i = 0; i < 30; i++){printf("%02x",skey[i]);}printf("\n"); 90 | } 91 | else printf("ERROR!\n"); 92 | 93 | //ECDSA testing with curve sect233k1 94 | printf("\nECDSA Signature Generation...\n"); 95 | if(ctr_generate(232, rndnum) == 1) 96 | key_generation(&keypair,rndnum, sect233k1); 97 | printf("Signer's Private key:\n"); 98 | printf(" k = ");for(i = 0; i < 8; i++){printf("%08x ",keypair.d[7 - i]);}printf("\n"); 99 | printf("Signer's Public key:\n"); 100 | printf(" x = ");for(i = 0; i < 8; i++){printf("%08x ",keypair.Qx[7 - i]);}printf("\n"); 101 | printf("Message:\n"); 102 | printf("msg = ");for(i = 0; i < 26; i++){printf("%02x",Uid[i]);}printf("\n"); 103 | ctr_generate(232, rndnum); 104 | if(ECDSA_sign(keypair.d, rndnum, Uid, 26, s, t, sect233k1) == 1) 105 | { 106 | printf("The signature are:\n"); 107 | printf(" r = ");for(i = 0; i < 8; i++){printf("%08x ",s[7 - i]);}printf("\n"); 108 | printf(" s = ");for(i = 0; i < 8; i++){printf("%08x ",t[7 - i]);}printf("\n"); 109 | } 110 | else 111 | { 112 | printf("ERROR!\n"); 113 | goto L; 114 | } 115 | if(ECDSA_verify(keypair.Qx, Uid, 26, s, t, sect233k1) == 1) 116 | printf("The signature is valid!\n"); 117 | else 118 | printf("The signature is invalid!\n"); 119 | L:; 120 | } 121 | --------------------------------------------------------------------------------