@@ -22,9 +22,11 @@ pub const WOTS_DIGIT_WIDTH: usize = 4;
22
22
pub const WOTS_DIGITS_PER_BYTE : usize = 8 / WOTS_DIGIT_WIDTH ;
23
23
24
24
/// The maximum number a WOTS digit can hold.
25
+ #[ allow( dead_code) ]
25
26
pub const WOTS_MAX_DIGIT : usize = ( 2 << WOTS_DIGIT_WIDTH ) - 1 ;
26
27
27
28
/// The number of WOTS digits required to represent a message for a given message length.
29
+ #[ allow( dead_code) ]
28
30
pub const fn wots_msg_digits ( msg_len_bytes : usize ) -> usize {
29
31
WOTS_DIGITS_PER_BYTE * msg_len_bytes
30
32
}
@@ -33,6 +35,7 @@ pub const fn wots_msg_digits(msg_len_bytes: usize) -> usize {
33
35
///
34
36
/// The checksum of a WOTS commitment is the sum of the digit values themselves which is then
35
37
/// encoded as a base256 integer. That integer is then signed using the same WOTS scheme.
38
+ #[ allow( dead_code) ]
36
39
pub const fn wots_checksum_digits ( msg_len_bytes : usize ) -> usize {
37
40
let max_checksum = wots_msg_digits ( msg_len_bytes) * WOTS_MAX_DIGIT ;
38
41
@@ -52,47 +55,46 @@ pub const fn wots_checksum_digits(msg_len_bytes: usize) -> usize {
52
55
}
53
56
54
57
/// The total number of WOTS digit keys
58
+ #[ allow( dead_code) ]
55
59
pub const fn wots_total_digits ( msg_len_bytes : usize ) -> usize {
56
60
wots_msg_digits ( msg_len_bytes) + wots_checksum_digits ( msg_len_bytes)
57
61
}
58
62
59
63
/// A variable-length Winternitz One-Time Signature (WOTS) public key.
60
64
#[ derive( Debug , Clone , Copy , PartialEq , Eq , PartialOrd , Ord , Hash ) ]
61
65
#[ cfg_attr( feature = "proptest" , derive( Arbitrary ) ) ]
62
- pub struct WotsPublicKey < const MSG_LEN_BYTES : usize > (
63
- pub [ [ u8 ; WOTS_SINGLE ] ; wots_total_digits ( MSG_LEN_BYTES ) ] ,
64
- )
66
+ pub struct WotsPublicKey < const MSG_LEN_BYTES : usize > ( pub [ [ u8 ; WOTS_SINGLE ] ; MSG_LEN_BYTES ] )
65
67
where
66
- [ ( ) ; wots_total_digits ( MSG_LEN_BYTES ) ] : Sized ;
68
+ [ ( ) ; MSG_LEN_BYTES ] : Sized ;
67
69
68
70
/// 160-bit Winternitz One-Time Signature (WOTS) public key.
69
- pub type Wots160PublicKey = WotsPublicKey < 20 > ;
71
+ pub type Wots160PublicKey = WotsPublicKey < 44 > ;
70
72
71
73
/// 256-bit Winternitz One-Time Signature (WOTS) public key.
72
- pub type Wots256PublicKey = WotsPublicKey < 32 > ;
74
+ pub type Wots256PublicKey = WotsPublicKey < 68 > ;
73
75
74
76
impl < const MSG_LEN_BYTES : usize > WotsPublicKey < MSG_LEN_BYTES >
75
77
where
76
- [ ( ) ; wots_total_digits ( MSG_LEN_BYTES ) ] : Sized ,
77
- [ ( ) ; WOTS_SINGLE * wots_total_digits ( MSG_LEN_BYTES ) ] : Sized ,
78
+ [ ( ) ; MSG_LEN_BYTES ] : Sized ,
79
+ [ ( ) ; WOTS_SINGLE * MSG_LEN_BYTES ] : Sized ,
78
80
{
79
81
/// The size of this WOTS public key in bytes.
80
- pub const SIZE : usize = wots_total_digits ( MSG_LEN_BYTES ) ;
82
+ pub const SIZE : usize = MSG_LEN_BYTES ;
81
83
82
84
/// Creates a new WOTS 160-bit public key from a byte array.
83
- pub fn new ( bytes : [ [ u8 ; WOTS_SINGLE ] ; wots_total_digits ( MSG_LEN_BYTES ) ] ) -> Self {
85
+ pub fn new ( bytes : [ [ u8 ; WOTS_SINGLE ] ; MSG_LEN_BYTES ] ) -> Self {
84
86
Self ( bytes)
85
87
}
86
88
87
89
/// Converts the public key to a byte array.
88
- pub fn to_bytes ( & self ) -> [ [ u8 ; WOTS_SINGLE ] ; wots_total_digits ( MSG_LEN_BYTES ) ] {
90
+ pub fn to_bytes ( & self ) -> [ [ u8 ; WOTS_SINGLE ] ; MSG_LEN_BYTES ] {
89
91
self . 0
90
92
}
91
93
92
94
/// Converts the public key to a flattened byte array.
93
95
pub fn to_flattened_bytes ( & self ) -> Vec < u8 > {
94
96
// Changed return type to Vec<u8>
95
- let mut bytes = Vec :: with_capacity ( WOTS_SINGLE * wots_total_digits ( MSG_LEN_BYTES ) ) ;
97
+ let mut bytes = Vec :: with_capacity ( WOTS_SINGLE * MSG_LEN_BYTES ) ;
96
98
for byte_array in & self . 0 {
97
99
bytes. extend_from_slice ( byte_array) ;
98
100
}
@@ -110,11 +112,11 @@ where
110
112
pub fn from_flattened_bytes ( bytes : & [ u8 ] ) -> Self {
111
113
assert_eq ! (
112
114
bytes. len( ) ,
113
- WOTS_SINGLE * ( 2 * MSG_LEN_BYTES + 4 ) ,
115
+ WOTS_SINGLE * MSG_LEN_BYTES ,
114
116
"Invalid byte array length"
115
117
) ;
116
118
117
- let mut key = [ [ 0u8 ; WOTS_SINGLE ] ; wots_total_digits ( MSG_LEN_BYTES ) ] ;
119
+ let mut key = [ [ 0u8 ; WOTS_SINGLE ] ; MSG_LEN_BYTES ] ;
118
120
for ( i, byte_array) in key. iter_mut ( ) . enumerate ( ) {
119
121
byte_array. copy_from_slice ( & bytes[ i * WOTS_SINGLE ..( i + 1 ) * WOTS_SINGLE ] ) ;
120
122
}
@@ -124,9 +126,9 @@ where
124
126
125
127
impl < const MSG_LEN_BYTES : usize > Deref for WotsPublicKey < MSG_LEN_BYTES >
126
128
where
127
- [ ( ) ; wots_total_digits ( MSG_LEN_BYTES ) ] : Sized ,
129
+ [ ( ) ; MSG_LEN_BYTES ] : Sized ,
128
130
{
129
- type Target = [ [ u8 ; WOTS_SINGLE ] ; wots_total_digits ( MSG_LEN_BYTES ) ] ;
131
+ type Target = [ [ u8 ; WOTS_SINGLE ] ; MSG_LEN_BYTES ] ;
130
132
131
133
fn deref ( & self ) -> & Self :: Target {
132
134
& self . 0
@@ -135,7 +137,7 @@ where
135
137
136
138
impl < const MSG_LEN_BYTES : usize > DerefMut for WotsPublicKey < MSG_LEN_BYTES >
137
139
where
138
- [ ( ) ; wots_total_digits ( MSG_LEN_BYTES ) ] : Sized ,
140
+ [ ( ) ; MSG_LEN_BYTES ] : Sized ,
139
141
{
140
142
fn deref_mut ( & mut self ) -> & mut Self :: Target {
141
143
& mut self . 0
@@ -145,8 +147,8 @@ where
145
147
// Custom Serialization for WotsPublicKey
146
148
impl < const MSG_LEN_BYTES : usize > Serialize for WotsPublicKey < MSG_LEN_BYTES >
147
149
where
148
- [ ( ) ; wots_total_digits ( MSG_LEN_BYTES ) ] : Sized ,
149
- [ ( ) ; WOTS_SINGLE * wots_total_digits ( MSG_LEN_BYTES ) ] : Sized ,
150
+ [ ( ) ; MSG_LEN_BYTES ] : Sized ,
151
+ [ ( ) ; WOTS_SINGLE * MSG_LEN_BYTES ] : Sized ,
150
152
{
151
153
fn serialize < S > ( & self , serializer : S ) -> Result < S :: Ok , S :: Error >
152
154
where
@@ -167,8 +169,8 @@ where
167
169
// Custom Deserialization for WotsPublicKey
168
170
impl < ' de , const MSG_LEN_BYTES : usize > Deserialize < ' de > for WotsPublicKey < MSG_LEN_BYTES >
169
171
where
170
- [ ( ) ; wots_total_digits ( MSG_LEN_BYTES ) ] : Sized ,
171
- [ ( ) ; WOTS_SINGLE * wots_total_digits ( MSG_LEN_BYTES ) ] : Sized ,
172
+ [ ( ) ; MSG_LEN_BYTES ] : Sized ,
173
+ [ ( ) ; WOTS_SINGLE * MSG_LEN_BYTES ] : Sized ,
172
174
{
173
175
fn deserialize < D > ( deserializer : D ) -> Result < Self , D :: Error >
174
176
where
@@ -178,26 +180,23 @@ where
178
180
179
181
impl < ' de , const M : usize > Visitor < ' de > for WotsPublicKeyVisitor < M >
180
182
where
181
- [ ( ) ; wots_total_digits ( M ) ] : Sized ,
183
+ [ ( ) ; M ] : Sized ,
182
184
{
183
185
type Value = WotsPublicKey < M > ;
184
186
185
187
fn expecting ( & self , formatter : & mut fmt:: Formatter ) -> fmt:: Result {
186
- formatter. write_str ( & format ! (
187
- "a WotsPublicKey with {} bytes" ,
188
- WOTS_SINGLE * ( 2 * M + 4 )
189
- ) )
188
+ formatter. write_str ( & format ! ( "a WotsPublicKey with {} bytes" , WOTS_SINGLE * M ) )
190
189
}
191
190
192
191
fn visit_bytes < E > ( self , bytes : & [ u8 ] ) -> Result < Self :: Value , E >
193
192
where
194
193
E : de:: Error ,
195
194
{
196
- if bytes. len ( ) != WOTS_SINGLE * ( 2 * M + 4 ) {
195
+ if bytes. len ( ) != WOTS_SINGLE * M {
197
196
return Err ( E :: invalid_length ( bytes. len ( ) , & self ) ) ;
198
197
}
199
198
200
- let mut array = [ [ 0u8 ; WOTS_SINGLE ] ; wots_total_digits ( M ) ] ;
199
+ let mut array = [ [ 0u8 ; WOTS_SINGLE ] ; M ] ;
201
200
for ( i, chunk) in bytes. chunks ( WOTS_SINGLE ) . enumerate ( ) {
202
201
array[ i] . copy_from_slice ( chunk) ;
203
202
}
@@ -208,7 +207,7 @@ where
208
207
where
209
208
A : SeqAccess < ' de > ,
210
209
{
211
- let mut array = [ [ 0u8 ; WOTS_SINGLE ] ; wots_total_digits ( M ) ] ;
210
+ let mut array = [ [ 0u8 ; WOTS_SINGLE ] ; M ] ;
212
211
for ( i, item) in array. iter_mut ( ) . enumerate ( ) {
213
212
* item = seq
214
213
. next_element ( ) ?
@@ -249,8 +248,8 @@ mod tests {
249
248
250
249
#[ test]
251
250
fn flattened_bytes_roundtrip ( ) {
252
- let key160 = Wots160PublicKey :: new ( [ [ 1u8 ; WOTS_SINGLE ] ; wots_total_digits ( 20 ) ] ) ; // 2 * 20 + 4
253
- let key256 = Wots256PublicKey :: new ( [ [ 1u8 ; WOTS_SINGLE ] ; wots_total_digits ( 32 ) ] ) ; // 2 * 32 + 4
251
+ let key160 = Wots160PublicKey :: new ( [ [ 1u8 ; WOTS_SINGLE ] ; 44 ] ) ; // 2 * 20 + 4
252
+ let key256 = Wots256PublicKey :: new ( [ [ 1u8 ; WOTS_SINGLE ] ; 68 ] ) ; // 2 * 32 + 4
254
253
255
254
// Test flattened bytes roundtrip
256
255
let flattened160 = key160. to_flattened_bytes ( ) ;
@@ -265,8 +264,8 @@ mod tests {
265
264
266
265
#[ test]
267
266
fn json_serialization ( ) {
268
- let key160 = Wots160PublicKey :: new ( [ [ 1u8 ; WOTS_SINGLE ] ; wots_total_digits ( 20 ) ] ) ; // 2 * 20 + 4
269
- let key256 = Wots256PublicKey :: new ( [ [ 1u8 ; WOTS_SINGLE ] ; wots_total_digits ( 32 ) ] ) ; // 2 * 32 + 4
267
+ let key160 = Wots160PublicKey :: new ( [ [ 1u8 ; WOTS_SINGLE ] ; 44 ] ) ; // 2 * 20 + 4
268
+ let key256 = Wots256PublicKey :: new ( [ [ 1u8 ; WOTS_SINGLE ] ; 68 ] ) ; // 2 * 32 + 4
270
269
271
270
// Test JSON serialization
272
271
let serialized160 = serde_json:: to_string ( & key160) . unwrap ( ) ;
@@ -280,8 +279,8 @@ mod tests {
280
279
281
280
#[ test]
282
281
fn bincode_serialization ( ) {
283
- let key160 = Wots160PublicKey :: new ( [ [ 1u8 ; WOTS_SINGLE ] ; wots_total_digits ( 20 ) ] ) ; // 2 * 20 + 4
284
- let key256 = Wots256PublicKey :: new ( [ [ 1u8 ; WOTS_SINGLE ] ; wots_total_digits ( 32 ) ] ) ; // 2 * 32 + 4
282
+ let key160 = Wots160PublicKey :: new ( [ [ 1u8 ; WOTS_SINGLE ] ; 44 ] ) ; // 2 * 20 + 4
283
+ let key256 = Wots256PublicKey :: new ( [ [ 1u8 ; WOTS_SINGLE ] ; 68 ] ) ; // 2 * 32 + 4
285
284
286
285
// Test bincode serialization
287
286
let serialized160 = bincode:: serialize ( & key160) . unwrap ( ) ;
@@ -304,7 +303,7 @@ mod tests {
304
303
305
304
#[ test]
306
305
#[ should_panic]
307
- fn deserialize_too_many_elements20 ( ) {
306
+ fn deserialize_too_many_elements160 ( ) {
308
307
// Create JSON string with 45 arrays
309
308
let mut json = String :: from ( "[" ) ;
310
309
for i in 0 ..45 {
@@ -320,7 +319,7 @@ mod tests {
320
319
321
320
#[ test]
322
321
#[ should_panic]
323
- fn deserialize_too_many_elements32 ( ) {
322
+ fn deserialize_too_many_elements256 ( ) {
324
323
// Create JSON string with 33 arrays
325
324
let mut json = String :: from ( "[" ) ;
326
325
for i in 0 ..33 {
@@ -336,10 +335,10 @@ mod tests {
336
335
337
336
#[ test]
338
337
#[ should_panic]
339
- fn deserialize_invalid_array_length20 ( ) {
338
+ fn deserialize_invalid_array_length44 ( ) {
340
339
// Create JSON with one array having wrong length (19 instead of 20)
341
340
let mut json = String :: from ( "[" ) ;
342
- for i in 0 ..WotsPublicKey :: < 20 > :: SIZE {
341
+ for i in 0 ..WotsPublicKey :: < 44 > :: SIZE {
343
342
if i == 14 {
344
343
json. push_str ( "[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]" ) ; // 19 elements
345
344
} else {
@@ -356,16 +355,16 @@ mod tests {
356
355
357
356
#[ test]
358
357
#[ should_panic]
359
- fn deserialize_invalid_array_length32 ( ) {
358
+ fn deserialize_invalid_array_length256 ( ) {
360
359
// Create JSON with one array having wrong length (19 instead of 20)
361
360
let mut json = String :: from ( "[" ) ;
362
- for i in 0 ..WotsPublicKey :: < 32 > :: SIZE {
361
+ for i in 0 ..WotsPublicKey :: < 68 > :: SIZE {
363
362
if i == 20 {
364
363
json. push_str ( "[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]" ) ; // 19 elements
365
364
} else {
366
365
json. push_str ( "[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]" ) ;
367
366
}
368
- if i < WotsPublicKey :: < 32 > :: SIZE - 1 {
367
+ if i < WotsPublicKey :: < 68 > :: SIZE - 1 {
369
368
json. push ( ',' ) ;
370
369
}
371
370
}
@@ -447,7 +446,7 @@ mod tests {
447
446
let flattened = key. to_flattened_bytes( ) ;
448
447
449
448
// Verify the length is correct
450
- prop_assert_eq!( flattened. len( ) , WOTS_SINGLE * ( 2 * 20 + 4 ) ) ;
449
+ prop_assert_eq!( flattened. len( ) , WOTS_SINGLE * 44 ) ;
451
450
452
451
// Verify each segment matches the original arrays
453
452
for ( i, original_array) in key. 0 . iter( ) . enumerate( ) {
@@ -461,7 +460,7 @@ mod tests {
461
460
let flattened = key. to_flattened_bytes( ) ;
462
461
463
462
// Verify the length is correct
464
- prop_assert_eq!( flattened. len( ) , WOTS_SINGLE * ( 2 * 32 + 4 ) ) ;
463
+ prop_assert_eq!( flattened. len( ) , WOTS_SINGLE * 68 ) ;
465
464
466
465
// Verify each segment matches the original arrays
467
466
for ( i, original_array) in key. 0 . iter( ) . enumerate( ) {
0 commit comments