Skip to content

Commit

Permalink
Merge pull request #127 from dusk-network/scalar-hash-equality
Browse files Browse the repository at this point in the history
Add hash implementation to scalar
  • Loading branch information
HDauven authored Oct 30, 2023
2 parents 7990d15 + 6b5716c commit 3ebde2e
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 1 deletion.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- Add `uni_random` scalar generation [#125]

### Changed

- Change `Hash` derive on `Scalar` to explicit implementation [#106]

## [0.12.2] - 2023-10-11

### Fixed
Expand Down Expand Up @@ -218,6 +222,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
[#117]: https://github.com/dusk-network/bls12_381/issues/117
[#109]: https://github.com/dusk-network/bls12_381/issues/109
[#108]: https://github.com/dusk-network/bls12_381/issues/108
[#106]: https://github.com/dusk-network/bls12_381/issues/106
[#100]: https://github.com/dusk-network/bls12_381/issues/100
[#93]: https://github.com/dusk-network/bls12_381/issues/93
[#75]: https://github.com/dusk-network/bls12_381/issues/75
Expand Down
2 changes: 1 addition & 1 deletion src/scalar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use rkyv::{Archive, Deserialize as RkyvDeserialize, Serialize as RkyvSerialize};
// The internal representation of this type is four 64-bit unsigned
// integers in little-endian order. `Scalar` values are always in
// Montgomery form; i.e., Scalar(a) = aR mod q, with R = 2^256.
#[derive(Clone, Copy, Eq, Hash)]
#[derive(Clone, Copy, Eq)]
#[cfg_attr(
feature = "rkyv-impl",
derive(Archive, RkyvSerialize, RkyvDeserialize),
Expand Down
39 changes: 39 additions & 0 deletions src/scalar/dusk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use core::cmp::{Ord, Ordering, PartialOrd};
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};
Expand Down Expand Up @@ -205,6 +206,13 @@ impl<'a, 'b> BitAnd<&'b Scalar> for &'a Scalar {
}
}

impl Hash for Scalar {
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
self.0.hash(state);
}
}

impl Scalar {
/// Checks in ct_time whether a Scalar is equal to zero.
pub fn is_zero(&self) -> Choice {
Expand Down Expand Up @@ -407,3 +415,34 @@ fn pow_of_two_test() {
assert_eq!(Scalar::pow_of_2(i as u64), two.pow(&[i as u64, 0, 0, 0]));
}
}

#[test]
fn test_scalar_eq_and_hash() {
use sha3::{Digest, Keccak256};

let r0 = Scalar::from_raw([
0x1fff_3231_233f_fffd,
0x4884_b7fa_0003_4802,
0x998c_4fef_ecbc_4ff3,
0x1824_b159_acc5_0562,
]);
let r1 = Scalar::from_raw([
0x1fff_3231_233f_fffd,
0x4884_b7fa_0003_4802,
0x998c_4fef_ecbc_4ff3,
0x1824_b159_acc5_0562,
]);
let r2 = Scalar::from(7);

// Check PartialEq
assert!(r0 == r1);
assert!(r0 != r2);

let hash_r0 = Keccak256::digest(&r0.to_bytes());
let hash_r1 = Keccak256::digest(&r1.to_bytes());
let hash_r2 = Keccak256::digest(&r2.to_bytes());

// Check if hash results are consistent with PartialEq results
assert_eq!(hash_r0, hash_r1);
assert_ne!(hash_r0, hash_r2);
}

0 comments on commit 3ebde2e

Please sign in to comment.