|
|
@@ -0,0 +1,35 @@
|
|
|
+//! The basepoints map is keyed by group type, so two groups must be able
|
|
|
+//! to coexist in one process.
|
|
|
+//!
|
|
|
+//! Before the key was `G`, `StaticTypeMap::call_once` was handed
|
|
|
+//! `Box<dyn CMZbp>` — the same `TypeId` for every group — so the map held a
|
|
|
+//! single shared slot. The second group's `cmz_group_init` was silently
|
|
|
+//! ignored and the following `cmz_basepoints` read back the *first* group's
|
|
|
+//! basepoints, failing the downcast and panicking.
|
|
|
+
|
|
|
+use cmz::{cmz_basepoints, cmz_group_init};
|
|
|
+use curve25519_dalek::ristretto::RistrettoPoint;
|
|
|
+use group::Group;
|
|
|
+use sha2::Sha512;
|
|
|
+
|
|
|
+#[test]
|
|
|
+fn two_groups_coexist() {
|
|
|
+ let ristretto_a = RistrettoPoint::hash_from_bytes::<Sha512>(b"CMZ Generator A");
|
|
|
+ let p256_a = p256::ProjectivePoint::generator() * p256::Scalar::from(42u64);
|
|
|
+
|
|
|
+ cmz_group_init::<RistrettoPoint>(ristretto_a);
|
|
|
+ cmz_group_init::<p256::ProjectivePoint>(p256_a);
|
|
|
+
|
|
|
+ // Each group must read back its own basepoints, not the other's.
|
|
|
+ assert_eq!(cmz_basepoints::<RistrettoPoint>().A(), ristretto_a);
|
|
|
+ assert_eq!(cmz_basepoints::<RistrettoPoint>().B(), RistrettoPoint::generator());
|
|
|
+ assert_eq!(cmz_basepoints::<p256::ProjectivePoint>().A(), p256_a);
|
|
|
+ assert_eq!(
|
|
|
+ cmz_basepoints::<p256::ProjectivePoint>().B(),
|
|
|
+ p256::ProjectivePoint::generator()
|
|
|
+ );
|
|
|
+
|
|
|
+ // Re-initializing keeps the first value, per cmz_group_init's contract.
|
|
|
+ cmz_group_init::<RistrettoPoint>(RistrettoPoint::generator());
|
|
|
+ assert_eq!(cmz_basepoints::<RistrettoPoint>().A(), ristretto_a);
|
|
|
+}
|