Skip to content

Commit 73c8245

Browse files
authored
srp: DRY out monty_form (#243)
Perhaps the upstream behavior should be changed to match
1 parent 8e47ede commit 73c8245

File tree

3 files changed

+42
-38
lines changed

3 files changed

+42
-38
lines changed

srp/src/client.rs

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@ use subtle::ConstantTimeEq;
77
use crate::{
88
Group,
99
errors::AuthError,
10-
utils::{compute_hash, compute_k, compute_m1, compute_m1_rfc5054, compute_m2, compute_u},
10+
utils::{
11+
compute_hash, compute_k, compute_m1_legacy, compute_m1_rfc5054, compute_m2, compute_u,
12+
monty_form,
13+
},
1114
};
1215

1316
/// SRP client implementation.
@@ -179,8 +182,8 @@ impl<G: Group, D: Digest> Client<G, D> {
179182
a: &BoxedUint,
180183
u: &BoxedUint,
181184
) -> BoxedUint {
182-
let b_pub = self.monty_form(b_pub);
183-
let k = self.monty_form(k);
185+
let b_pub = monty_form(b_pub, self.g.params());
186+
let k = monty_form(k, self.g.params());
184187

185188
// B - kg^x
186189
let base = b_pub - k * self.g.pow(x);
@@ -292,7 +295,7 @@ impl<G: Group, D: Digest> Client<G, D> {
292295
.to_be_bytes_trimmed_vartime()
293296
.to_vec();
294297

295-
let m1 = compute_m1::<D>(&a_pub_bytes, b_pub_bytes, &key);
298+
let m1 = compute_m1_legacy::<D>(&a_pub_bytes, b_pub_bytes, &key);
296299
let m2 = compute_m2::<D>(&a_pub_bytes, &m1, &key);
297300
Ok(LegacyClientVerifier { m1, m2, key })
298301
}
@@ -302,12 +305,6 @@ impl<G: Group, D: Digest> Client<G, D> {
302305
if self.username_in_x { username } else { &[] }
303306
}
304307

305-
/// Convert an integer into the Montgomery domain, returning a [`BoxedMontyForm`] modulo `N`.
306-
fn monty_form(&self, x: &BoxedUint) -> BoxedMontyForm {
307-
let precision = self.n().bits_precision();
308-
BoxedMontyForm::new(x.resize(precision), self.g.params())
309-
}
310-
311308
/// Get the modulus `N`.
312309
fn n(&self) -> &Odd<BoxedUint> {
313310
self.g.params().modulus()

srp/src/server.rs

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@ use subtle::ConstantTimeEq;
77
use crate::{
88
Group,
99
errors::AuthError,
10-
utils::{compute_hash, compute_k, compute_m1, compute_m1_rfc5054, compute_m2, compute_u},
10+
utils::{
11+
compute_hash, compute_k, compute_m1_legacy, compute_m1_rfc5054, compute_m2, compute_u,
12+
monty_form,
13+
},
1114
};
1215

1316
/// SRP server implementation.
@@ -105,8 +108,8 @@ impl<G: Group, D: Digest> Server<G, D> {
105108
/// Compute the server's public ephemeral: `k*v + g^b % N`.
106109
#[must_use]
107110
pub fn compute_b_pub(&self, b: &BoxedUint, k: &BoxedUint, v: &BoxedUint) -> BoxedUint {
108-
let k = self.monty_form(k);
109-
let v = self.monty_form(v);
111+
let k = monty_form(k, self.g.params());
112+
let v = monty_form(v, self.g.params());
110113
(k * v + self.g.pow(b)).retrieve()
111114
}
112115

@@ -119,8 +122,8 @@ impl<G: Group, D: Digest> Server<G, D> {
119122
u: &BoxedUint,
120123
b: &BoxedUint,
121124
) -> BoxedUint {
122-
let a_pub = self.monty_form(a_pub);
123-
let v = self.monty_form(v);
125+
let a_pub = monty_form(a_pub, self.g.params());
126+
let v = monty_form(v, self.g.params());
124127

125128
// (A * v^u)
126129
(a_pub * v.pow(u)).pow(b).retrieve()
@@ -223,7 +226,7 @@ impl<G: Group, D: Digest> Server<G, D> {
223226

224227
let key = self.compute_premaster_secret(&a_pub, &v, &u, &b);
225228

226-
let m1 = compute_m1::<D>(
229+
let m1 = compute_m1_legacy::<D>(
227230
a_pub_bytes,
228231
&b_pub_bytes,
229232
&key.to_be_bytes_trimmed_vartime(),
@@ -238,12 +241,6 @@ impl<G: Group, D: Digest> Server<G, D> {
238241
})
239242
}
240243

241-
/// Convert an integer into the Montgomery domain, returning a [`BoxedMontyForm`] modulo `N`.
242-
fn monty_form(&self, x: &BoxedUint) -> BoxedMontyForm {
243-
let precision = self.n().bits_precision();
244-
BoxedMontyForm::new(x.resize(precision), self.g.params())
245-
}
246-
247244
/// Get the modulus `N`.
248245
fn n(&self) -> &Odd<BoxedUint> {
249246
self.g.params().modulus()

srp/src/utils.rs

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
use alloc::vec::Vec;
2-
use crypto_bigint::{BoxedUint, modular::BoxedMontyForm};
2+
use crypto_bigint::{
3+
BoxedUint, Resize,
4+
modular::{BoxedMontyForm, BoxedMontyParams},
5+
};
36
use digest::{Digest, Output};
47

5-
// u = H(PAD(A) | PAD(B))
8+
/// `u = H(PAD(A) | PAD(B))`
69
#[must_use]
710
pub fn compute_u<D: Digest>(a_pub: &[u8], b_pub: &[u8]) -> BoxedUint {
811
let mut u = D::new();
@@ -11,7 +14,7 @@ pub fn compute_u<D: Digest>(a_pub: &[u8], b_pub: &[u8]) -> BoxedUint {
1114
BoxedUint::from_be_slice_vartime(&u.finalize())
1215
}
1316

14-
// k = H(N | PAD(g))
17+
/// `k = H(N | PAD(g))`
1518
#[must_use]
1619
pub fn compute_k<D: Digest>(g: &BoxedMontyForm) -> BoxedUint {
1720
let n = g.params().modulus().to_be_bytes();
@@ -26,7 +29,7 @@ pub fn compute_k<D: Digest>(g: &BoxedMontyForm) -> BoxedUint {
2629
BoxedUint::from_be_slice_vartime(d.finalize().as_slice())
2730
}
2831

29-
// H(N) XOR H(PAD(g))
32+
/// `H(N) XOR H(PAD(g))`
3033
#[must_use]
3134
pub fn compute_hash_n_xor_hash_g<D: Digest>(g: &BoxedMontyForm) -> Vec<u8> {
3235
let n = g.params().modulus().to_be_bytes();
@@ -44,24 +47,14 @@ pub fn compute_hash_n_xor_hash_g<D: Digest>(g: &BoxedMontyForm) -> Vec<u8> {
4447
.collect()
4548
}
4649

47-
// M1 = H(A, B, K) this doesn't follow the spec but apparently no one does for M1
48-
#[must_use]
49-
pub fn compute_m1<D: Digest>(a_pub: &[u8], b_pub: &[u8], key: &[u8]) -> Output<D> {
50-
let mut d = D::new();
51-
d.update(a_pub);
52-
d.update(b_pub);
53-
d.update(key);
54-
d.finalize()
55-
}
56-
5750
#[must_use]
5851
pub fn compute_hash<D: Digest>(data: &[u8]) -> Output<D> {
5952
let mut d = D::new();
6053
d.update(data);
6154
d.finalize()
6255
}
6356

64-
// M1 = H(H(N) XOR H(g) | H(U) | s | A | B | K) following RFC5054
57+
/// `M1 = H(H(N) XOR H(g) | H(U) | s | A | B | K)` following RFC5054
6558
#[must_use]
6659
pub fn compute_m1_rfc5054<D: Digest>(
6760
g: &BoxedMontyForm,
@@ -81,7 +74,17 @@ pub fn compute_m1_rfc5054<D: Digest>(
8174
d.finalize()
8275
}
8376

84-
// M2 = H(A, M1, K)
77+
/// `M1 = H(A, B, K)`
78+
#[must_use]
79+
pub fn compute_m1_legacy<D: Digest>(a_pub: &[u8], b_pub: &[u8], key: &[u8]) -> Output<D> {
80+
let mut d = D::new();
81+
d.update(a_pub);
82+
d.update(b_pub);
83+
d.update(key);
84+
d.finalize()
85+
}
86+
87+
/// `M2 = H(A, M1, K)`
8588
#[must_use]
8689
pub fn compute_m2<D: Digest>(a_pub: &[u8], m1: &Output<D>, key: &[u8]) -> Output<D> {
8790
let mut d = D::new();
@@ -90,3 +93,10 @@ pub fn compute_m2<D: Digest>(a_pub: &[u8], m1: &Output<D>, key: &[u8]) -> Output
9093
d.update(key);
9194
d.finalize()
9295
}
96+
97+
/// Convert the given value into Montgomery form, resizing it in the process.
98+
/// Convert an integer into the Montgomery domain, returning a [`BoxedMontyForm`] modulo `N`.
99+
pub(crate) fn monty_form(x: &BoxedUint, n: &BoxedMontyParams) -> BoxedMontyForm {
100+
let precision = n.modulus().bits_precision();
101+
BoxedMontyForm::new(x.resize(precision), n)
102+
}

0 commit comments

Comments
 (0)