Skip to content

Commit

Permalink
Refactor and rename Scalar::from_bytes_wide
Browse files Browse the repository at this point in the history
It now used a 512-bit large destination string to hash into.
New name: `hash_to_scalar`.

Resolves #137
Co-authored_by: Victor Lopez <[email protected]>
  • Loading branch information
moCello committed Dec 5, 2023
1 parent 6d187b0 commit c8e17a3
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 26 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- Add `from_var_bytes` to scalar [#133]
- Add `from_var_bytes` to scalar [#133] and refactor and rename to `hash_to_scalar` [#137]

## [0.12.3] - 2023-11-01

Expand Down Expand Up @@ -228,6 +228,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Rename `S` to `TWO_ADACITY` and export it

<!-- Issues -->
[#137]: https://github.com/dusk-network/bls12_381/issues/137
[#135]: https://github.com/dusk-network/bls12_381/issues/135
[#133]: https://github.com/dusk-network/bls12_381/issues/133
[#125]: https://github.com/dusk-network/bls12_381/issues/125
Expand Down
58 changes: 33 additions & 25 deletions src/scalar/dusk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ use core::convert::TryFrom;
use core::hash::{Hash, Hasher};
use core::ops::{BitAnd, BitXor};
use dusk_bytes::{Error as BytesError, Serializable};
use rand_core::{CryptoRng, RngCore};
use subtle::{Choice, ConditionallySelectable, ConstantTimeEq};

use super::{Scalar, MODULUS, R2};
Expand Down Expand Up @@ -262,34 +261,43 @@ impl Scalar {
res
}

/// Creates a `Scalar` from arbitrary bytes by hashing the input with BLAKE2b into a 256-bits
/// number, and then converting it into its `Scalar` representation.
pub fn from_var_bytes(input: &[u8]) -> Scalar {
/// Creates a `Scalar` from arbitrary bytes by hashing the input with
/// BLAKE2b into a 512-bits number, and then converting the number into its
/// `Scalar` representation by reducing it by the modulo.
///
/// By treating the output of the BLAKE2b hash as a random oracle, this
/// implementation follows the first conversion of
/// https://hackmd.io/zV6qe1_oSU-kYU6Tt7pO7Q with concrete numbers:
/// ```text
/// p = 0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001
/// p = 52435875175126190479447740508185965837690552500527637822603658699938581184513
///
/// s = 2^512
/// s = 13407807929942597099574024998205846127479365820592393377723561443721764030073546976801874298166903427690031858186486050853753882811946569946433649006084096
///
/// r = 255699135089535202043525422716183576215815630510683217819334674386498370757523
///
/// m = 3294906474794265442129797520630710739278575682199800681788903916070560242797
/// ```
pub fn hash_to_scalar(input: &[u8]) -> Scalar {
let state = blake2b_simd::Params::new()
.hash_length(32)
.hash_length(64)
.to_state()
.update(input)
.finalize();

let h = state.as_bytes();
let mut r = [0u64; 4];

// will be optmized by the compiler, depending on the available target
for i in 0..4 {
r[i] = u64::from_le_bytes([
h[i * 8],
h[i * 8 + 1],
h[i * 8 + 2],
h[i * 8 + 3],
h[i * 8 + 4],
h[i * 8 + 5],
h[i * 8 + 6],
h[i * 8 + 7],
]);
}

// `from_raw` converts from arbitrary to congruent scalar
Self::from_raw(r)
let bytes = state.as_bytes();

Scalar::from_u512([
u64::from_le_bytes(<[u8; 8]>::try_from(&bytes[0..8]).unwrap()),
u64::from_le_bytes(<[u8; 8]>::try_from(&bytes[8..16]).unwrap()),
u64::from_le_bytes(<[u8; 8]>::try_from(&bytes[16..24]).unwrap()),
u64::from_le_bytes(<[u8; 8]>::try_from(&bytes[24..32]).unwrap()),
u64::from_le_bytes(<[u8; 8]>::try_from(&bytes[32..40]).unwrap()),
u64::from_le_bytes(<[u8; 8]>::try_from(&bytes[40..48]).unwrap()),
u64::from_le_bytes(<[u8; 8]>::try_from(&bytes[48..56]).unwrap()),
u64::from_le_bytes(<[u8; 8]>::try_from(&bytes[56..64]).unwrap()),
])
}

/// SHR impl
Expand Down Expand Up @@ -462,7 +470,7 @@ mod fuzz {

quickcheck::quickcheck! {
fn prop_scalar_from_raw_bytes(bytes: Vec<u8>) -> bool {
let scalar = Scalar::from_var_bytes(&bytes);
let scalar = Scalar::hash_to_scalar(&bytes);

is_scalar_in_range(&scalar)
}
Expand Down

0 comments on commit c8e17a3

Please sign in to comment.