Skip to content

Commit 1c65231

Browse files
committed
clean up errors, constrain context
1 parent b6d36fb commit 1c65231

File tree

5 files changed

+101
-30
lines changed

5 files changed

+101
-30
lines changed

ecdsa/src/impl_signature_trait.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ pub mod signers {
4848
) -> Result<(), arrayref::SignError> {
4949
let result = libcrux_p256::$sign_fn(
5050
signature,
51-
payload.len().try_into().map_err(|_| arrayref::SignError::InvalidPayloadLength)?,
51+
payload.len().try_into().map_err(|_| arrayref::SignError::InvalidArgument)?,
5252
payload,
5353
signing_key.declassify_ref(),
5454
&nonce.0,
@@ -58,8 +58,9 @@ pub mod signers {
5858
}
5959
Ok(())
6060
}
61-
#[inline(always)]
61+
6262
/// Verify a signature using a provided verification key.
63+
#[inline(always)]
6364
fn verify(
6465
payload: &[u8],
6566
verification_key: &[u8; VERIFICATION_KEY_LEN],
@@ -77,6 +78,7 @@ pub mod signers {
7778
}
7879
Ok(())
7980
}
81+
8082
fn keygen_derand(
8183
signing_key: &mut [U8; SIGNING_KEY_LEN],
8284
verification_key: &mut [u8; VERIFICATION_KEY_LEN],
@@ -94,6 +96,7 @@ pub mod signers {
9496

9597
}
9698
}
99+
97100
libcrux_traits::impl_signature_slice_trait!(
98101
Signer<$name> => SIGNING_KEY_LEN, VERIFICATION_KEY_LEN, SIG_LEN, RAND_KEYGEN_LEN, &Nonce, nonce);
99102

@@ -106,13 +109,11 @@ pub mod signers {
106109
RAND_KEYGEN_LEN,
107110
&'a Nonce
108111
);
109-
110112
};
111113
}
112114

115+
/// [`libcrux_traits::signature`] APIs for p256.
113116
pub mod p256 {
114-
//! [`libcrux_traits::signature`] APIs for p256.
115-
116117
use super::*;
117118

118119
pub use crate::p256::Nonce;

ed25519/src/impl_signature_trait.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ pub mod signers {
2626
payload
2727
.len()
2828
.try_into()
29-
.map_err(|_| SignError::InvalidPayloadLength)?,
29+
.map_err(|_| SignError::InvalidArgument)?,
3030
payload,
3131
);
3232

libcrux-ml-dsa/src/impl_signature_trait.rs

Lines changed: 76 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,36 +10,93 @@ pub mod signers {
1010
///
1111
/// Can be implemented using the convenience macro [`impl_context`].
1212
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+
1318
/// Return the context.
14-
fn context() -> &'static [u8];
19+
fn context() -> &'static Self::Buf;
1520
}
1621

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+
1772
#[macro_export]
1873
/// 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]`.
2075
///
2176
/// Usage:
2277
/// ```rust
2378
/// use libcrux_ml_dsa::signers::{Context, impl_context};
24-
/// impl_context!(AppContext, b"context");
79+
/// impl_context!(AppContext, b"context", 7);
2580
/// ```
2681
macro_rules! impl_context {
27-
($name:ident, $context:literal) => {
82+
($name:ident, $context:literal,$len:expr) => {
2883
impl_context!(
2984
$name,
3085
$context,
86+
$len,
3187
concat!(
3288
"An ML-DSA signing context that contains \"",
3389
stringify!($context),
3490
"\"."
3591
)
3692
)
3793
};
38-
($name:ident, $context:literal, $doc:expr) => {
94+
($name:ident, $context:literal, $len:expr, $doc:expr) => {
3995
#[doc = $doc]
4096
pub struct $name;
4197
impl Context for $name {
42-
fn context() -> &'static [u8] {
98+
type Buf = [u8; $len];
99+
fn context() -> &'static [u8; $len] {
43100
$context
44101
}
45102
}
@@ -68,7 +125,7 @@ pub mod signers {
68125
///
69126
/// It is the responsibility of the caller to ensure that the `randomness` argument is actually
70127
/// random.
71-
impl<T: Context>
128+
impl<const N: usize, T: Context<Buf= [u8;N]>>
72129
arrayref::Sign<
73130
SIGNING_KEY_LEN,
74131
VERIFICATION_KEY_LEN,
@@ -91,7 +148,11 @@ pub mod signers {
91148
randomness.declassify(),
92149
signature
93150
)
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+
})
95156
}
96157
/// Verify a signature using a provided verification key and context.
97158
fn verify(
@@ -105,7 +166,13 @@ pub mod signers {
105166
T::context(),
106167
signature,
107168
)
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+
})
109176
}
110177

