facebook / akd

An implementation of an auditable key directory

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Verification failure with small trees

afterdusk opened this issue · comments

commented

Lookup and key history verifications encounter failures with small trees. This manifests with the Blake3 Hasher as well as with Sha3_256.

Repros:

Resolved with #155

We're still seeing this issue with small trees (e.g. 2 nodes). The following is a minimal repro test case (commented out in directory.rs)

// Test coverage on issue #144, verification failures with small trees (<4 nodes)
    #[tokio::test]
    async fn test_simple_lookup_for_small_tree() -> Result<(), AkdError> {
        let db = AsyncInMemoryDatabase::new();
        let vrf = HardCodedAkdVRF {};
        // epoch 0
        let akd = Directory::<_, _>::new::<Blake3>(&db, &vrf, false).await?;

        let mut updates = vec![];
        for i in 0..1 {
            updates.push((
                AkdLabel(format!("hello{}", i).as_bytes().to_vec()),
                AkdValue(format!("hello{}", i).as_bytes().to_vec()),
            ));
        }

        akd.publish::<Blake3>(updates).await?;

        let target_label = AkdLabel(format!("hello{}", 0).as_bytes().to_vec());

        // retrieve the lookup proof
        let lookup_proof = akd.lookup(target_label.clone()).await?;
        // retrieve the root hash
        let current_azks = akd.retrieve_current_azks().await?;
        let root_hash = akd.get_root_hash::<Blake3>(&current_azks).await?;

        let vrf_pk = vrf.get_vrf_public_key().await?;

        // perform the "traditional" AKD verification
        let akd_result = crate::client::lookup_verify::<Blake3>(
            &vrf_pk,
            root_hash,
            target_label.clone(),
            lookup_proof,
        );

        // check the two results to make sure they both verify
        assert!(matches!(akd_result, Ok(())));

        Ok(())
    }

I have added this fix to the TODO list for the optimized AZKS. cc @Jasleen1

#206 fixes this and includes passing tests using the reproduction above. FYI the issue was that the get_longest_common_prefix function didn't account for EMPTY_LABEL, which should be treated as NULL.