Skip to content

Commit 957627f

Browse files
committed
feat: add from_be_bytes_mod_order to facilitate hash_to_field implementation
1 parent 6646be1 commit 957627f

1 file changed

Lines changed: 43 additions & 0 deletions

File tree

src/scalar.rs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -569,6 +569,23 @@ impl Scalar {
569569
Self::from_bytes_le(&le_bytes)
570570
}
571571

572+
/// Interprets `bytes` as a big-endian integer of any length and reduces it modulo the
573+
/// group order.
574+
pub fn from_be_bytes_mod_order(bytes: &[u8]) -> Self {
575+
// necessary because `blst_scalar_from_be_bytes` below does not work for this value
576+
if bytes.is_empty() {
577+
return Self::ZERO;
578+
}
579+
580+
let mut raw = blst_scalar::default();
581+
unsafe { blst_scalar_from_be_bytes(&mut raw, bytes.as_ptr(), bytes.len()) };
582+
583+
let mut out = blst_fr::default();
584+
unsafe { blst_fr_from_scalar(&mut out, &raw) };
585+
586+
Scalar(out)
587+
}
588+
572589
/// Converts an element of `Scalar` into a byte representation in
573590
/// little-endian byte order.
574591
#[inline]
@@ -1895,4 +1912,30 @@ mod tests {
18951912
}
18961913
assert_eq!(0, yep_bad.len());
18971914
}
1915+
1916+
/// Vectors from `bls12_381`'s `map_scalar`. These pin the endianness; blst covers the
1917+
/// reduction itself.
1918+
#[test]
1919+
fn test_from_be_bytes_mod_order() {
1920+
let vectors: &[(&[u8], &str)] = &[
1921+
(
1922+
b"aaaaaabbbbbbccccccddddddeeeeeeffffffgggggghhhhhh",
1923+
"Scalar(0x2228450bf55d8fe62395161bd3677ff6fc28e45b89bc87e02a818eda11a8c5da)",
1924+
),
1925+
(
1926+
b"111111222222333333444444555555666666777777888888",
1927+
"Scalar(0x4aa543cbd2f0c8f37f8a375ce2e383eb343e7e3405f61e438b0a15fb8899d1ae)",
1928+
),
1929+
];
1930+
1931+
for (okm, expected) in vectors {
1932+
assert_eq!(
1933+
&format!("{:?}", Scalar::from_be_bytes_mod_order(okm)),
1934+
expected
1935+
);
1936+
}
1937+
1938+
// The empty-input guard is ours: blst would underflow its digit count.
1939+
assert_eq!(Scalar::from_be_bytes_mod_order(&[]), Scalar::ZERO);
1940+
}
18981941
}

0 commit comments

Comments
 (0)