Skip to content

Commit 401887a

Browse files
authored
streebog: fix bit-length counter carry propagation to 512-bit (#759)
The update_n() implementation propagated carry only through limbs 1..6, effectively making n a 448-bit counter. According to GOST R 34.11-2012 (RFC 6986), the total processed bit-length must be tracked modulo 2^512. This change extends the loop to include limb 7 so carry ripples through all eight 64-bit words and any further carry is discarded, thus restoring correct modulo 2^512 semantics. Although this bug only manifests for astronomically large inputs, it is a correctness issue and brings the implementation in line with the specification and the behavior of similar counters in this codebase.
1 parent 44b2e75 commit 401887a

File tree

1 file changed

+37
-1
lines changed

1 file changed

+37
-1
lines changed

streebog/src/block_api.rs

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ impl StreebogVarCore {
7777
let mut carry = false;
7878
// Note: `len` can not be bigger than block size, so `8 * len` never overflows
7979
adc(&mut self.n[0], 8 * len, &mut carry);
80-
for i in 1..7 {
80+
for i in 1..8 {
8181
adc(&mut self.n[i], 0, &mut carry);
8282
}
8383
}
@@ -217,3 +217,39 @@ fn from_bytes(b: &Block) -> [u64; 8] {
217217
}
218218
t
219219
}
220+
221+
#[cfg(test)]
222+
mod tests {
223+
use super::*;
224+
225+
#[test]
226+
fn counter_carry_propagates_to_top_limb() {
227+
let mut core = StreebogVarCore {
228+
h: [0u64; 8],
229+
n: [0u64; 8],
230+
sigma: [0u64; 8],
231+
};
232+
core.n[0] = u64::MAX - 511;
233+
for i in 1..=6 {
234+
core.n[i] = u64::MAX;
235+
}
236+
core.n[7] = 0;
237+
core.update_n(64);
238+
for i in 0..=6 {
239+
assert_eq!(core.n[i], 0);
240+
}
241+
assert_eq!(core.n[7], 1);
242+
}
243+
244+
#[test]
245+
fn counter_zero_len_no_change() {
246+
let mut core = StreebogVarCore {
247+
h: [0u64; 8],
248+
n: [1, 2, 3, 4, 5, 6, 7, 8],
249+
sigma: [0u64; 8],
250+
};
251+
let before = core.n;
252+
core.update_n(0);
253+
assert_eq!(core.n, before);
254+
}
255+
}

0 commit comments

Comments
 (0)