annotate ecc.c @ 143:5d99163f7e32 libtomcrypt-orig

import of libtomcrypt 0.99
author Matt Johnston <matt@ucc.asn.au>
date Sun, 19 Dec 2004 11:34:45 +0000
parents 7faae8f46238
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2 *
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3 * LibTomCrypt is a library that provides various cryptographic
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
4 * algorithms in a highly modular and flexible manner.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
5 *
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
6 * The library is free for all purposes without any express
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
7 * guarantee it works.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
8 *
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
9 * Tom St Denis, [email protected], http://libtomcrypt.org
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
10 */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
11
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
12 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
13 *
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
14 * All curves taken from NIST recommendation paper of July 1999
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
15 * Available at http://csrc.nist.gov/cryptval/dss.htm
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
16 */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
17
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
18 #include "mycrypt.h"
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
19
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
20 #ifdef MECC
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
21
143
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
22 /* size of our temp buffers for exported keys */
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
23 #define ECC_BUF_SIZE 160
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
24
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
25 /* max private key size */
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
26 #define ECC_MAXSIZE 66
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
27
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
28 /* This holds the key settings. ***MUST*** be organized by size from smallest to largest. */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
29 static const struct {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
30 int size;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
31 char *name, *prime, *B, *order, *Gx, *Gy;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
32 } sets[] = {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
33 #ifdef ECC160
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
34 {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
35 20,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
36 "ECC-160",
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
37 /* prime */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
38 "G00000000000000000000000007",
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
39 /* B */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
40 "1oUV2vOaSlWbxr6",
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
41 /* order */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
42 "G0000000000004sCQUtDxaqDUN5",
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
43 /* Gx */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
44 "jpqOf1BHus6Yd/pyhyVpP",
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
45 /* Gy */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
46 "D/wykuuIFfr+vPyx7kQEPu8MixO",
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
47 },
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
48 #endif
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
49 #ifdef ECC192
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
50 {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
51 24,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
52 "ECC-192",
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
53 /* prime */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
54 "/////////////////////l//////////",
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
55
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
56 /* B */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
57 "P2456UMSWESFf+chSYGmIVwutkp1Hhcn",
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
58
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
59 /* order */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
60 "////////////////cTxuDXHhoR6qqYWn",
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
61
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
62 /* Gx */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
63 "68se3h0maFPylo3hGw680FJ/2ls2/n0I",
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
64
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
65 /* Gy */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
66 "1nahbV/8sdXZ417jQoJDrNFvTw4UUKWH"
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
67 },
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
68 #endif
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
69 #ifdef ECC224
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
70 {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
71 28,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
72 "ECC-224",
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
73
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
74 /* prime */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
75 "400000000000000000000000000000000000BV",
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
76
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
77 /* B */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
78 "21HkWGL2CxJIp",
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
79
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
80 /* order */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
81 "4000000000000000000Kxnixk9t8MLzMiV264/",
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
82
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
83 /* Gx */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
84 "jpqOf1BHus6Yd/pyhyVpP",
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
85
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
86 /* Gy */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
87 "3FCtyo2yHA5SFjkCGbYxbOvNeChwS+j6wSIwck",
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
88 },
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
89 #endif
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
90 #ifdef ECC256
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
91 {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
92 32,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
93 "ECC-256",
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
94 /* Prime */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
95 "F////y000010000000000000000////////////////",
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
96
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
97 /* B */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
98 "5h6DTYgEfFdi+kzLNQOXhnb7GQmp5EmzZlEF3udqc1B",
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
99
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
100 /* Order */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
101 "F////y00000//////////+yvlgjfnUUXFEvoiByOoLH",
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
102
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
103 /* Gx */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
104 "6iNqVBXB497+BpcvMEaGF9t0ts1BUipeFIXEKNOcCAM",
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
105
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
106 /* Gy */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
107 "4/ZGkB+6d+RZkVhIdmFdXOhpZDNQp5UpiksG6Wtlr7r"
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
108 },
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
109 #endif
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
110 #ifdef ECC384
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
111 {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
112 48,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
113 "ECC-384",
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
114 /* prime */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
115 "//////////////////////////////////////////x/////00000000003/"
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
116 "////",
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
117
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
118 /* B */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
119 "ip4lf+8+v+IOZWLhu/Wj6HWTd6x+WK4I0nG8Zr0JXrh6LZcDYYxHdIg5oEtJ"
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
120 "x2hl",
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
121
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
122 /* Order */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
123 "////////////////////////////////nsDDWVGtBTzO6WsoIB2dUkpi6MhC"
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
124 "nIbp",
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
125
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
126 /* Gx and Gy */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
127 "geVA8hwB1JUEiSSUyo2jT6uTEsABfvkOMVT1u89KAZXL0l9TlrKfR3fKNZXo"
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
128 "TWgt",
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
129
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
130 "DXVUIfOcB6zTdfY/afBSAVZq7RqecXHywTen4xNmkC0AOB7E7Nw1dNf37NoG"
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
131 "wWvV"
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
132 },
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
133 #endif
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
134 #ifdef ECC521
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
135 {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
136 65,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
137 "ECC-521",
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
138 /* prime */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
139 "V///////////////////////////////////////////////////////////"
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
140 "///////////////////////////",
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
141
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
142 /* B */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
143 "56LFhbXZXoQ7vAQ8Q2sXK3kejfoMvcp5VEuj8cHZl49uLOPEL7iVfDx5bB0l"
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
144 "JknlmSrSz+8FImqyUz57zHhK3y0",
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
145
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
146 /* Order */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
147 "V//////////////////////////////////////////+b66XuE/BvPhVym1I"
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
148 "FS9fT0xjScuYPn7hhjljnwHE6G9",
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
149
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
150 /* Gx and Gy */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
151 "CQ5ZWQt10JfpPu+osOZbRH2d6I1EGK/jI7uAAzWQqqzkg5BNdVlvrae/Xt19"
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
152 "wB/gDupIBF1XMf2c/b+VZ72vRrc",
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
153
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
154 "HWvAMfucZl015oANxGiVHlPcFL4ILURH6WNhxqN9pvcB9VkSfbUz2P0nL2v0"
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
155 "J+j1s4rF726edB2G8Y+b7QVqMPG",
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
156 },
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
157 #endif
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
158 {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
159 0,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
160 NULL, NULL, NULL, NULL, NULL, NULL
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
161 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
162 };
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
163
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
164 #if 0
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
165
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
166 /* you plug in a prime and B value and it finds a pseudo-random base point */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
167 void ecc_find_base(void)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
168 {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
169 static char *prime = "26959946667150639794667015087019630673637144422540572481103610249951";
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
170 static char *order = "26959946667150639794667015087019637467111563745054605861463538557247";
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
171 static char *b = "9538957348957353489587";
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
172 mp_int pp, p, r, B, tmp1, tmp2, tx, ty, x, y;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
173 char buf[4096];
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
174 int i;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
175
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
176 mp_init_multi(&tx, &ty, &x, &y, &p, &pp, &r, &B, &tmp1, &tmp2, NULL);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
177 mp_read_radix(&p, prime, 10);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
178 mp_read_radix(&r, order, 10);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
179 mp_read_radix(&B, b, 10);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
180
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
181 /* get (p+1)/4 */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
182 mp_add_d(&p, 1, &pp);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
183 mp_div_2(&pp, &pp);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
184 mp_div_2(&pp, &pp);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
185
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
186 buf[0] = 0;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
187 do {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
188 printf("."); fflush(stdout);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
189 /* make a random value of x */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
190 for (i = 0; i < 16; i++) buf[i+1] = rand() & 255;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
191 mp_read_raw(&x, buf, 17);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
192 mp_copy(&x, &tx);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
193
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
194 /* now compute x^3 - 3x + b */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
195 mp_expt_d(&x, 3, &tmp1);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
196 mp_mul_d(&x, 3, &tmp2);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
197 mp_sub(&tmp1, &tmp2, &tmp1);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
198 mp_add(&tmp1, &B, &tmp1);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
199 mp_mod(&tmp1, &p, &tmp1);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
200
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
201 /* now compute sqrt via x^((p+1)/4) */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
202 mp_exptmod(&tmp1, &pp, &p, &tmp2);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
203 mp_copy(&tmp2, &ty);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
204
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
205 /* now square it */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
206 mp_sqrmod(&tmp2, &p, &tmp2);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
207
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
208 /* tmp2 should equal tmp1 */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
209 } while (mp_cmp(&tmp1, &tmp2));
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
210
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
211 /* now output values in way that libtomcrypt wants */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
212 mp_todecimal(&p, buf);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
213 printf("\n\np==%s\n", buf);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
214 mp_tohex(&B, buf);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
215 printf("b==%s\n", buf);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
216 mp_todecimal(&r, buf);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
217 printf("r==%s\n", buf);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
218 mp_tohex(&tx, buf);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
219 printf("Gx==%s\n", buf);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
220 mp_tohex(&ty, buf);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
221 printf("Gy==%s\n", buf);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
222
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
223 mp_clear_multi(&tx, &ty, &x, &y, &p, &pp, &r, &B, &tmp1, &tmp2, NULL);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
224 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
225
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
226 #endif
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
227
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
228 static int is_valid_idx(int n)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
229 {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
230 int x;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
231
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
232 for (x = 0; sets[x].size != 0; x++);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
233 if ((n < 0) || (n >= x)) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
234 return 0;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
235 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
236 return 1;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
237 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
238
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
239 static ecc_point *new_point(void)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
240 {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
241 ecc_point *p;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
242 p = XMALLOC(sizeof(ecc_point));
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
243 if (p == NULL) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
244 return NULL;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
245 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
246 if (mp_init_multi(&p->x, &p->y, NULL) != MP_OKAY) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
247 XFREE(p);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
248 return NULL;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
249 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
250 return p;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
251 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
252
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
253 static void del_point(ecc_point *p)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
254 {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
255 /* prevents free'ing null arguments */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
256 if (p != NULL) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
257 mp_clear_multi(&p->x, &p->y, NULL);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
258 XFREE(p);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
259 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
260 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
261
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
262 /* double a point R = 2P, R can be P*/
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
263 static int dbl_point(ecc_point *P, ecc_point *R, mp_int *modulus, mp_int *mu)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
264 {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
265 mp_int s, tmp, tmpx;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
266 int err;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
267
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
268 if ((err = mp_init_multi(&s, &tmp, &tmpx, NULL)) != MP_OKAY) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
269 return mpi_to_ltc_error(err);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
270 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
271
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
272 /* s = (3Xp^2 + a) / (2Yp) */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
273 if ((err = mp_mul_2(&P->y, &tmp)) != MP_OKAY) { goto error; } /* tmp = 2*y */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
274 if ((err = mp_invmod(&tmp, modulus, &tmp)) != MP_OKAY) { goto error; } /* tmp = 1/tmp mod modulus */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
275 if ((err = mp_sqr(&P->x, &s)) != MP_OKAY) { goto error; } /* s = x^2 */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
276 if ((err = mp_reduce(&s, modulus, mu)) != MP_OKAY) { goto error; }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
277 if ((err = mp_mul_d(&s,(mp_digit)3, &s)) != MP_OKAY) { goto error; } /* s = 3*(x^2) */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
278 if ((err = mp_sub_d(&s,(mp_digit)3, &s)) != MP_OKAY) { goto error; } /* s = 3*(x^2) - 3 */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
279 if (mp_cmp_d(&s, 0) == MP_LT) { /* if s < 0 add modulus */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
280 if ((err = mp_add(&s, modulus, &s)) != MP_OKAY) { goto error; }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
281 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
282 if ((err = mp_mul(&s, &tmp, &s)) != MP_OKAY) { goto error; } /* s = tmp * s mod modulus */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
283 if ((err = mp_reduce(&s, modulus, mu)) != MP_OKAY) { goto error; }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
284
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
285 /* Xr = s^2 - 2Xp */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
286 if ((err = mp_sqr(&s, &tmpx)) != MP_OKAY) { goto error; } /* tmpx = s^2 */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
287 if ((err = mp_reduce(&tmpx, modulus, mu)) != MP_OKAY) { goto error; } /* tmpx = tmpx mod modulus */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
288 if ((err = mp_sub(&tmpx, &P->x, &tmpx)) != MP_OKAY) { goto error; } /* tmpx = tmpx - x */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
289 if ((err = mp_submod(&tmpx, &P->x, modulus, &tmpx)) != MP_OKAY) { goto error; } /* tmpx = tmpx - x mod modulus */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
290
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
291 /* Yr = -Yp + s(Xp - Xr) */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
292 if ((err = mp_sub(&P->x, &tmpx, &tmp)) != MP_OKAY) { goto error; } /* tmp = x - tmpx */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
293 if ((err = mp_mul(&tmp, &s, &tmp)) != MP_OKAY) { goto error; } /* tmp = tmp * s */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
294 if ((err = mp_submod(&tmp, &P->y, modulus, &R->y)) != MP_OKAY) { goto error; } /* y = tmp - y mod modulus */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
295 if ((err = mp_copy(&tmpx, &R->x)) != MP_OKAY) { goto error; } /* x = tmpx */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
296
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
297 err = CRYPT_OK;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
298 goto done;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
299 error:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
300 err = mpi_to_ltc_error(err);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
301 done:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
302 mp_clear_multi(&tmpx, &tmp, &s, NULL);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
303 return err;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
304 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
305
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
306 /* add two different points over Z/pZ, R = P + Q, note R can equal either P or Q */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
307 static int add_point(ecc_point *P, ecc_point *Q, ecc_point *R, mp_int *modulus, mp_int *mu)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
308 {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
309 mp_int s, tmp, tmpx;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
310 int err;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
311
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
312 if ((err = mp_init(&tmp)) != MP_OKAY) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
313 return mpi_to_ltc_error(err);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
314 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
315
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
316 /* is P==Q or P==-Q? */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
317 if (((err = mp_neg(&Q->y, &tmp)) != MP_OKAY) || ((err = mp_mod(&tmp, modulus, &tmp)) != MP_OKAY)) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
318 mp_clear(&tmp);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
319 return mpi_to_ltc_error(err);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
320 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
321
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
322 if (mp_cmp(&P->x, &Q->x) == MP_EQ)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
323 if (mp_cmp(&P->y, &Q->y) == MP_EQ || mp_cmp(&P->y, &tmp) == MP_EQ) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
324 mp_clear(&tmp);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
325 return dbl_point(P, R, modulus, mu);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
326 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
327
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
328 if ((err = mp_init_multi(&tmpx, &s, NULL)) != MP_OKAY) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
329 mp_clear(&tmp);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
330 return mpi_to_ltc_error(err);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
331 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
332
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
333 /* get s = (Yp - Yq)/(Xp-Xq) mod p */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
334 if ((err = mp_sub(&P->x, &Q->x, &tmp)) != MP_OKAY) { goto error; } /* tmp = Px - Qx mod modulus */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
335 if (mp_cmp_d(&tmp, 0) == MP_LT) { /* if tmp<0 add modulus */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
336 if ((err = mp_add(&tmp, modulus, &tmp)) != MP_OKAY) { goto error; }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
337 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
338 if ((err = mp_invmod(&tmp, modulus, &tmp)) != MP_OKAY) { goto error; } /* tmp = 1/tmp mod modulus */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
339 if ((err = mp_sub(&P->y, &Q->y, &s)) != MP_OKAY) { goto error; } /* s = Py - Qy mod modulus */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
340 if (mp_cmp_d(&s, 0) == MP_LT) { /* if s<0 add modulus */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
341 if ((err = mp_add(&s, modulus, &s)) != MP_OKAY) { goto error; }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
342 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
343 if ((err = mp_mul(&s, &tmp, &s)) != MP_OKAY) { goto error; } /* s = s * tmp mod modulus */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
344 if ((err = mp_reduce(&s, modulus, mu)) != MP_OKAY) { goto error; }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
345
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
346 /* Xr = s^2 - Xp - Xq */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
347 if ((err = mp_sqr(&s, &tmp)) != MP_OKAY) { goto error; } /* tmp = s^2 mod modulus */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
348 if ((err = mp_reduce(&tmp, modulus, mu)) != MP_OKAY) { goto error; }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
349 if ((err = mp_sub(&tmp, &P->x, &tmp)) != MP_OKAY) { goto error; } /* tmp = tmp - Px */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
350 if ((err = mp_sub(&tmp, &Q->x, &tmpx)) != MP_OKAY) { goto error; } /* tmpx = tmp - Qx */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
351
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
352 /* Yr = -Yp + s(Xp - Xr) */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
353 if ((err = mp_sub(&P->x, &tmpx, &tmp)) != MP_OKAY) { goto error; } /* tmp = Px - tmpx */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
354 if ((err = mp_mul(&tmp, &s, &tmp)) != MP_OKAY) { goto error; } /* tmp = tmp * s */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
355 if ((err = mp_submod(&tmp, &P->y, modulus, &R->y)) != MP_OKAY) { goto error; } /* Ry = tmp - Py mod modulus */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
356 if ((err = mp_mod(&tmpx, modulus, &R->x)) != MP_OKAY) { goto error; } /* Rx = tmpx mod modulus */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
357
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
358 err = CRYPT_OK;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
359 goto done;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
360 error:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
361 err = mpi_to_ltc_error(err);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
362 done:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
363 mp_clear_multi(&s, &tmpx, &tmp, NULL);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
364 return err;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
365 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
366
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
367 /* size of sliding window, don't change this! */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
368 #define WINSIZE 4
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
369
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
370 /* perform R = kG where k == integer and G == ecc_point */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
371 static int ecc_mulmod(mp_int *k, ecc_point *G, ecc_point *R, mp_int *modulus)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
372 {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
373 ecc_point *tG, *M[8];
143
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
374 int i, j, err;
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
375 mp_int mu;
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
376 mp_digit buf;
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
377 int first, bitbuf, bitcpy, bitcnt, mode, digidx;
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
378
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
379 /* init barrett reduction */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
380 if ((err = mp_init(&mu)) != MP_OKAY) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
381 return mpi_to_ltc_error(err);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
382 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
383 if ((err = mp_reduce_setup(&mu, modulus)) != MP_OKAY) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
384 mp_clear(&mu);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
385 return mpi_to_ltc_error(err);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
386 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
387
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
388 /* alloc ram for window temps */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
389 for (i = 0; i < 8; i++) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
390 M[i] = new_point();
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
391 if (M[i] == NULL) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
392 for (j = 0; j < i; j++) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
393 del_point(M[j]);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
394 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
395 mp_clear(&mu);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
396 return CRYPT_MEM;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
397 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
398 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
399
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
400 /* make a copy of G incase R==G */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
401 tG = new_point();
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
402 if (tG == NULL) { err = CRYPT_MEM; goto done; }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
403
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
404 /* tG = G */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
405 if ((err = mp_copy(&G->x, &tG->x)) != MP_OKAY) { goto error; }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
406 if ((err = mp_copy(&G->y, &tG->y)) != MP_OKAY) { goto error; }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
407
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
408 /* calc the M tab, which holds kG for k==8..15 */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
409 /* M[0] == 8G */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
410 if ((err = dbl_point(G, M[0], modulus, &mu)) != CRYPT_OK) { goto done; }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
411 if ((err = dbl_point(M[0], M[0], modulus, &mu)) != CRYPT_OK) { goto done; }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
412 if ((err = dbl_point(M[0], M[0], modulus, &mu)) != CRYPT_OK) { goto done; }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
413
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
414 /* now find (8+k)G for k=1..7 */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
415 for (j = 9; j < 16; j++) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
416 if ((err = add_point(M[j-9], G, M[j-8], modulus, &mu)) != CRYPT_OK) { goto done; }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
417 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
418
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
419 /* setup sliding window */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
420 mode = 0;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
421 bitcnt = 1;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
422 buf = 0;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
423 digidx = k->used - 1;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
424 bitcpy = bitbuf = 0;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
425 first = 1;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
426
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
427 /* perform ops */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
428 for (;;) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
429 /* grab next digit as required */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
430 if (--bitcnt == 0) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
431 if (digidx == -1) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
432 break;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
433 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
434 buf = k->dp[digidx--];
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
435 bitcnt = (int) DIGIT_BIT;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
436 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
437
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
438 /* grab the next msb from the multiplicand */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
439 i = (buf >> (DIGIT_BIT - 1)) & 1;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
440 buf <<= 1;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
441
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
442 /* skip leading zero bits */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
443 if (mode == 0 && i == 0) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
444 continue;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
445 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
446
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
447 /* if the bit is zero and mode == 1 then we double */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
448 if (mode == 1 && i == 0) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
449 if ((err = dbl_point(R, R, modulus, &mu)) != CRYPT_OK) { goto done; }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
450 continue;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
451 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
452
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
453 /* else we add it to the window */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
454 bitbuf |= (i << (WINSIZE - ++bitcpy));
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
455 mode = 2;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
456
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
457 if (bitcpy == WINSIZE) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
458 /* if this is the first window we do a simple copy */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
459 if (first == 1) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
460 /* R = kG [k = first window] */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
461 if ((err = mp_copy(&M[bitbuf-8]->x, &R->x)) != MP_OKAY) { goto error; }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
462 if ((err = mp_copy(&M[bitbuf-8]->y, &R->y)) != MP_OKAY) { goto error; }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
463 first = 0;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
464 } else {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
465 /* normal window */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
466 /* ok window is filled so double as required and add */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
467 /* double first */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
468 for (j = 0; j < WINSIZE; j++) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
469 if ((err = dbl_point(R, R, modulus, &mu)) != CRYPT_OK) { goto done; }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
470 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
471
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
472 /* then add, bitbuf will be 8..15 [8..2^WINSIZE] guaranteed */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
473 if ((err = add_point(R, M[bitbuf-8], R, modulus, &mu)) != CRYPT_OK) { goto done; }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
474 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
475 /* empty window and reset */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
476 bitcpy = bitbuf = 0;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
477 mode = 1;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
478 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
479 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
480
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
481 /* if bits remain then double/add */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
482 if (mode == 2 && bitcpy > 0) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
483 /* double then add */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
484 for (j = 0; j < bitcpy; j++) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
485 /* only double if we have had at least one add first */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
486 if (first == 0) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
487 if ((err = dbl_point(R, R, modulus, &mu)) != CRYPT_OK) { goto done; }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
488 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
489
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
490 bitbuf <<= 1;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
491 if ((bitbuf & (1 << WINSIZE)) != 0) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
492 if (first == 1){
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
493 /* first add, so copy */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
494 if ((err = mp_copy(&tG->x, &R->x)) != MP_OKAY) { goto error; }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
495 if ((err = mp_copy(&tG->y, &R->y)) != MP_OKAY) { goto error; }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
496 first = 0;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
497 } else {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
498 /* then add */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
499 if ((err = add_point(R, tG, R, modulus, &mu)) != CRYPT_OK) { goto done; }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
500 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
501 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
502 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
503 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
504 err = CRYPT_OK;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
505 goto done;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
506 error:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
507 err = mpi_to_ltc_error(err);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
508 done:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
509 del_point(tG);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
510 for (i = 0; i < 8; i++) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
511 del_point(M[i]);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
512 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
513 mp_clear(&mu);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
514 return err;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
515 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
516
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
517 #undef WINSIZE
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
518
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
519 int ecc_test(void)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
520 {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
521 mp_int modulus, order;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
522 ecc_point *G, *GG;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
523 int i, err, primality;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
524
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
525 if ((err = mp_init_multi(&modulus, &order, NULL)) != MP_OKAY) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
526 return mpi_to_ltc_error(err);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
527 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
528
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
529 G = new_point();
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
530 GG = new_point();
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
531 if (G == NULL || GG == NULL) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
532 mp_clear_multi(&modulus, &order, NULL);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
533 del_point(G);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
534 del_point(GG);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
535 return CRYPT_MEM;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
536 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
537
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
538 for (i = 0; sets[i].size; i++) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
539 #if 0
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
540 printf("Testing %d\n", sets[i].size);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
541 #endif
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
542 if ((err = mp_read_radix(&modulus, (char *)sets[i].prime, 64)) != MP_OKAY) { goto error; }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
543 if ((err = mp_read_radix(&order, (char *)sets[i].order, 64)) != MP_OKAY) { goto error; }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
544
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
545 /* is prime actually prime? */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
546 if ((err = is_prime(&modulus, &primality)) != CRYPT_OK) { goto done; }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
547 if (primality == 0) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
548 err = CRYPT_FAIL_TESTVECTOR;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
549 goto done;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
550 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
551
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
552 /* is order prime ? */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
553 if ((err = is_prime(&order, &primality)) != CRYPT_OK) { goto done; }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
554 if (primality == 0) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
555 err = CRYPT_FAIL_TESTVECTOR;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
556 goto done;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
557 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
558
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
559 if ((err = mp_read_radix(&G->x, (char *)sets[i].Gx, 64)) != MP_OKAY) { goto error; }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
560 if ((err = mp_read_radix(&G->y, (char *)sets[i].Gy, 64)) != MP_OKAY) { goto error; }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
561
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
562 /* then we should have G == (order + 1)G */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
563 if ((err = mp_add_d(&order, 1, &order)) != MP_OKAY) { goto error; }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
564 if ((err = ecc_mulmod(&order, G, GG, &modulus)) != CRYPT_OK) { goto done; }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
565 if (mp_cmp(&G->x, &GG->x) != 0 || mp_cmp(&G->y, &GG->y) != 0) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
566 err = CRYPT_FAIL_TESTVECTOR;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
567 goto done;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
568 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
569 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
570 err = CRYPT_OK;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
571 goto done;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
572 error:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
573 err = mpi_to_ltc_error(err);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
574 done:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
575 del_point(GG);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
576 del_point(G);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
577 mp_clear_multi(&order, &modulus, NULL);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
578 return err;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
579 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
580
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
581 void ecc_sizes(int *low, int *high)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
582 {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
583 int i;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
584 _ARGCHK(low != NULL);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
585 _ARGCHK(high != NULL);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
586
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
587 *low = INT_MAX;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
588 *high = 0;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
589 for (i = 0; sets[i].size != 0; i++) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
590 if (sets[i].size < *low) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
591 *low = sets[i].size;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
592 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
593 if (sets[i].size > *high) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
594 *high = sets[i].size;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
595 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
596 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
597 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
598
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
599 int ecc_make_key(prng_state *prng, int wprng, int keysize, ecc_key *key)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
600 {
143
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
601 int x, err;
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
602 ecc_point *base;
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
603 mp_int prime;
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
604 unsigned char *buf;
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
605
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
606 _ARGCHK(key != NULL);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
607
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
608 /* good prng? */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
609 if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
610 return err;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
611 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
612
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
613 /* find key size */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
614 for (x = 0; (keysize > sets[x].size) && (sets[x].size != 0); x++);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
615 keysize = sets[x].size;
143
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
616 _ARGCHK(keysize <= ECC_MAXSIZE);
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
617
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
618 if (sets[x].size == 0) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
619 return CRYPT_INVALID_KEYSIZE;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
620 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
621 key->idx = x;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
622
143
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
623 /* allocate ram */
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
624 base = NULL;
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
625 buf = XMALLOC(ECC_MAXSIZE);
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
626 if (buf == NULL) {
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
627 return CRYPT_MEM;
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
628 }
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
629
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
630 /* make up random string */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
631 if (prng_descriptor[wprng].read(buf, (unsigned long)keysize, prng) != (unsigned long)keysize) {
143
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
632 err = CRYPT_ERROR_READPRNG;
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
633 goto __ERR2;
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
634 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
635
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
636 /* setup the key variables */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
637 if ((err = mp_init_multi(&key->pubkey.x, &key->pubkey.y, &key->k, &prime, NULL)) != MP_OKAY) {
143
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
638 err = mpi_to_ltc_error(err);
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
639 goto __ERR;
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
640 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
641 base = new_point();
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
642 if (base == NULL) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
643 mp_clear_multi(&key->pubkey.x, &key->pubkey.y, &key->k, &prime, NULL);
143
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
644 err = CRYPT_MEM;
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
645 goto __ERR;
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
646 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
647
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
648 /* read in the specs for this key */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
649 if ((err = mp_read_radix(&prime, (char *)sets[key->idx].prime, 64)) != MP_OKAY) { goto error; }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
650 if ((err = mp_read_radix(&base->x, (char *)sets[key->idx].Gx, 64)) != MP_OKAY) { goto error; }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
651 if ((err = mp_read_radix(&base->y, (char *)sets[key->idx].Gy, 64)) != MP_OKAY) { goto error; }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
652 if ((err = mp_read_unsigned_bin(&key->k, (unsigned char *)buf, keysize)) != MP_OKAY) { goto error; }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
653
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
654 /* make the public key */
143
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
655 if ((err = ecc_mulmod(&key->k, base, &key->pubkey, &prime)) != CRYPT_OK) { goto __ERR; }
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
656 key->type = PK_PRIVATE;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
657
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
658 /* shrink key */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
659 if ((err = mp_shrink(&key->k)) != MP_OKAY) { goto error; }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
660 if ((err = mp_shrink(&key->pubkey.x)) != MP_OKAY) { goto error; }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
661 if ((err = mp_shrink(&key->pubkey.y)) != MP_OKAY) { goto error; }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
662
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
663 /* free up ram */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
664 err = CRYPT_OK;
143
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
665 goto __ERR;
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
666 error:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
667 err = mpi_to_ltc_error(err);
143
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
668 __ERR:
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
669 del_point(base);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
670 mp_clear(&prime);
143
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
671 __ERR2:
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
672 #ifdef CLEAN_STACK
143
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
673 zeromem(buf, ECC_MAXSIZE);
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
674 #endif
143
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
675
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
676 XFREE(buf);
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
677
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
678 return err;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
679 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
680
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
681 void ecc_free(ecc_key *key)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
682 {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
683 _ARGCHK(key != NULL);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
684 mp_clear_multi(&key->pubkey.x, &key->pubkey.y, &key->k, NULL);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
685 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
686
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
687 static int compress_y_point(ecc_point *pt, int idx, int *result)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
688 {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
689 mp_int tmp, tmp2, p;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
690 int err;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
691
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
692 _ARGCHK(pt != NULL);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
693 _ARGCHK(result != NULL);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
694
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
695 if ((err = mp_init_multi(&tmp, &tmp2, &p, NULL)) != MP_OKAY) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
696 return mpi_to_ltc_error(err);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
697 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
698
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
699 /* get x^3 - 3x + b */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
700 if ((err = mp_read_radix(&p, (char *)sets[idx].B, 64)) != MP_OKAY) { goto error; } /* p = B */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
701 if ((err = mp_expt_d(&pt->x, 3, &tmp)) != MP_OKAY) { goto error; } /* tmp = pX^3 */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
702 if ((err = mp_mul_d(&pt->x, 3, &tmp2)) != MP_OKAY) { goto error; } /* tmp2 = 3*pX^3 */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
703 if ((err = mp_sub(&tmp, &tmp2, &tmp)) != MP_OKAY) { goto error; } /* tmp = tmp - tmp2 */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
704 if ((err = mp_add(&tmp, &p, &tmp)) != MP_OKAY) { goto error; } /* tmp = tmp + p */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
705 if ((err = mp_read_radix(&p, (char *)sets[idx].prime, 64)) != MP_OKAY) { goto error; } /* p = prime */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
706 if ((err = mp_mod(&tmp, &p, &tmp)) != MP_OKAY) { goto error; } /* tmp = tmp mod p */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
707
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
708 /* now find square root */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
709 if ((err = mp_add_d(&p, 1, &tmp2)) != MP_OKAY) { goto error; } /* tmp2 = p + 1 */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
710 if ((err = mp_div_2d(&tmp2, 2, &tmp2, NULL)) != MP_OKAY) { goto error; } /* tmp2 = (p+1)/4 */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
711 if ((err = mp_exptmod(&tmp, &tmp2, &p, &tmp)) != MP_OKAY) { goto error; } /* tmp = (x^3 - 3x + b)^((p+1)/4) mod p */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
712
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
713 /* if tmp equals the y point give a 0, otherwise 1 */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
714 if (mp_cmp(&tmp, &pt->y) == 0) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
715 *result = 0;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
716 } else {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
717 *result = 1;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
718 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
719
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
720 err = CRYPT_OK;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
721 goto done;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
722 error:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
723 err = mpi_to_ltc_error(err);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
724 done:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
725 mp_clear_multi(&p, &tmp, &tmp2, NULL);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
726 return err;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
727 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
728
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
729 static int expand_y_point(ecc_point *pt, int idx, int result)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
730 {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
731 mp_int tmp, tmp2, p;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
732 int err;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
733
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
734 _ARGCHK(pt != NULL);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
735
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
736 if ((err = mp_init_multi(&tmp, &tmp2, &p, NULL)) != MP_OKAY) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
737 return CRYPT_MEM;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
738 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
739
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
740 /* get x^3 - 3x + b */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
741 if ((err = mp_read_radix(&p, (char *)sets[idx].B, 64)) != MP_OKAY) { goto error; } /* p = B */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
742 if ((err = mp_expt_d(&pt->x, 3, &tmp)) != MP_OKAY) { goto error; } /* tmp = pX^3 */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
743 if ((err = mp_mul_d(&pt->x, 3, &tmp2)) != MP_OKAY) { goto error; } /* tmp2 = 3*pX^3 */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
744 if ((err = mp_sub(&tmp, &tmp2, &tmp)) != MP_OKAY) { goto error; } /* tmp = tmp - tmp2 */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
745 if ((err = mp_add(&tmp, &p, &tmp)) != MP_OKAY) { goto error; } /* tmp = tmp + p */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
746 if ((err = mp_read_radix(&p, (char *)sets[idx].prime, 64)) != MP_OKAY) { goto error; } /* p = prime */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
747 if ((err = mp_mod(&tmp, &p, &tmp)) != MP_OKAY) { goto error; } /* tmp = tmp mod p */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
748
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
749 /* now find square root */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
750 if ((err = mp_add_d(&p, 1, &tmp2)) != MP_OKAY) { goto error; } /* tmp2 = p + 1 */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
751 if ((err = mp_div_2d(&tmp2, 2, &tmp2, NULL)) != MP_OKAY) { goto error; } /* tmp2 = (p+1)/4 */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
752 if ((err = mp_exptmod(&tmp, &tmp2, &p, &tmp)) != MP_OKAY) { goto error; } /* tmp = (x^3 - 3x + b)^((p+1)/4) mod p */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
753
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
754 /* if result==0, then y==tmp, otherwise y==p-tmp */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
755 if (result == 0) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
756 if ((err = mp_copy(&tmp, &pt->y) != MP_OKAY)) { goto error; }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
757 } else {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
758 if ((err = mp_sub(&p, &tmp, &pt->y) != MP_OKAY)) { goto error; }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
759 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
760
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
761 err = CRYPT_OK;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
762 goto done;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
763 error:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
764 err = mpi_to_ltc_error(err);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
765 done:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
766 mp_clear_multi(&p, &tmp, &tmp2, NULL);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
767 return err;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
768 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
769
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
770 int ecc_export(unsigned char *out, unsigned long *outlen, int type, ecc_key *key)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
771 {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
772 unsigned long y, z;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
773 int cp, err;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
774
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
775 _ARGCHK(out != NULL);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
776 _ARGCHK(outlen != NULL);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
777 _ARGCHK(key != NULL);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
778
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
779 /* can we store the static header? */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
780 if (*outlen < (PACKET_SIZE + 3)) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
781 return CRYPT_BUFFER_OVERFLOW;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
782 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
783
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
784 /* type valid? */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
785 if (key->type != PK_PRIVATE && type == PK_PRIVATE) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
786 return CRYPT_PK_TYPE_MISMATCH;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
787 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
788
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
789 /* output type and magic byte */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
790 y = PACKET_SIZE;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
791 out[y++] = (unsigned char)type;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
792 out[y++] = (unsigned char)sets[key->idx].size;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
793
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
794 /* output x coordinate */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
795 OUTPUT_BIGNUM(&(key->pubkey.x), out, y, z);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
796
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
797 /* compress y and output it */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
798 if ((err = compress_y_point(&key->pubkey, key->idx, &cp)) != CRYPT_OK) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
799 return err;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
800 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
801 out[y++] = (unsigned char)cp;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
802
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
803 if (type == PK_PRIVATE) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
804 OUTPUT_BIGNUM(&key->k, out, y, z);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
805 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
806
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
807 /* store header */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
808 packet_store_header(out, PACKET_SECT_ECC, PACKET_SUB_KEY);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
809 *outlen = y;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
810
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
811 return CRYPT_OK;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
812 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
813
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
814 int ecc_import(const unsigned char *in, unsigned long inlen, ecc_key *key)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
815 {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
816 unsigned long x, y, s;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
817 int err;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
818
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
819 _ARGCHK(in != NULL);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
820 _ARGCHK(key != NULL);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
821
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
822 /* check length */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
823 if ((3+PACKET_SIZE) > inlen) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
824 return CRYPT_INVALID_PACKET;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
825 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
826
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
827 /* check type */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
828 if ((err = packet_valid_header((unsigned char *)in, PACKET_SECT_ECC, PACKET_SUB_KEY)) != CRYPT_OK) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
829 return err;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
830 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
831
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
832 /* init key */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
833 if (mp_init_multi(&key->pubkey.x, &key->pubkey.y, &key->k, NULL) != MP_OKAY) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
834 return CRYPT_MEM;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
835 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
836
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
837 y = PACKET_SIZE;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
838 key->type = (int)in[y++];
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
839 s = (unsigned long)in[y++];
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
840
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
841 for (x = 0; (s > (unsigned long)sets[x].size) && (sets[x].size != 0); x++);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
842 if (sets[x].size == 0) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
843 err = CRYPT_INVALID_KEYSIZE;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
844 goto error;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
845 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
846 key->idx = (int)x;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
847
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
848 /* type check both values */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
849 if ((key->type != PK_PUBLIC) && (key->type != PK_PRIVATE)) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
850 err = CRYPT_INVALID_PACKET;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
851 goto error;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
852 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
853
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
854 /* is the key idx valid? */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
855 if (is_valid_idx(key->idx) != 1) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
856 err = CRYPT_INVALID_PACKET;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
857 goto error;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
858 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
859
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
860 /* load x coordinate */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
861 INPUT_BIGNUM(&key->pubkey.x, in, x, y, inlen);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
862
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
863 /* load y */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
864 x = (unsigned long)in[y++];
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
865 if ((err = expand_y_point(&key->pubkey, key->idx, (int)x)) != CRYPT_OK) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
866 goto error;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
867 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
868
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
869 if (key->type == PK_PRIVATE) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
870 /* load private key */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
871 INPUT_BIGNUM(&key->k, in, x, y, inlen);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
872 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
873
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
874 /* eliminate private key if public */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
875 if (key->type == PK_PUBLIC) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
876 mp_clear(&key->k);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
877 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
878
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
879 return CRYPT_OK;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
880 error:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
881 mp_clear_multi(&key->pubkey.x, &key->pubkey.y, &key->k, NULL);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
882 return err;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
883 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
884
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
885 int ecc_shared_secret(ecc_key *private_key, ecc_key *public_key,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
886 unsigned char *out, unsigned long *outlen)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
887 {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
888 unsigned long x, y;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
889 ecc_point *result;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
890 mp_int prime;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
891 int err;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
892
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
893 _ARGCHK(private_key != NULL);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
894 _ARGCHK(public_key != NULL);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
895 _ARGCHK(out != NULL);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
896 _ARGCHK(outlen != NULL);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
897
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
898 /* type valid? */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
899 if (private_key->type != PK_PRIVATE) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
900 return CRYPT_PK_NOT_PRIVATE;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
901 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
902
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
903 if (private_key->idx != public_key->idx) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
904 return CRYPT_PK_TYPE_MISMATCH;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
905 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
906
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
907 /* make new point */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
908 result = new_point();
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
909 if (result == NULL) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
910 return CRYPT_MEM;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
911 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
912
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
913 if ((err = mp_init(&prime)) != MP_OKAY) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
914 del_point(result);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
915 return mpi_to_ltc_error(err);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
916 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
917
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
918 if ((err = mp_read_radix(&prime, (char *)sets[private_key->idx].prime, 64)) != MP_OKAY) { goto error; }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
919 if ((err = ecc_mulmod(&private_key->k, &public_key->pubkey, result, &prime)) != CRYPT_OK) { goto done1; }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
920
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
921 x = (unsigned long)mp_unsigned_bin_size(&result->x);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
922 y = (unsigned long)mp_unsigned_bin_size(&result->y);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
923
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
924 if (*outlen < (x+y)) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
925 err = CRYPT_BUFFER_OVERFLOW;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
926 goto done1;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
927 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
928 *outlen = x+y;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
929 if ((err = mp_to_unsigned_bin(&result->x, out)) != MP_OKAY) { goto error; }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
930 if ((err = mp_to_unsigned_bin(&result->y, out+x)) != MP_OKAY) { goto error; }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
931
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
932 err = CRYPT_OK;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
933 goto done1;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
934 error:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
935 err = mpi_to_ltc_error(err);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
936 done1:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
937 mp_clear(&prime);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
938 del_point(result);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
939 return err;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
940 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
941
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
942 int ecc_get_size(ecc_key *key)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
943 {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
944 _ARGCHK(key != NULL);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
945 if (is_valid_idx(key->idx))
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
946 return sets[key->idx].size;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
947 else
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
948 return INT_MAX; /* large value known to cause it to fail when passed to ecc_make_key() */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
949 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
950
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
951 #include "ecc_sys.c"
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
952
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
953 #endif
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
954
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
955