1 /* Copyright 2014, Kenneth MacKay. Licensed under the BSD 2-clause license. */ 2 3 #include "uECC.h" 4 5 #include <stdio.h> 6 #include <string.h> 7 8 #if LPC11XX 9 10 #include "/Projects/lpc11xx/peripherals/uart.h" 11 #include "/Projects/lpc11xx/peripherals/time.h" 12 13 static uint64_t g_rand = 88172645463325252ull; 14 int fake_rng(uint8_t *dest, unsigned size) { 15 while (size) { 16 g_rand ^= (g_rand << 13); 17 g_rand ^= (g_rand >> 7); 18 g_rand ^= (g_rand << 17); 19 20 unsigned amount = (size > 8 ? 8 : size); 21 memcpy(dest, &g_rand, amount); 22 dest += amount; 23 size -= amount; 24 } 25 return 1; 26 } 27 28 #endif 29 30 #define SHA256_BLOCK_LENGTH 64 31 #define SHA256_DIGEST_LENGTH 32 32 33 typedef struct SHA256_CTX { 34 uint32_t state[8]; 35 uint64_t bitcount; 36 uint8_t buffer[SHA256_BLOCK_LENGTH]; 37 } SHA256_CTX; 38 39 extern void SHA256_Init(SHA256_CTX *ctx); 40 extern void SHA256_Update(SHA256_CTX *ctx, const uint8_t *message, size_t message_size); 41 extern void SHA256_Final(uint8_t digest[SHA256_DIGEST_LENGTH], SHA256_CTX *ctx); 42 43 typedef struct SHA256_HashContext { 44 uECC_HashContext uECC; 45 SHA256_CTX ctx; 46 } SHA256_HashContext; 47 48 static void init_SHA256(uECC_HashContext *base) { 49 SHA256_HashContext *context = (SHA256_HashContext *)base; 50 SHA256_Init(&context->ctx); 51 } 52 53 static void update_SHA256(uECC_HashContext *base, 54 const uint8_t *message, 55 unsigned message_size) { 56 SHA256_HashContext *context = (SHA256_HashContext *)base; 57 SHA256_Update(&context->ctx, message, message_size); 58 } 59 60 static void finish_SHA256(uECC_HashContext *base, uint8_t *hash_result) { 61 SHA256_HashContext *context = (SHA256_HashContext *)base; 62 SHA256_Final(hash_result, &context->ctx); 63 } 64 65 int main() { 66 #if LPC11XX 67 uartInit(BAUD_115200); 68 initTime(); 69 70 uECC_set_rng(&fake_rng); 71 #endif 72 73 uint8_t public[uECC_BYTES * 2]; 74 uint8_t private[uECC_BYTES]; 75 uint8_t hash[uECC_BYTES]; 76 uint8_t sig[uECC_BYTES * 2]; 77 uint8_t tmp[2 * SHA256_DIGEST_LENGTH + SHA256_BLOCK_LENGTH]; 78 SHA256_HashContext ctx = {{ 79 &init_SHA256, 80 &update_SHA256, 81 &finish_SHA256, 82 SHA256_BLOCK_LENGTH, 83 SHA256_DIGEST_LENGTH, 84 tmp 85 }}; 86 87 int i; 88 printf("Testing 256 signatures\n"); 89 for (i = 0; i < 256; ++i) { 90 printf("."); 91 #if !LPC11XX 92 fflush(stdout); 93 #endif 94 95 if (!uECC_make_key(public, private)) { 96 printf("uECC_make_key() failed\n"); 97 continue; 98 } 99 memcpy(hash, public, uECC_BYTES); 100 101 if (!uECC_sign_deterministic(private, hash, &ctx.uECC, sig)) { 102 printf("uECC_sign() failed\n"); 103 continue; 104 } 105 106 if (!uECC_verify(public, hash, sig)) { 107 printf("uECC_verify() failed\n"); 108 } 109 } 110 printf("\n"); 111 112 return 0; 113 } 114