Apply %restore_fcommon macro for Address Sanitizer
[platform/upstream/nettle.git] / testsuite / ed25519-test.c
1 /* ed25519-test.c
2
3    Copyright (C) 2014 Niels Möller
4
5    This file is part of GNU Nettle.
6
7    GNU Nettle is free software: you can redistribute it and/or
8    modify it under the terms of either:
9
10      * the GNU Lesser General Public License as published by the Free
11        Software Foundation; either version 3 of the License, or (at your
12        option) any later version.
13
14    or
15
16      * the GNU General Public License as published by the Free
17        Software Foundation; either version 2 of the License, or (at your
18        option) any later version.
19
20    or both in parallel, as here.
21
22    GNU Nettle is distributed in the hope that it will be useful,
23    but WITHOUT ANY WARRANTY; without even the implied warranty of
24    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
25    General Public License for more details.
26
27    You should have received copies of the GNU General Public License and
28    the GNU Lesser General Public License along with this program.  If
29    not, see http://www.gnu.org/licenses/.
30 */
31
32 #include "testutils.h"
33
34 #include <errno.h>
35
36 #include "eddsa.h"
37
38 #include "base16.h"
39
40 static void
41 decode_hex (size_t length, uint8_t *dst, const char *src)
42 {
43   struct base16_decode_ctx ctx;
44   size_t out_size;
45   base16_decode_init (&ctx);
46   ASSERT (base16_decode_update (&ctx, &out_size, dst, 2*length, src));
47   ASSERT (out_size == length);
48   ASSERT (base16_decode_final (&ctx));
49 }
50
51 /* Processes a single line in the format of
52    http://ed25519.cr.yp.to/python/sign.input:
53
54      sk pk : pk : m : s m :
55
56    where sk (secret key) and pk (public key) are 32 bytes each, m is
57    variable size, and s is 64 bytes. All values hex encoded.
58 */
59 static void
60 test_one (const char *line)
61 {
62   const char *p;
63   const char *mp;
64   uint8_t sk[ED25519_KEY_SIZE];
65   uint8_t pk[ED25519_KEY_SIZE];
66   uint8_t t[ED25519_KEY_SIZE];
67   uint8_t s[ED25519_SIGNATURE_SIZE];
68   uint8_t *msg;
69   size_t msg_size;
70   uint8_t s2[ED25519_SIGNATURE_SIZE];
71
72   decode_hex (ED25519_KEY_SIZE, sk, line);
73
74   p = strchr (line, ':');
75   ASSERT (p == line + 128);
76   p++;
77   decode_hex (ED25519_KEY_SIZE, pk, p);
78   p = strchr (p, ':');
79   ASSERT (p == line + 193);
80   mp = ++p;
81   p = strchr (p, ':');
82   ASSERT (p);
83   ASSERT ((p - mp) % 2 == 0);
84   msg_size = (p - mp) / 2;
85
86   decode_hex (ED25519_SIGNATURE_SIZE, s, p+1);
87
88   msg = xalloc (msg_size + 1);
89   msg[msg_size] = 'x';
90
91   decode_hex (msg_size, msg, mp);
92
93   ed25519_sha512_public_key (t, sk);
94   ASSERT (MEMEQ(ED25519_KEY_SIZE, t, pk));
95
96   ed25519_sha512_sign (pk, sk, msg_size, msg, s2);
97   ASSERT (MEMEQ (ED25519_SIGNATURE_SIZE, s, s2));
98
99   ASSERT (ed25519_sha512_verify (pk, msg_size, msg, s));
100
101   s2[ED25519_SIGNATURE_SIZE/3] ^= 0x40;
102   ASSERT (!ed25519_sha512_verify (pk, msg_size, msg, s2));
103
104   memcpy (s2, s, ED25519_SIGNATURE_SIZE);
105   s2[2*ED25519_SIGNATURE_SIZE/3] ^= 0x40;
106   ASSERT (!ed25519_sha512_verify (pk, msg_size, msg, s2));
107
108   ASSERT (!ed25519_sha512_verify (pk, msg_size + 1, msg, s));
109
110   if (msg_size > 0)
111     {
112       msg[msg_size-1] ^= 0x20;
113       ASSERT (!ed25519_sha512_verify (pk, msg_size, msg, s));
114     }
115   free (msg);
116 }
117
118 #ifndef HAVE_GETLINE
119 static ssize_t
120 getline(char **lineptr, size_t *n, FILE *f)
121 {
122   size_t i;
123   int c;
124   if (!*lineptr)
125     {
126       *n = 500;
127       *lineptr = xalloc (*n);
128     }
129
130   i = 0;
131   do
132     {
133       c = getc(f);
134       if (c < 0)
135         {
136           if (i > 0)
137             break;
138           return -1;
139         }
140
141       (*lineptr) [i++] = c;
142       if (i == *n)
143         {
144           *n *= 2;
145           *lineptr = realloc (*lineptr, *n);
146           if (!*lineptr)
147             die ("Virtual memory exhausted.\n");
148         }
149     } while (c != '\n');
150
151   (*lineptr) [i] = 0;
152   return i;
153 }
154 #endif
155
156 void
157 test_main(void)
158 {
159   const char *input = getenv ("ED25519_SIGN_INPUT");
160   if (input)
161     {
162       size_t buf_size;
163       char *buf;
164       FILE *f = fopen (input, "r");
165       if (!f)
166         die ("Opening input file '%s' failed: %s\n",
167              input, strerror (errno));
168
169       for (buf = NULL; getline (&buf, &buf_size, f) >= 0; )
170         test_one (buf);
171
172       free (buf);
173       fclose (f);
174     }
175   else
176     {
177       /* First few lines only */
178       test_one ("9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a:d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a::e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b:");
179       test_one ("4ccd089b28ff96da9db6c346ec114e0f5b8a319f35aba624da8cf6ed4fb8a6fb3d4017c3e843895a92b70aa74d1b7ebc9c982ccf2ec4968cc0cd55f12af4660c:3d4017c3e843895a92b70aa74d1b7ebc9c982ccf2ec4968cc0cd55f12af4660c:72:92a009a9f0d4cab8720e820b5f642540a2b27b5416503f8fb3762223ebdb69da085ac1e43e15996e458f3613d0f11d8c387b2eaeb4302aeeb00d291612bb0c0072:");
180       test_one ("c5aa8df43f9f837bedb7442f31dcb7b166d38535076f094b85ce3a2e0b4458f7fc51cd8e6218a1a38da47ed00230f0580816ed13ba3303ac5deb911548908025:fc51cd8e6218a1a38da47ed00230f0580816ed13ba3303ac5deb911548908025:af82:6291d657deec24024827e69c3abe01a30ce548a284743a445e3680d7db5ac3ac18ff9b538d16f290ae67f760984dc6594a7c15e9716ed28dc027beceea1ec40aaf82:");
181       test_one ("0d4a05b07352a5436e180356da0ae6efa0345ff7fb1572575772e8005ed978e9e61a185bcef2613a6c7cb79763ce945d3b245d76114dd440bcf5f2dc1aa57057:e61a185bcef2613a6c7cb79763ce945d3b245d76114dd440bcf5f2dc1aa57057:cbc77b:d9868d52c2bebce5f3fa5a79891970f309cb6591e3e1702a70276fa97c24b3a8e58606c38c9758529da50ee31b8219cba45271c689afa60b0ea26c99db19b00ccbc77b:");
182     }
183 }