forked from kj3moraes/further-testing-xmss
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathxmss.c
156 lines (130 loc) · 4.22 KB
/
xmss.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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
#include <stdint.h>
#include "params.h"
#include "xmss_core.h"
#include "utils.h"
/* This file provides wrapper functions that take keys that include OIDs to
identify the parameter set to be used. After setting the parameters accordingly
it falls back to the regular XMSS core functions. */
int xmss_keypair(unsigned char *pk, unsigned char *sk, const uint32_t oid)
{
xmss_params params;
unsigned int i;
if (xmss_parse_oid(¶ms, oid)) {
return -1;
}
for (i = 0; i < XMSS_OID_LEN; i++) {
pk[XMSS_OID_LEN - i - 1] = (oid >> (8 * i)) & 0xFF;
/* For an implementation that uses runtime parameters, it is crucial
that the OID is part of the secret key as well;
i.e. not just for interoperability, but also for internal use. */
sk[XMSS_OID_LEN - i - 1] = (oid >> (8 * i)) & 0xFF;
}
return xmss_core_keypair(¶ms, pk + XMSS_OID_LEN, sk + XMSS_OID_LEN);
}
int xmss_sign(unsigned char *sk,
unsigned char *sm, unsigned long long *smlen,
const unsigned char *m, unsigned long long mlen)
{
xmss_params params;
uint32_t oid = 0;
unsigned int i;
for (i = 0; i < XMSS_OID_LEN; i++) {
oid |= sk[XMSS_OID_LEN - i - 1] << (i * 8);
}
if (xmss_parse_oid(¶ms, oid)) {
return -1;
}
return xmss_core_sign(¶ms, sk + XMSS_OID_LEN, sm, smlen, m, mlen);
}
int xmss_sign_open(unsigned char *m, unsigned long long *mlen,
const unsigned char *sm, unsigned long long smlen,
const unsigned char *pk)
{
xmss_params params;
uint32_t oid = 0;
unsigned int i;
for (i = 0; i < XMSS_OID_LEN; i++) {
oid |= pk[XMSS_OID_LEN - i - 1] << (i * 8);
}
if (xmss_parse_oid(¶ms, oid)) {
return -1;
}
return xmss_core_sign_open(¶ms, m, mlen, sm, smlen, pk + XMSS_OID_LEN);
}
int xmss_remain_signatures(unsigned long long *remain, const unsigned char *sk)
{
xmss_params params;
uint32_t oid = 0;
unsigned int i;
unsigned long long idx, max;
for (i = 0; i < XMSS_OID_LEN; i++) {
oid |= sk[XMSS_OID_LEN - i - 1] << (i * 8);
}
if (xmss_parse_oid(¶ms, oid)) {
return -1;
}
idx = bytes_to_ull(sk + XMSS_OID_LEN, params.index_bytes);
max = ((1ULL << params.full_height) - 1);
*remain = max - idx;
return 0;
}
int xmssmt_keypair(unsigned char *pk, unsigned char *sk, const uint32_t oid)
{
xmss_params params;
unsigned int i;
if (xmssmt_parse_oid(¶ms, oid)) {
return -1;
}
for (i = 0; i < XMSS_OID_LEN; i++) {
pk[XMSS_OID_LEN - i - 1] = (oid >> (8 * i)) & 0xFF;
sk[XMSS_OID_LEN - i - 1] = (oid >> (8 * i)) & 0xFF;
}
return xmssmt_core_keypair(¶ms, pk + XMSS_OID_LEN, sk + XMSS_OID_LEN);
}
int xmssmt_sign(unsigned char *sk,
unsigned char *sm, unsigned long long *smlen,
const unsigned char *m, unsigned long long mlen)
{
xmss_params params;
uint32_t oid = 0;
unsigned int i;
for (i = 0; i < XMSS_OID_LEN; i++) {
oid |= sk[XMSS_OID_LEN - i - 1] << (i * 8);
}
if (xmssmt_parse_oid(¶ms, oid)) {
return -1;
}
return xmssmt_core_sign(¶ms, sk + XMSS_OID_LEN, sm, smlen, m, mlen);
}
int xmssmt_sign_open(unsigned char *m, unsigned long long *mlen,
const unsigned char *sm, unsigned long long smlen,
const unsigned char *pk)
{
xmss_params params;
uint32_t oid = 0;
unsigned int i;
for (i = 0; i < XMSS_OID_LEN; i++) {
oid |= pk[XMSS_OID_LEN - i - 1] << (i * 8);
}
if (xmssmt_parse_oid(¶ms, oid)) {
return -1;
}
return xmssmt_core_sign_open(¶ms, m, mlen, sm, smlen, pk + XMSS_OID_LEN);
}
int xmssmt_remain_signatures(unsigned long long *remain, const unsigned char *sk)
{
xmss_params params;
uint32_t oid = 0;
unsigned int i;
unsigned long long idx, max;
for (i = 0; i < XMSS_OID_LEN; i++) {
oid |= sk[XMSS_OID_LEN - i - 1] << (i * 8);
}
if (xmssmt_parse_oid(¶ms, oid)) {
return -1;
}
idx = bytes_to_ull(sk + XMSS_OID_LEN, params.index_bytes);
max = ((1ULL << params.full_height) - 1);
*remain = max - idx;
return 0;
}