import { AESCipherSIVDeterministic } from "../../base/cipher/aes";
import { AbstractSelfAccountKeyring } from "../../keyring/account_base";
import { AccountMasterDeriveKeyV1 } from "../common";
import { AbstractAccountTrustConfig } from "./common";
import { makeInfoByteArray } from "../../utility";

/**
 * The trust of the account builds on chained signatures of root trusts (by upgrades) and signatures of other keys.
    Account root key fingerprint: HKDF generated "fingerprint" by the peer's root as info encrypted with AES-SIV
    If the fingerprint is not salted with a secret of the account, then any attacker has the opportunity to try to do
    a known-plaintext-attack. This is prevented by the KDF, even though it would not give any practical advantage to
    an attacker as the AES-SIV RFC states in Section 7 (paraphrased): "even if the attacker knows the plaintext, they
    will be unable to construct a string of bits that will return anything other than FAIL". What this actually means
    is that the attacker could not discover the secret key.
 */
export class AccountTrustConfigV1 extends AbstractAccountTrustConfig{

    constructor(never_dump = false){
        super(1, never_dump);
    }

    protected _decrypt(cipher: Uint8Array, key: Uint8Array): Promise<Uint8Array>{
        return AESCipherSIVDeterministic.decrypt(cipher.slice(this.version.byteLength), key);
    }

    protected _encrypt(plain: Uint8Array, key: Uint8Array): Promise<Uint8Array>{
        return AESCipherSIVDeterministic.encrypt(plain, key, undefined, this.version);
    }

    protected _get_fingerprint(peer_root_key: Uint8Array, self_kr: AbstractSelfAccountKeyring): Promise<Uint8Array>{
        // NOTE: Could use HMAC for output, but even for that a HKDF would need to be called for a secret key...
        //       unless we agree to use the master key directly.
        return AccountMasterDeriveKeyV1.derive_key(
            self_kr,
            makeInfoByteArray(["peer-trust-key-", peer_root_key]),
            false, // these are not created or checked frequently
            19 // have more than 1 block worth of data to encrypt
        )

        
    }
}