hotshot_contract_adapter/
stake_table.rs

1use ark_bn254::G2Affine;
2use ark_ec::AffineRepr;
3use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
4use hotshot_types::{light_client::StateVerKey, signature_key::BLSPubKey};
5
6use crate::sol_types::*;
7
8impl From<G2PointSol> for BLSPubKey {
9    fn from(value: G2PointSol) -> Self {
10        let point: G2Affine = value.into();
11        let mut bytes = vec![];
12        point
13            .into_group()
14            .serialize_uncompressed(&mut bytes)
15            .unwrap();
16        Self::deserialize_uncompressed(&bytes[..]).unwrap()
17    }
18}
19
20impl From<EdOnBN254PointSol> for StateVerKey {
21    fn from(value: EdOnBN254PointSol) -> Self {
22        let point: ark_ed_on_bn254::EdwardsAffine = value.into();
23        Self::from(point)
24    }
25}
26
27#[cfg(test)]
28mod test {
29    use hotshot_types::signature_key::{BLSPrivKey, BLSPubKey};
30
31    use crate::sol_types::G2PointSol;
32
33    fn check_round_trip(pk: BLSPubKey) {
34        let g2: G2PointSol = pk.to_affine().into();
35        let pk2: BLSPubKey = g2.into();
36        assert_eq!(pk2, pk, "Failed to roundtrip G2PointSol to BLSPubKey: {pk}");
37    }
38
39    #[test]
40    fn test_bls_g2_point_roundtrip() {
41        let mut rng = rand::thread_rng();
42        for _ in 0..100 {
43            let pk = (&BLSPrivKey::generate(&mut rng)).into();
44            check_round_trip(pk);
45        }
46    }
47
48    #[test]
49    fn test_bls_g2_point_alloy_migration_regression() {
50        // This pubkey fails the roundtrip if "serialize_{un,}compressed" are mixed
51        let s = "BLS_VER_KEY~JlRLUrn0T_MltAJXaaojwk_CnCgd0tyPny_IGdseMBLBPv9nWabIPAaS-aHmn0ARu5YZHJ7mfmGQ-alW42tkJM663Lse-Is80fyA1jnRxPsHcJDnO05oW1M1SC5LeE8sXITbuhmtG2JdTAgmLqWOxbMRmVIqS1AQXqvGGXdo5qpd";
52        let pk: BLSPubKey = s.parse().unwrap();
53        check_round_trip(pk);
54    }
55}