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