-
Notifications
You must be signed in to change notification settings - Fork 48
/
example.c
142 lines (117 loc) · 3.84 KB
/
example.c
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
133
134
135
136
137
138
139
140
141
142
/*! @file example.c
* @brief This is an example program to demonstrate how to use the
* Picnic signature API.
*
* This file is part of the reference implementation of the Picnic signature scheme.
* See the accompanying documentation for complete details.
*
* The code is provided under the MIT license, see LICENSE for
* more details.
* SPDX-License-Identifier: MIT
*/
#include "picnic.h"
#include <stdio.h>
#include <memory.h>
#include <inttypes.h>
#define MSG_LEN 500
int picnicExample(picnic_params_t parameters)
{
picnic_publickey_t pk;
picnic_privatekey_t sk;
printf("Picnic example with parameter set: %s\n", picnic_get_param_name(parameters) );
fprintf(stdout, "Generating key... ");
fflush(stdout);
int ret = picnic_keygen(parameters, &pk, &sk);
if (ret != 0) {
printf("picnic_keygen failed\n");
exit(-1);
}
printf(" success\n");
uint8_t message[MSG_LEN];
memset(message, 0x01, sizeof(message));
uint8_t* signature = NULL;
size_t signature_len = picnic_signature_size(parameters);
signature = (uint8_t*)malloc(signature_len);
if (signature == NULL) {
printf("failed to allocate signature\n");
exit(-1);
}
fprintf(stdout, "Max signature length %" PRIuPTR " bytes\n", signature_len);
fprintf(stdout, "Signing a %d byte message... ", MSG_LEN);
fflush(stdout);
ret = picnic_sign(&sk, message, sizeof(message), signature, &signature_len);
if (ret != 0) {
printf("picnic_sign failed\n");
exit(-1);
}
printf(" success, signature is %d bytes\n", (int)signature_len);
/* signature_len has the exact number of bytes used */
if (signature_len < picnic_signature_size(parameters)) {
uint8_t* newsig = realloc(signature, signature_len);
if (newsig == NULL) {
printf("failed to re-size signature\n");
/* Not an error, we can continue with signature */
}
else {
signature = newsig;
}
}
fprintf(stdout, "Verifying signature... ");
fflush(stdout);
ret = picnic_verify(&pk, message, sizeof(message), signature, signature_len);
if (ret != 0) {
printf("picnic_verify failed\n");
exit(-1);
}
printf(" success\n");
printf("Testing public key serialization... ");
uint8_t pk_buf[PICNIC_MAX_PUBLICKEY_SIZE];
ret = picnic_write_public_key(&pk, pk_buf, sizeof(pk_buf));
if (ret <= 0) {
printf("Failed to serialize public key\n");
exit(-1);
}
memset(&pk, 0x00, sizeof(picnic_publickey_t));
ret = picnic_read_public_key(&pk, pk_buf, sizeof(pk_buf));
if (ret != 0) {
printf("Failed to read public key\n");
exit(-1);
}
ret = picnic_verify(&pk, message, sizeof(message), signature, signature_len);
if (ret != 0) {
printf("picnic_verify failed after de-serializing public key\n");
exit(-1);
}
printf(" success\n");
printf("Testing private key serialization... ");
uint8_t sk_buf[PICNIC_MAX_PRIVATEKEY_SIZE];
ret = picnic_write_private_key(&sk, sk_buf, sizeof(sk_buf));
if (ret <= 0) {
printf("Failed to write private key\n");
exit(-1);
}
memset(&sk, 0x00, sizeof(picnic_privatekey_t));
ret = picnic_read_private_key(&sk, sk_buf, sizeof(sk_buf));
if (ret != 0) {
printf("Failed to read private key\n");
exit(-1);
}
ret = picnic_validate_keypair(&sk, &pk);
if (ret != 0) {
printf("Keypair invalid after deserializing private key\n");
exit(-1);
}
printf(" success\n\n");
free(signature);
return 0;
}
int main(int argc, char** argv)
{
if (argc > 1) {
picnicExample(atoi(argv[1]));
return 0;
}
for (picnic_params_t params = 1; params < PARAMETER_SET_MAX_INDEX; params++) {
picnicExample(params);
}
}