Simple example of secp256k1 library

Committer:
diybitcoinhardware
Date:
Mon Sep 16 12:17:13 2019 +0000
Revision:
2:6b892a0b43e5
Parent:
0:23d71aa111c7
increase stack size for RTOS

Who changed what in which revision?

UserRevisionLine numberNew contents of line
diybitcoinhardware 0:23d71aa111c7 1 #include "mbed.h"
diybitcoinhardware 0:23d71aa111c7 2
diybitcoinhardware 0:23d71aa111c7 3 #include "secp256k1.h"
diybitcoinhardware 0:23d71aa111c7 4 #include "secp256k1_preallocated.h"
diybitcoinhardware 0:23d71aa111c7 5
diybitcoinhardware 0:23d71aa111c7 6 RawSerial pc(SERIAL_TX, SERIAL_RX, 115200);
diybitcoinhardware 0:23d71aa111c7 7
diybitcoinhardware 0:23d71aa111c7 8 // small helper functions that prints
diybitcoinhardware 0:23d71aa111c7 9 // data in hex to the serial port
diybitcoinhardware 0:23d71aa111c7 10 void print_hex(const uint8_t * data, size_t data_len){
diybitcoinhardware 0:23d71aa111c7 11 for(int i=0; i<data_len; i++){
diybitcoinhardware 0:23d71aa111c7 12 printf("%02x", data[i]);
diybitcoinhardware 0:23d71aa111c7 13 }
diybitcoinhardware 0:23d71aa111c7 14 }
diybitcoinhardware 0:23d71aa111c7 15 // just adds a new line to the end of the data
diybitcoinhardware 0:23d71aa111c7 16 void println_hex(const uint8_t * data, size_t data_len){
diybitcoinhardware 0:23d71aa111c7 17 print_hex(data, data_len);
diybitcoinhardware 0:23d71aa111c7 18 printf("\r\n");
diybitcoinhardware 0:23d71aa111c7 19 }
diybitcoinhardware 0:23d71aa111c7 20 // prints error and hangs forever
diybitcoinhardware 0:23d71aa111c7 21 void err(const char * message, void * data = NULL){
diybitcoinhardware 0:23d71aa111c7 22 printf("ERROR: %s\r\n", message);
diybitcoinhardware 0:23d71aa111c7 23 while(1){
diybitcoinhardware 0:23d71aa111c7 24 wait(1);
diybitcoinhardware 0:23d71aa111c7 25 }
diybitcoinhardware 0:23d71aa111c7 26 }
diybitcoinhardware 0:23d71aa111c7 27
diybitcoinhardware 0:23d71aa111c7 28 void secp_example(){
diybitcoinhardware 0:23d71aa111c7 29 // secp256k1 context
diybitcoinhardware 0:23d71aa111c7 30 secp256k1_context *ctx = NULL;
diybitcoinhardware 0:23d71aa111c7 31
diybitcoinhardware 0:23d71aa111c7 32 int res; // to store results of function calls
diybitcoinhardware 0:23d71aa111c7 33 size_t len; // to store serialization lengths
diybitcoinhardware 0:23d71aa111c7 34
diybitcoinhardware 0:23d71aa111c7 35 printf("=== secp256k1 context ===\r\n");
diybitcoinhardware 0:23d71aa111c7 36
diybitcoinhardware 0:23d71aa111c7 37 // first we need to create the context
diybitcoinhardware 0:23d71aa111c7 38 // this is the size of memory to be allocated
diybitcoinhardware 0:23d71aa111c7 39 size_t context_size = secp256k1_context_preallocated_size(SECP256K1_CONTEXT_VERIFY | SECP256K1_CONTEXT_SIGN);
diybitcoinhardware 0:23d71aa111c7 40 printf("Context size: %u bytes\r\n", context_size);
diybitcoinhardware 0:23d71aa111c7 41
diybitcoinhardware 0:23d71aa111c7 42 // creating the context
diybitcoinhardware 0:23d71aa111c7 43 ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY | SECP256K1_CONTEXT_SIGN);
diybitcoinhardware 0:23d71aa111c7 44 printf("Context created\r\n");
diybitcoinhardware 0:23d71aa111c7 45
diybitcoinhardware 0:23d71aa111c7 46 printf("=== Secret key ===\r\n");
diybitcoinhardware 0:23d71aa111c7 47 // some random secret key
diybitcoinhardware 0:23d71aa111c7 48 uint8_t secret[] = {
diybitcoinhardware 0:23d71aa111c7 49 0xbd, 0xb5, 0x1a, 0x16, 0xeb, 0x64, 0x60, 0xec,
diybitcoinhardware 0:23d71aa111c7 50 0x16, 0xf8, 0x4d, 0x7b, 0x6f, 0x19, 0xe2, 0x0d,
diybitcoinhardware 0:23d71aa111c7 51 0x9b, 0x9a, 0xb5, 0x58, 0xfa, 0x0e, 0x9a, 0xe4,
diybitcoinhardware 0:23d71aa111c7 52 0xbb, 0x49, 0x3e, 0xf7, 0x79, 0xf1, 0x40, 0x55
diybitcoinhardware 0:23d71aa111c7 53 };
diybitcoinhardware 0:23d71aa111c7 54 printf("Secret key: ");
diybitcoinhardware 0:23d71aa111c7 55 println_hex(secret, sizeof(secret));
diybitcoinhardware 0:23d71aa111c7 56
diybitcoinhardware 0:23d71aa111c7 57 // Makes sense to check if secret key is valid.
diybitcoinhardware 0:23d71aa111c7 58 // It will be ok in most cases, only if secret > N it will be invalid
diybitcoinhardware 0:23d71aa111c7 59 res = secp256k1_ec_seckey_verify(ctx, secret);
diybitcoinhardware 0:23d71aa111c7 60 if(!res){ err("Secret key is invalid"); }
diybitcoinhardware 0:23d71aa111c7 61
diybitcoinhardware 0:23d71aa111c7 62 /**************** Public key ******************/
diybitcoinhardware 0:23d71aa111c7 63
diybitcoinhardware 0:23d71aa111c7 64 printf("=== Public key ===\r\n");
diybitcoinhardware 0:23d71aa111c7 65 // computing corresponding pubkey
diybitcoinhardware 0:23d71aa111c7 66 secp256k1_pubkey pubkey;
diybitcoinhardware 0:23d71aa111c7 67 res = secp256k1_ec_pubkey_create(ctx, &pubkey, secret);
diybitcoinhardware 0:23d71aa111c7 68 if(!res){ err("Pubkey computation failed"); }
diybitcoinhardware 0:23d71aa111c7 69
diybitcoinhardware 0:23d71aa111c7 70 // serialize the pubkey in compressed format
diybitcoinhardware 0:23d71aa111c7 71 uint8_t pub[33];
diybitcoinhardware 0:23d71aa111c7 72 len = sizeof(pub);
diybitcoinhardware 0:23d71aa111c7 73 secp256k1_ec_pubkey_serialize(ctx, pub, &len, &pubkey, SECP256K1_EC_COMPRESSED);
diybitcoinhardware 0:23d71aa111c7 74 printf("Public key: ");
diybitcoinhardware 0:23d71aa111c7 75 println_hex(pub, len);
diybitcoinhardware 0:23d71aa111c7 76
diybitcoinhardware 0:23d71aa111c7 77 // this is how you parse the pubkey
diybitcoinhardware 0:23d71aa111c7 78 res = secp256k1_ec_pubkey_parse(ctx, &pubkey, pub, 33);
diybitcoinhardware 0:23d71aa111c7 79 if(res){
diybitcoinhardware 0:23d71aa111c7 80 printf("Key is valid\r\n");
diybitcoinhardware 0:23d71aa111c7 81 }else{
diybitcoinhardware 0:23d71aa111c7 82 printf("Invalid key\r\n");
diybitcoinhardware 0:23d71aa111c7 83 }
diybitcoinhardware 0:23d71aa111c7 84
diybitcoinhardware 0:23d71aa111c7 85 /**************** Signature stuff ******************/
diybitcoinhardware 0:23d71aa111c7 86
diybitcoinhardware 0:23d71aa111c7 87 printf("=== Signature generation ===\r\n");
diybitcoinhardware 0:23d71aa111c7 88
diybitcoinhardware 0:23d71aa111c7 89 // hash of the string "hello"
diybitcoinhardware 0:23d71aa111c7 90 uint8_t hash[32] = {
diybitcoinhardware 0:23d71aa111c7 91 0x2c, 0xf2, 0x4d, 0xba, 0x5f, 0xb0, 0xa3, 0x0e,
diybitcoinhardware 0:23d71aa111c7 92 0x26, 0xe8, 0x3b, 0x2a, 0xc5, 0xb9, 0xe2, 0x9e,
diybitcoinhardware 0:23d71aa111c7 93 0x1b, 0x16, 0x1e, 0x5c, 0x1f, 0xa7, 0x42, 0x5e,
diybitcoinhardware 0:23d71aa111c7 94 0x73, 0x04, 0x33, 0x62, 0x93, 0x8b, 0x98, 0x24
diybitcoinhardware 0:23d71aa111c7 95 };
diybitcoinhardware 0:23d71aa111c7 96 // signing
diybitcoinhardware 0:23d71aa111c7 97 secp256k1_ecdsa_signature sig;
diybitcoinhardware 0:23d71aa111c7 98 res = secp256k1_ecdsa_sign(ctx, &sig, hash, secret, NULL, NULL);
diybitcoinhardware 0:23d71aa111c7 99 if(!res){ err("Can't sign"); }
diybitcoinhardware 0:23d71aa111c7 100
diybitcoinhardware 0:23d71aa111c7 101 // serialization
diybitcoinhardware 0:23d71aa111c7 102 uint8_t der[72];
diybitcoinhardware 0:23d71aa111c7 103 len = sizeof(der);
diybitcoinhardware 0:23d71aa111c7 104 res = secp256k1_ecdsa_signature_serialize_der(ctx, der, &len, &sig);
diybitcoinhardware 0:23d71aa111c7 105 if(!res){ err("Can't serialize the signature"); }
diybitcoinhardware 0:23d71aa111c7 106 printf("Signature: ");
diybitcoinhardware 0:23d71aa111c7 107 println_hex(der, len);
diybitcoinhardware 0:23d71aa111c7 108
diybitcoinhardware 0:23d71aa111c7 109 // verification
diybitcoinhardware 0:23d71aa111c7 110 printf("=== Signature verification ===\r\n");
diybitcoinhardware 0:23d71aa111c7 111 res = secp256k1_ecdsa_verify(ctx, &sig, hash, &pubkey);
diybitcoinhardware 0:23d71aa111c7 112 if(res){
diybitcoinhardware 0:23d71aa111c7 113 printf("Signature is valid\r\n");
diybitcoinhardware 0:23d71aa111c7 114 }else{
diybitcoinhardware 0:23d71aa111c7 115 printf("Invalid signature\r\n");
diybitcoinhardware 0:23d71aa111c7 116 }
diybitcoinhardware 0:23d71aa111c7 117
diybitcoinhardware 0:23d71aa111c7 118 secp256k1_context_destroy(ctx);
diybitcoinhardware 0:23d71aa111c7 119 }
diybitcoinhardware 0:23d71aa111c7 120
diybitcoinhardware 0:23d71aa111c7 121 int main(){
diybitcoinhardware 0:23d71aa111c7 122 printf("Press any key to continue\r\n");
diybitcoinhardware 0:23d71aa111c7 123 pc.getc();
diybitcoinhardware 0:23d71aa111c7 124 printf("Ready to go!\r\n");
diybitcoinhardware 0:23d71aa111c7 125
diybitcoinhardware 0:23d71aa111c7 126 printf("=== Running example for secp256k1 ===\r\n");
diybitcoinhardware 0:23d71aa111c7 127 secp_example();
diybitcoinhardware 0:23d71aa111c7 128
diybitcoinhardware 0:23d71aa111c7 129
diybitcoinhardware 0:23d71aa111c7 130 printf("\r\n=== Done ===\r\n");
diybitcoinhardware 0:23d71aa111c7 131
diybitcoinhardware 0:23d71aa111c7 132 }