@@ -10,36 +10,93 @@ pub mod signers {
10
10
///
11
11
/// Can be implemented using the convenience macro [`impl_context`].
12
12
pub trait Context {
13
+ /// This is a buffer of valid size. The validity trait is private, so the users can't
14
+ /// flag more sizes as valid and circumvent the type safety we established here.
15
+ #[ allow( private_bounds) ]
16
+ type Buf : ValidContextBuf ;
17
+
13
18
/// Return the context.
14
- fn context ( ) -> & ' static [ u8 ] ;
19
+ fn context ( ) -> & ' static Self :: Buf ;
15
20
}
16
21
22
+ trait ValidContextBuf { }
23
+
24
+ // Implement ValidContextBuf for all sizes 0..=255
25
+ macro_rules! define_valid_buf {
26
+ ( ) => {
27
+ define_valid_buf!( 0 ) ;
28
+ define_valid_buf!( 1 ) ;
29
+ define_valid_buf!( 2 , 0 ) ;
30
+ define_valid_buf!( 2 , 1 ) ;
31
+ define_valid_buf!( 2 , 2 ) ;
32
+ define_valid_buf!( 2 , 3 ) ;
33
+ define_valid_buf!( 2 , 4 ) ;
34
+ define_valid_buf!( 2 , 5 , 0 ) ;
35
+ define_valid_buf!( 2 , 5 , 1 ) ;
36
+ define_valid_buf!( 2 , 5 , 2 ) ;
37
+ define_valid_buf!( 2 , 5 , 3 ) ;
38
+ define_valid_buf!( 2 , 5 , 4 ) ;
39
+ define_valid_buf!( 2 , 5 , 5 ) ;
40
+ } ;
41
+ ( $num: expr) => {
42
+ define_valid_buf!( $num, 0 ) ;
43
+ define_valid_buf!( $num, 1 ) ;
44
+ define_valid_buf!( $num, 2 ) ;
45
+ define_valid_buf!( $num, 3 ) ;
46
+ define_valid_buf!( $num, 4 ) ;
47
+ define_valid_buf!( $num, 5 ) ;
48
+ define_valid_buf!( $num, 6 ) ;
49
+ define_valid_buf!( $num, 7 ) ;
50
+ define_valid_buf!( $num, 8 ) ;
51
+ define_valid_buf!( $num, 9 ) ;
52
+ } ;
53
+ ( $num1: expr, $num2: expr) => {
54
+ define_valid_buf!( $num1, $num2, 0 ) ;
55
+ define_valid_buf!( $num1, $num2, 1 ) ;
56
+ define_valid_buf!( $num1, $num2, 2 ) ;
57
+ define_valid_buf!( $num1, $num2, 3 ) ;
58
+ define_valid_buf!( $num1, $num2, 4 ) ;
59
+ define_valid_buf!( $num1, $num2, 5 ) ;
60
+ define_valid_buf!( $num1, $num2, 6 ) ;
61
+ define_valid_buf!( $num1, $num2, 7 ) ;
62
+ define_valid_buf!( $num1, $num2, 8 ) ;
63
+ define_valid_buf!( $num1, $num2, 9 ) ;
64
+ } ;
65
+ ( $num1: expr, $num2: expr, $num3: expr) => {
66
+ impl ValidContextBuf for [ u8 ; $num1 * 100 + $num2 * 10 + $num3] { }
67
+ } ;
68
+ }
69
+
70
+ define_valid_buf ! ( ) ;
71
+
17
72
#[ macro_export]
18
73
/// A convenience macro for implementing the [`Context`] trait.
19
- /// The `$context` must be provided as a `&'static [u8]`.
74
+ /// The `$context` must be provided as a `&'static [u8; $len ]`.
20
75
///
21
76
/// Usage:
22
77
/// ```rust
23
78
/// use libcrux_ml_dsa::signers::{Context, impl_context};
24
- /// impl_context!(AppContext, b"context");
79
+ /// impl_context!(AppContext, b"context", 7 );
25
80
/// ```
26
81
macro_rules! impl_context {
27
- ( $name: ident, $context: literal) => {
82
+ ( $name: ident, $context: literal, $len : expr ) => {
28
83
impl_context!(
29
84
$name,
30
85
$context,
86
+ $len,
31
87
concat!(
32
88
"An ML-DSA signing context that contains \" " ,
33
89
stringify!( $context) ,
34
90
"\" ."
35
91
)
36
92
)
37
93
} ;
38
- ( $name: ident, $context: literal, $doc: expr) => {
94
+ ( $name: ident, $context: literal, $len : expr , $ doc: expr) => {
39
95
#[ doc = $doc]
40
96
pub struct $name;
41
97
impl Context for $name {
42
- fn context( ) -> & ' static [ u8 ] {
98
+ type Buf = [ u8 ; $len] ;
99
+ fn context( ) -> & ' static [ u8 ; $len] {
43
100
$context
44
101
}
45
102
}
@@ -68,7 +125,7 @@ pub mod signers {
68
125
///
69
126
/// It is the responsibility of the caller to ensure that the `randomness` argument is actually
70
127
/// random.
71
- impl <T : Context >
128
+ impl <const N : usize , T : Context < Buf = [ u8 ; N ] > >
72
129
arrayref:: Sign <
73
130
SIGNING_KEY_LEN ,
74
131
VERIFICATION_KEY_LEN ,
@@ -91,7 +148,11 @@ pub mod signers {
91
148
randomness. declassify( ) ,
92
149
signature
93
150
)
94
- . map_err( |_| arrayref:: SignError :: LibraryError )
151
+ . map_err( |err| match err {
152
+ crate :: types:: SigningError :: RejectionSamplingError => arrayref:: SignError :: InvalidRandomness ,
153
+ crate :: types:: SigningError :: ContextTooLongError => arrayref:: SignError :: InvalidArgument ,
154
+
155
+ } )
95
156
}
96
157
/// Verify a signature using a provided verification key and context.
97
158
fn verify(
@@ -105,7 +166,13 @@ pub mod signers {
105
166
T :: context( ) ,
106
167
signature,
107
168
)
108
- . map_err( |_| arrayref:: VerifyError :: LibraryError )
169
+ . map_err( |err| match err {
170
+ crate :: types:: VerificationError :: MalformedHintError =>arrayref:: VerifyError :: InvalidSignature ,
171
+ crate :: types:: VerificationError :: SignerResponseExceedsBoundError =>arrayref:: VerifyError :: InvalidSignature ,
172
+ crate :: types:: VerificationError :: CommitmentHashesDontMatchError =>arrayref:: VerifyError :: InvalidSignature ,
173
+ crate :: types:: VerificationError :: VerificationContextTooLongError =>arrayref:: VerifyError :: LibraryError ,
174
+
175
+ } )
109
176
}
110
177
111
178
fn keygen_derand(
0 commit comments