Skip to content

Commit 721637b

Browse files
committed
Limit SharedSecret to 32 byte buffer
The `SharedSecret` uses sha256 to hash the secret, this implies the secret is 32 bytes of data. Currently we use a buffer of 256 bytes, this seems to be unneeded. Change the implementation to use a 32 byte buffer. This simplifies the API and implementation quite considerably.
1 parent 3e815b7 commit 721637b

File tree

2 files changed

+15
-76
lines changed

2 files changed

+15
-76
lines changed

src/ecdh.rs

Lines changed: 15 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
//!
1818
1919
use core::ptr;
20-
use core::ops::{FnMut, Deref};
20+
use core::ops::FnMut;
2121

2222
use key::{SecretKey, PublicKey};
2323
use ffi::{self, CPtr};
@@ -40,75 +40,26 @@ use secp256k1_sys::types::{c_int, c_uchar, c_void};
4040
/// assert_eq!(sec1, sec2);
4141
/// # }
4242
// ```
43-
#[derive(Copy, Clone)]
44-
pub struct SharedSecret {
45-
data: [u8; 256],
46-
len: usize,
47-
}
48-
impl_raw_debug!(SharedSecret);
49-
50-
51-
// This implementes `From<N>` for all `[u8; N]` arrays from 128bits(16 byte) to 2048bits allowing known hash lengths.
52-
// Lower than 128 bits isn't resistant to collisions any more.
53-
impl_from_array_len!(SharedSecret, 256, (16 20 28 32 48 64 96 128 256));
43+
#[derive(Copy, Clone, Debug, PartialEq)]
44+
pub struct SharedSecret([u8; 32]);
5445

5546
impl SharedSecret {
56-
5747
/// Create an empty SharedSecret
5848
pub(crate) fn empty() -> SharedSecret {
59-
SharedSecret {
60-
data: [0u8; 256],
61-
len: 0,
62-
}
49+
SharedSecret([0u8; 32])
6350
}
6451

65-
/// Get a pointer to the underlying data with the specified capacity.
52+
/// Get a mutable pointer to the underlying data.
6653
pub(crate) fn get_data_mut_ptr(&mut self) -> *mut u8 {
67-
self.data.as_mut_ptr()
68-
}
69-
70-
/// Get the capacity of the underlying data buffer.
71-
pub fn capacity(&self) -> usize {
72-
self.data.len()
73-
}
74-
75-
/// Get the len of the used data.
76-
pub fn len(&self) -> usize {
77-
self.len
54+
self.0.as_mut_ptr()
7855
}
7956

8057
/// True if the underlying data buffer is empty.
8158
pub fn is_empty(&self) -> bool {
82-
self.data.is_empty()
83-
}
84-
85-
/// Set the length of the object.
86-
pub(crate) fn set_len(&mut self, len: usize) {
87-
debug_assert!(len <= self.data.len());
88-
self.len = len;
59+
self.0.is_empty()
8960
}
9061
}
9162

92-
impl PartialEq for SharedSecret {
93-
fn eq(&self, other: &SharedSecret) -> bool {
94-
self.as_ref() == other.as_ref()
95-
}
96-
}
97-
98-
impl AsRef<[u8]> for SharedSecret {
99-
fn as_ref(&self) -> &[u8] {
100-
&self.data[..self.len]
101-
}
102-
}
103-
104-
impl Deref for SharedSecret {
105-
type Target = [u8];
106-
fn deref(&self) -> &[u8] {
107-
&self.data[..self.len]
108-
}
109-
}
110-
111-
11263
unsafe extern "C" fn c_callback(output: *mut c_uchar, x: *const c_uchar, y: *const c_uchar, _data: *mut c_void) -> c_int {
11364
ptr::copy_nonoverlapping(x, output, 32);
11465
ptr::copy_nonoverlapping(y, output.offset(32), 32);
@@ -133,7 +84,6 @@ impl SharedSecret {
13384
// The default `secp256k1_ecdh_hash_function_default` should always return 1.
13485
// and the scalar was verified to be valid(0 > scalar > group_order) via the type system
13586
debug_assert_eq!(res, 1);
136-
ss.set_len(32); // The default hash function is SHA256, which is 32 bytes long.
13787
ss
13888
}
13989

@@ -184,6 +134,12 @@ impl SharedSecret {
184134
}
185135
}
186136

137+
impl From<[u8; 32]> for SharedSecret {
138+
fn from(inner: [u8; 32]) -> SharedSecret {
139+
SharedSecret(inner)
140+
}
141+
}
142+
187143
#[cfg(test)]
188144
#[allow(unused_imports)]
189145
mod tests {
@@ -227,15 +183,15 @@ mod tests {
227183
fn ecdh_with_hash_callback() {
228184
let s = Secp256k1::signing_only();
229185
let (sk1, pk1) = s.generate_keypair(&mut thread_rng());
230-
let expect_result: [u8; 64] = [123; 64];
186+
let expect_result: [u8; 32] = [123; 32];
231187
let mut x_out = [0u8; 32];
232188
let mut y_out = [0u8; 32];
233189
let result = SharedSecret::new_with_hash(&pk1, &sk1, |x, y| {
234190
x_out = x;
235191
y_out = y;
236192
expect_result.into()
237193
});
238-
assert_eq!(&expect_result[..], &result[..]);
194+
assert_eq!(&expect_result[..], &result.0[..]);
239195
assert_ne!(x_out, [0u8; 32]);
240196
assert_ne!(y_out, [0u8; 32]);
241197
}

src/macros.rs

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -26,20 +26,3 @@ macro_rules! impl_pretty_debug {
2626
}
2727
}
2828
}
29-
30-
macro_rules! impl_from_array_len {
31-
($thing:ident, $capacity:tt, ($($N:tt)+)) => {
32-
$(
33-
impl From<[u8; $N]> for $thing {
34-
fn from(arr: [u8; $N]) -> Self {
35-
let mut data = [0u8; $capacity];
36-
data[..$N].copy_from_slice(&arr);
37-
$thing {
38-
data,
39-
len: $N,
40-
}
41-
}
42-
}
43-
)+
44-
}
45-
}

0 commit comments

Comments
 (0)