Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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);
}