diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 5bea3c0..88992cf 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -22,7 +22,7 @@ jobs:
strategy:
matrix:
rust:
- - 1.73.0 # MSRV
+ - 1.72.0 # MSRV is 1.70, but GA flaky
- stable
target:
- thumbv7em-none-eabi
@@ -48,7 +48,7 @@ jobs:
include:
# 32-bit Linux
- target: i686-unknown-linux-gnu
- rust: 1.73.0 # MSRV
+ rust: 1.72.0 # MSRV is 1.70, but GA flaky
deps: sudo apt update && sudo apt install gcc-multilib
- target: i686-unknown-linux-gnu
rust: stable
@@ -56,7 +56,7 @@ jobs:
# 64-bit Linux
- target: x86_64-unknown-linux-gnu
- rust: 1.73.0 # MSRV
+ rust: 1.72.0 # MSRV is 1.70, but GA flaky
- target: x86_64-unknown-linux-gnu
rust: stable
steps:
@@ -76,17 +76,17 @@ jobs:
include:
# ARM32
- target: armv7-unknown-linux-gnueabihf
- rust: 1.73.0 # MSRV (cross)
+ rust: 1.72.0 # MSRV is 1.70, but GA flaky
- target: armv7-unknown-linux-gnueabihf
rust: stable
# ARM64
- target: aarch64-unknown-linux-gnu
- rust: 1.73.0 # MSRV (cross)
+ rust: 1.72.0 # MSRV is 1.70, but GA flaky
- target: aarch64-unknown-linux-gnu
rust: stable
# PPC32
- target: powerpc-unknown-linux-gnu
- rust: 1.73.0 # MSRV (cross)
+ rust: 1.72.0 # MSRV (cross)
- target: powerpc-unknown-linux-gnu
rust: stable
runs-on: ubuntu-latest
diff --git a/Cargo.toml b/Cargo.toml
index 23670a6..19da0e0 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "fips205"
-version = "0.1.1"
+version = "0.1.2"
edition = "2021"
license = "MIT OR Apache-2.0"
description = "FIPS 205 (draft): Stateless Hash-Based Digital Signature Standard"
diff --git a/README.md b/README.md
index 788dc5b..2e7cd7a 100644
--- a/README.md
+++ b/README.md
@@ -53,7 +53,7 @@ The Rust [Documentation][docs-link] lives under each **Module** corresponding to
* This crate is fully functional and corresponds to the first initial public draft of FIPS 205.
* Constant-time assurances target the source-code level only, and are a work in progress.
* Note that FIPS 205 places specific requirements on randomness per section 3.1, hence the exposed `RNG`.
-* Requires Rust **1.73** or higher due to `div_ceil()`. The minimum supported Rust version may be changed
+* Requires Rust **1.70** or higher due to `div_ceil()`. The minimum supported Rust version may be changed
in the future, but it will be done with a minor version bump.
* All on-by-default features of this library are covered by SemVer.
* This software is experimental and still under active development -- USE AT YOUR OWN RISK!
diff --git a/src/helpers.rs b/src/helpers.rs
index ab2ecdd..34b3905 100644
--- a/src/helpers.rs
+++ b/src/helpers.rs
@@ -66,7 +66,7 @@ pub(crate) fn to_byte(x: u32, n: u32) -> [u8; ((crate::LEN2 * crate::LGW + 7) /
/// Input: Byte string `X` of length at least `ceil(out_len·b/8)`, integer `b`, output length `out_len`.
/// Output: Array of `out_len` integers in the range `[0, . . . , 2^b − 1]`.
pub(crate) fn base_2b(x: &[u8], b: u32, out_len: u32, baseb: &mut [u32]) {
- debug_assert!(x.len() >= (out_len * b).div_ceil(8) as usize);
+ debug_assert!(x.len() >= ((out_len * b + 7) / 8) as usize);
debug_assert!(b < 16); // Consider optimizing `baseb` output to be u16
debug_assert_eq!(out_len as usize, baseb.len());
diff --git a/src/slh.rs b/src/slh.rs
index 61823fd..56190f2 100644
--- a/src/slh.rs
+++ b/src/slh.rs
@@ -112,25 +112,25 @@ pub(crate) fn slh_sign_with_rng<
let digest = (hashers.h_msg)(&r, &sk.pk_seed, &sk.pk_root, m);
// 11: md ← digest[0 : ceil(k·a/8)] ▷ first ceil(k·a/8) bytes
- let index1 = (K::to_usize() * A::to_usize()).div_ceil(8);
+ let index1 = (K::to_usize() * A::to_usize() + 7) / 8;
let md = &digest[0..index1];
// 12: tmp_idx_tree ← digest[ceil(k·a/8) : ceil(k·a/8) + ceil((h-h/d)/8)] ▷ next ceil((h-h/d)/8) bytes
- let index2 = index1 + (H::to_usize() - H::to_usize() / D::to_usize()).div_ceil(8);
+ let index2 = index1 + (H::to_usize() - H::to_usize() / D::to_usize() + 7) / 8;
let tmp_idx_tree = &digest[index1..index2];
// 13: tmp_idx_leaf ← digest[ceil(k·a/8) + ceil((h-h/d)/8) : ceil(k·a/8) + ceil((h-h/d)/8) + ceil(h/8d)] ▷ next ceil(h/8d) bytes
- let index3 = index2 + H::to_usize().div_ceil(8 * D::to_usize());
+ let index3 = index2 + (H::to_usize() + 8 * D::to_usize() - 1) / (8 * D::to_usize());
let tmp_idx_leaf = &digest[index2..index3];
// 14:
// 15: idx_tree ← toInt(tmp_idx_tree, ceil((h-h/d)/8)) mod 2^{h−h/d}
let idx_tree =
- helpers::to_int(tmp_idx_tree, (H::to_u32() - H::to_u32() / D::to_u32()).div_ceil(8))
+ helpers::to_int(tmp_idx_tree, (H::to_u32() - H::to_u32() / D::to_u32() + 7) / 8)
& (u64::MAX >> (64 - (H::to_u32() - H::to_u32() / D::to_u32())));
// 16: idx_leaf ← toInt(tmp_idx_leaf, ceil(h/8d) mod 2^{h/d}
- let idx_leaf = helpers::to_int(tmp_idx_leaf, H::to_u32().div_ceil(8 * D::to_u32()))
+ let idx_leaf = helpers::to_int(tmp_idx_leaf, (H::to_u32() + 8 * D::to_u32() - 1) / (8 * D::to_u32()))
& (u64::MAX >> (64 - H::to_u32() / D::to_u32()));
// 17:
@@ -210,25 +210,25 @@ pub(crate) fn slh_verify<
let digest = (hashers.h_msg)(r, &pk.pk_seed, &pk.pk_root, m);
// 10: md ← digest[0 : ceil(k·a/8)] ▷ first ceil(k·a/8) bytes
- let index1 = (K::to_usize() * A::to_usize()).div_ceil(8);
+ let index1 = (K::to_usize() * A::to_usize() + 7) / 8;
let md = &digest[0..index1];
// 11: tmp_idx_tree ← digest[ceil(k·a/8) : ceil(k·a/8) + ceil((h - h/d)/8)] ▷ next ceil((h - h/d)/8) bytes
- let index2 = index1 + (H::to_usize() - H::to_usize() / D::to_usize()).div_ceil(8);
+ let index2 = index1 + (H::to_usize() - H::to_usize() / D::to_usize() + 7) / 8;
let tmp_idx_tree = &digest[index1..index2];
// 12: tmp_idx_leaf ← digest[ceil(k·a/8) + ceil((h - h/d)/8) : ceil(k·a/8) + ceil((h - h/d)/8) + ceil(h/8d)] ▷ next ceil(h/8d) bytes
- let index3 = index2 + H::to_usize().div_ceil(8 * D::to_usize());
+ let index3 = index2 + (H::to_usize() + 8 * D::to_usize() - 1) / (8 * D::to_usize());
let tmp_idx_leaf = &digest[index2..index3];
// 13:
// 14: idx_tree ← toInt(tmp_idx_tree, ceil((h - h/d)/8)) mod 2^{h−h/d}
let idx_tree =
- helpers::to_int(tmp_idx_tree, (H::to_u32() - H::to_u32() / D::to_u32()).div_ceil(8))
+ helpers::to_int(tmp_idx_tree, (H::to_u32() - H::to_u32() / D::to_u32() + 7) /8)
& (u64::MAX >> (64 - (H::to_u32() - H::to_u32() / D::to_u32())));
// 15: idx_leaf ← toInt(tmp_idx_leaf, ceil(h/8d) mod 2^{h/d}
- let idx_leaf = helpers::to_int(tmp_idx_leaf, H::to_u32().div_ceil(8 * D::to_u32()))
+ let idx_leaf = helpers::to_int(tmp_idx_leaf, (H::to_u32() + 8 * D::to_u32() - 1) / (8 * D::to_u32()))
& (u64::MAX >> (64 - H::to_u32() / D::to_u32()));
// 16:
diff --git a/src/wots.rs b/src/wots.rs
index ab47bbe..0f1c1e5 100644
--- a/src/wots.rs
+++ b/src/wots.rs
@@ -148,7 +148,7 @@ pub(crate) fn wots_sign