| 
									
										
										
										
											2015-05-24 06:55:12 +02:00
										 |  |  | // Copyright 2010 Dolphin Emulator Project
 | 
					
						
							| 
									
										
										
										
											2015-05-18 01:08:10 +02:00
										 |  |  | // Licensed under GPLv2+
 | 
					
						
							| 
									
										
										
										
											2013-08-28 01:07:43 +12:00
										 |  |  | // Refer to the license.txt file included.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | // Copyright 2007,2008  Segher Boessenkool  <segher@kernel.crashing.org>
 | 
					
						
							|  |  |  | // Licensed under the terms of the GNU GPL, version 2
 | 
					
						
							|  |  |  | // http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-17 05:18:15 -05:00
										 |  |  | #include <cstdio>
 | 
					
						
							|  |  |  | #include <cstdlib>
 | 
					
						
							|  |  |  | #include <ctime>
 | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | #include <string.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-18 23:17:41 -05:00
										 |  |  | #include "Common/Common.h"
 | 
					
						
							| 
									
										
										
										
											2014-02-28 12:41:10 +01:00
										 |  |  | #include "Common/Crypto/bn.h"
 | 
					
						
							|  |  |  | #include "Common/Crypto/ec.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 04:09:26 -07:00
										 |  |  | #ifdef _MSC_VER
 | 
					
						
							|  |  |  | #pragma warning(push)
 | 
					
						
							|  |  |  | #pragma warning(disable : 4505)
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | // y**2 + x*y = x**3 + x + b
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  | UNUSED static const u8 ec_b[30] = {0x00, 0x66, 0x64, 0x7e, 0xde, 0x6c, 0x33, 0x2c, 0x7f, 0x8c, | 
					
						
							|  |  |  |                                    0x09, 0x23, 0xbb, 0x58, 0x21, 0x3b, 0x33, 0x3b, 0x20, 0xe9, | 
					
						
							|  |  |  |                                    0xce, 0x42, 0x81, 0xfe, 0x11, 0x5f, 0x7d, 0x8f, 0x90, 0xad}; | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | // order of the addition group of points
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  | static const u8 ec_N[30] = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 
					
						
							|  |  |  |                             0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xe9, 0x74, 0xe7, 0x2f, | 
					
						
							|  |  |  |                             0x8a, 0x69, 0x22, 0x03, 0x1d, 0x26, 0x03, 0xcf, 0xe0, 0xd7}; | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | // base point
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  | static const u8 ec_G[60] = {0x00, 0xfa, 0xc9, 0xdf, 0xcb, 0xac, 0x83, 0x13, 0xbb, 0x21, 0x39, 0xf1, | 
					
						
							|  |  |  |                             0xbb, 0x75, 0x5f, 0xef, 0x65, 0xbc, 0x39, 0x1f, 0x8b, 0x36, 0xf8, 0xf8, | 
					
						
							|  |  |  |                             0xeb, 0x73, 0x71, 0xfd, 0x55, 0x8b, 0x01, 0x00, 0x6a, 0x08, 0xa4, 0x19, | 
					
						
							|  |  |  |                             0x03, 0x35, 0x06, 0x78, 0xe5, 0x85, 0x28, 0xbe, 0xbf, 0x8a, 0x0b, 0xef, | 
					
						
							|  |  |  |                             0xf8, 0x67, 0xa7, 0xca, 0x36, 0x71, 0x6f, 0x7e, 0x01, 0xf8, 0x10, 0x52}; | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-21 21:16:51 +01:00
										 |  |  | static void elt_copy(u8* d, const u8* a) | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   memcpy(d, a, 30); | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-21 21:16:51 +01:00
										 |  |  | static void elt_zero(u8* d) | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   memset(d, 0, 30); | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-21 21:16:51 +01:00
										 |  |  | static int elt_is_zero(const u8* d) | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   u32 i; | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   for (i = 0; i < 30; i++) | 
					
						
							|  |  |  |     if (d[i] != 0) | 
					
						
							|  |  |  |       return 0; | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   return 1; | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-21 21:16:51 +01:00
										 |  |  | static void elt_add(u8* d, const u8* a, const u8* b) | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   u32 i; | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   for (i = 0; i < 30; i++) | 
					
						
							|  |  |  |     d[i] = a[i] ^ b[i]; | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-21 21:16:51 +01:00
										 |  |  | static void elt_mul_x(u8* d, const u8* a) | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   u8 carry, x, y; | 
					
						
							|  |  |  |   u32 i; | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   carry = a[0] & 1; | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   x = 0; | 
					
						
							|  |  |  |   for (i = 0; i < 29; i++) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     y = a[i + 1]; | 
					
						
							|  |  |  |     d[i] = x ^ (y >> 7); | 
					
						
							|  |  |  |     x = y << 1; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   d[29] = x ^ carry; | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   d[20] ^= carry << 2; | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-21 21:16:51 +01:00
										 |  |  | static void elt_mul(u8* d, const u8* a, const u8* b) | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   u32 i, n; | 
					
						
							|  |  |  |   u8 mask; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   elt_zero(d); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   i = 0; | 
					
						
							|  |  |  |   mask = 1; | 
					
						
							|  |  |  |   for (n = 0; n < 233; n++) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     elt_mul_x(d, d); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if ((a[i] & mask) != 0) | 
					
						
							|  |  |  |       elt_add(d, d, b); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     mask >>= 1; | 
					
						
							|  |  |  |     if (mask == 0) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       mask = 0x80; | 
					
						
							|  |  |  |       i++; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  | static const u8 square[16] = {0x00, 0x01, 0x04, 0x05, 0x10, 0x11, 0x14, 0x15, | 
					
						
							|  |  |  |                               0x40, 0x41, 0x44, 0x45, 0x50, 0x51, 0x54, 0x55}; | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-21 21:16:51 +01:00
										 |  |  | static void elt_square_to_wide(u8* d, const u8* a) | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   u32 i; | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   for (i = 0; i < 30; i++) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     d[2 * i] = square[a[i] >> 4]; | 
					
						
							|  |  |  |     d[2 * i + 1] = square[a[i] & 15]; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-21 21:16:51 +01:00
										 |  |  | static void wide_reduce(u8* d) | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   u32 i; | 
					
						
							|  |  |  |   u8 x; | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   for (i = 0; i < 30; i++) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     x = d[i]; | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     d[i + 19] ^= x >> 7; | 
					
						
							|  |  |  |     d[i + 20] ^= x << 1; | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     d[i + 29] ^= x >> 1; | 
					
						
							|  |  |  |     d[i + 30] ^= x << 7; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   x = d[30] & ~1; | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   d[49] ^= x >> 7; | 
					
						
							|  |  |  |   d[50] ^= x << 1; | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   d[59] ^= x >> 1; | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   d[30] &= 1; | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-21 21:16:51 +01:00
										 |  |  | static void elt_square(u8* d, const u8* a) | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   u8 wide[60]; | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   elt_square_to_wide(wide, a); | 
					
						
							|  |  |  |   wide_reduce(wide); | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   elt_copy(d, wide + 30); | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-21 21:16:51 +01:00
										 |  |  | static void itoh_tsujii(u8* d, const u8* a, const u8* b, u32 j) | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   u8 t[30]; | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   elt_copy(t, a); | 
					
						
							|  |  |  |   while (j--) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     elt_square(d, t); | 
					
						
							|  |  |  |     elt_copy(t, d); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   elt_mul(d, t, b); | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-21 21:16:51 +01:00
										 |  |  | static void elt_inv(u8* d, const u8* a) | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   u8 t[30]; | 
					
						
							|  |  |  |   u8 s[30]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   itoh_tsujii(t, a, a, 1); | 
					
						
							|  |  |  |   itoh_tsujii(s, t, a, 1); | 
					
						
							|  |  |  |   itoh_tsujii(t, s, s, 3); | 
					
						
							|  |  |  |   itoh_tsujii(s, t, a, 1); | 
					
						
							|  |  |  |   itoh_tsujii(t, s, s, 7); | 
					
						
							|  |  |  |   itoh_tsujii(s, t, t, 14); | 
					
						
							|  |  |  |   itoh_tsujii(t, s, a, 1); | 
					
						
							|  |  |  |   itoh_tsujii(s, t, t, 29); | 
					
						
							|  |  |  |   itoh_tsujii(t, s, s, 58); | 
					
						
							|  |  |  |   itoh_tsujii(s, t, t, 116); | 
					
						
							|  |  |  |   elt_square(d, s); | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-21 21:16:51 +01:00
										 |  |  | UNUSED static int point_is_on_curve(u8* p) | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   u8 s[30], t[30]; | 
					
						
							|  |  |  |   u8 *x, *y; | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   x = p; | 
					
						
							|  |  |  |   y = p + 30; | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   elt_square(t, x); | 
					
						
							|  |  |  |   elt_mul(s, t, x); | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   elt_add(s, s, t); | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   elt_square(t, y); | 
					
						
							|  |  |  |   elt_add(s, s, t); | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   elt_mul(t, x, y); | 
					
						
							|  |  |  |   elt_add(s, s, t); | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   elt_add(s, s, ec_b); | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   return elt_is_zero(s); | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-02-28 12:41:10 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-21 21:16:51 +01:00
										 |  |  | static int point_is_zero(const u8* p) | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   return elt_is_zero(p) && elt_is_zero(p + 30); | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-21 21:16:51 +01:00
										 |  |  | static void point_double(u8* r, const u8* p) | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   u8 s[30], t[30]; | 
					
						
							|  |  |  |   const u8 *px, *py; | 
					
						
							|  |  |  |   u8 *rx, *ry; | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   px = p; | 
					
						
							|  |  |  |   py = p + 30; | 
					
						
							|  |  |  |   rx = r; | 
					
						
							|  |  |  |   ry = r + 30; | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   if (elt_is_zero(px)) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     elt_zero(rx); | 
					
						
							|  |  |  |     elt_zero(ry); | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   elt_inv(t, px); | 
					
						
							|  |  |  |   elt_mul(s, py, t); | 
					
						
							|  |  |  |   elt_add(s, s, px); | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   elt_square(t, px); | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   elt_square(rx, s); | 
					
						
							|  |  |  |   elt_add(rx, rx, s); | 
					
						
							|  |  |  |   rx[29] ^= 1; | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   elt_mul(ry, s, rx); | 
					
						
							|  |  |  |   elt_add(ry, ry, rx); | 
					
						
							|  |  |  |   elt_add(ry, ry, t); | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-21 21:16:51 +01:00
										 |  |  | static void point_add(u8* r, const u8* p, const u8* q) | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   u8 s[30], t[30], u[30]; | 
					
						
							|  |  |  |   const u8 *px, *py, *qx, *qy; | 
					
						
							|  |  |  |   u8 *rx, *ry; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   px = p; | 
					
						
							|  |  |  |   py = p + 30; | 
					
						
							|  |  |  |   qx = q; | 
					
						
							|  |  |  |   qy = q + 30; | 
					
						
							|  |  |  |   rx = r; | 
					
						
							|  |  |  |   ry = r + 30; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (point_is_zero(p)) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     elt_copy(rx, qx); | 
					
						
							|  |  |  |     elt_copy(ry, qy); | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (point_is_zero(q)) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     elt_copy(rx, px); | 
					
						
							|  |  |  |     elt_copy(ry, py); | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   elt_add(u, px, qx); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (elt_is_zero(u)) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     elt_add(u, py, qy); | 
					
						
							|  |  |  |     if (elt_is_zero(u)) | 
					
						
							|  |  |  |       point_double(r, p); | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       elt_zero(rx); | 
					
						
							|  |  |  |       elt_zero(ry); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   elt_inv(t, u); | 
					
						
							|  |  |  |   elt_add(u, py, qy); | 
					
						
							|  |  |  |   elt_mul(s, t, u); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   elt_square(t, s); | 
					
						
							|  |  |  |   elt_add(t, t, s); | 
					
						
							|  |  |  |   elt_add(t, t, qx); | 
					
						
							|  |  |  |   t[29] ^= 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   elt_mul(u, s, t); | 
					
						
							|  |  |  |   elt_add(s, u, py); | 
					
						
							|  |  |  |   elt_add(rx, t, px); | 
					
						
							|  |  |  |   elt_add(ry, s, rx); | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-08 12:40:50 +01:00
										 |  |  | void point_mul(u8* d, const u8* a, const u8* b)  // a is bignum
 | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   u32 i; | 
					
						
							|  |  |  |   u8 mask; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   elt_zero(d); | 
					
						
							|  |  |  |   elt_zero(d + 30); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   for (i = 0; i < 30; i++) | 
					
						
							|  |  |  |     for (mask = 0x80; mask != 0; mask >>= 1) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       point_double(d, d); | 
					
						
							|  |  |  |       if ((a[i] & mask) != 0) | 
					
						
							|  |  |  |         point_add(d, d, b); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  | static void silly_random(u8* rndArea, u8 count) | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   u16 i; | 
					
						
							|  |  |  |   srand((unsigned)(time(nullptr))); | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   for (i = 0; i < count; i++) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     rndArea[i] = rand(); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-21 21:16:51 +01:00
										 |  |  | void generate_ecdsa(u8* R, u8* S, const u8* k, const u8* hash) | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   u8 e[30]; | 
					
						
							|  |  |  |   u8 kk[30]; | 
					
						
							|  |  |  |   u8 m[30]; | 
					
						
							|  |  |  |   u8 minv[30]; | 
					
						
							|  |  |  |   u8 mG[60]; | 
					
						
							|  |  |  |   // FILE *fp;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   elt_zero(e); | 
					
						
							|  |  |  |   memcpy(e + 10, hash, 20); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Changing random number generator to a lame one...
 | 
					
						
							|  |  |  |   silly_random(m, sizeof(m)); | 
					
						
							|  |  |  |   // fp = fopen("/dev/random", "rb");
 | 
					
						
							|  |  |  |   // if (fread(m, sizeof m, 1, fp) != 1)
 | 
					
						
							|  |  |  |   //	fatal("reading random");
 | 
					
						
							|  |  |  |   // fclose(fp);
 | 
					
						
							|  |  |  |   m[0] = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   //	R = (mG).x
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   point_mul(mG, m, ec_G); | 
					
						
							|  |  |  |   elt_copy(R, mG); | 
					
						
							|  |  |  |   if (bn_compare(R, ec_N, 30) >= 0) | 
					
						
							|  |  |  |     bn_sub_modulus(R, ec_N, 30); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   //	S = m**-1*(e + Rk) (mod N)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   elt_copy(kk, k); | 
					
						
							|  |  |  |   if (bn_compare(kk, ec_N, 30) >= 0) | 
					
						
							|  |  |  |     bn_sub_modulus(kk, ec_N, 30); | 
					
						
							|  |  |  |   bn_mul(S, R, kk, ec_N, 30); | 
					
						
							|  |  |  |   bn_add(kk, S, e, ec_N, 30); | 
					
						
							|  |  |  |   bn_inv(minv, m, ec_N, 30); | 
					
						
							|  |  |  |   bn_mul(S, minv, kk, ec_N, 30); | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-21 21:16:51 +01:00
										 |  |  | UNUSED static int check_ecdsa(u8* Q, u8* R, u8* S, const u8* hash) | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   u8 Sinv[30]; | 
					
						
							|  |  |  |   u8 e[30]; | 
					
						
							|  |  |  |   u8 w1[30], w2[30]; | 
					
						
							|  |  |  |   u8 r1[60], r2[60]; | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   bn_inv(Sinv, S, ec_N, 30); | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   elt_zero(e); | 
					
						
							|  |  |  |   memcpy(e + 10, hash, 20); | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   bn_mul(w1, e, Sinv, ec_N, 30); | 
					
						
							|  |  |  |   bn_mul(w2, R, Sinv, ec_N, 30); | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   point_mul(r1, w1, ec_G); | 
					
						
							|  |  |  |   point_mul(r2, w2, Q); | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   point_add(r1, r1, r2); | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   if (bn_compare(r1, ec_N, 30) >= 0) | 
					
						
							|  |  |  |     bn_sub_modulus(r1, ec_N, 30); | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   return (bn_compare(r1, R, 30) == 0); | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-21 21:16:51 +01:00
										 |  |  | void ec_priv_to_pub(const u8* k, u8* Q) | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   point_mul(Q, k, ec_G); | 
					
						
							| 
									
										
										
										
											2010-02-19 17:05:26 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2017-06-07 04:09:26 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | #ifdef _MSC_VER
 | 
					
						
							|  |  |  | #pragma warning(pop)
 | 
					
						
							|  |  |  | #endif
 |