111178
fn keygen_derand(

traits/src/signature/arrayref.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -118,16 +118,21 @@ pub trait Sign<
118118
/// input parameters to internal library errors.
119119
#[derive(Debug, PartialEq, Eq)]
120120
pub enum SignError {
121-
/// The length of the provided payload is invalid for this signature algorithm.
122-
InvalidPayloadLength,
121+
/// The the provided argument is invalid for this signature algorithm.
122+
/// It could be that the payload is too long.
123+
InvalidArgument,
124+
/// The random value provided is not suitable. For rejection sampling, try again with new
125+
/// randomness.
126+
InvalidRandomness,
123127
/// An internal library error occurred during the signing operation.
124128
LibraryError,
125129
}
126130

127131
impl core::fmt::Display for SignError {
128132
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
129133
let text = match self {
130-
SignError::InvalidPayloadLength => "the length of the provided payload is invalid",
134+
SignError::InvalidArgument => "a provided argument is invalid",
135+
SignError::InvalidRandomness => "the provided randomness is unsuitable",
131136
SignError::LibraryError => "indicates a library error",
132137
};
133138

@@ -143,8 +148,6 @@ impl core::fmt::Display for SignError {
143148
pub enum VerifyError {
144149
/// The provided signature is cryptographically invalid or does not match the payload.
145150
InvalidSignature,
146-
/// The length of the provided signature buffer is invalid for this algorithm.
147-
InvalidSignatureBufferLength,
148151
/// The length of the provided payload is invalid for this signature algorithm.
149152
InvalidPayloadLength,
150153
/// An internal library error occurred during verification.
@@ -155,9 +158,6 @@ impl core::fmt::Display for VerifyError {
155158
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
156159
let text = match self {
157160
VerifyError::InvalidSignature => "the provided signature is invalid",
158-
VerifyError::InvalidSignatureBufferLength => {
159-
"the length of the provided signature buffer is invalid"
160-
}
161161
VerifyError::InvalidPayloadLength => "the length of the provided payload is invalid",
162162
VerifyError::LibraryError => "indicates a library error",
163163
};

traits/src/signature/slice.rs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,12 @@ pub enum SignError {
103103
InvalidSigningKeyLength,
104104
/// The length of the provided signature output buffer is invalid.
105105
InvalidSignatureBufferLength,
106-
/// The length of the provided payload is invalid for this signature algorithm.
107-
InvalidPayloadLength,
106+
/// The the provided argument is invalid for this signature algorithm.
107+
/// It could be that the payload is too long.
108+
InvalidArgument,
109+
/// The random value provided is not suitable. For rejection sampling, try again with new
110+
/// randomness.
111+
InvalidRandomness,
108112
/// An internal library error occurred during the signing operation.
109113
LibraryError,
110114
}
@@ -118,7 +122,8 @@ impl core::fmt::Display for SignError {
118122
SignError::InvalidSignatureBufferLength => {
119123
"the length of the provided signature buffer is invalid"
120124
}
121-
SignError::InvalidPayloadLength => "the length of the provided payload is invalid",
125+
SignError::InvalidArgument => "a provided argument is invalid",
126+
SignError::InvalidRandomness => "the provided randomness is unsuitable",
122127
SignError::LibraryError => "indicates a library error",
123128
};
124129

@@ -206,7 +211,8 @@ mod error_in_core {
206211
impl From<super::arrayref::SignError> for SignError {
207212
fn from(e: super::arrayref::SignError) -> Self {
208213
match e {
209-
super::arrayref::SignError::InvalidPayloadLength => Self::InvalidPayloadLength,
214+
super::arrayref::SignError::InvalidArgument => Self::InvalidArgument,
215+
super::arrayref::SignError::InvalidRandomness => Self::InvalidRandomness,
210216
super::arrayref::SignError::LibraryError => Self::LibraryError,
211217
}
212218
}
@@ -215,9 +221,6 @@ impl From<super::arrayref::VerifyError> for VerifyError {
215221
fn from(e: super::arrayref::VerifyError) -> Self {
216222
match e {
217223
super::arrayref::VerifyError::InvalidSignature => Self::InvalidSignature,
218-
super::arrayref::VerifyError::InvalidSignatureBufferLength => {
219-
Self::InvalidSignatureBufferLength
220-
}
221224
super::arrayref::VerifyError::InvalidPayloadLength => Self::InvalidPayloadLength,
222225
super::arrayref::VerifyError::LibraryError => Self::LibraryError,
223226
}

0 commit comments

Comments
 (0)