Skip to content

Instantly share code, notes, and snippets.

@10to4
Last active January 24, 2024 20:00
Show Gist options
  • Save 10to4/b2dece43bcbc210e2ee93d7c753f7bc6 to your computer and use it in GitHub Desktop.
Save 10to4/b2dece43bcbc210e2ee93d7c753f7bc6 to your computer and use it in GitHub Desktop.
puzzle-supervillain

In this problem, PoK verification is first performed on each set of public keys and their proofs, followed by the aggregation of all public keys for BLS signature verification.

The BLS signature verification code is as follows:

fn bls_sign(sk: Fr, msg: &[u8]) -> G2Affine {
    hasher().hash(msg).unwrap().mul(sk).into_affine()
}

fn bls_verify(pk: G1Affine, sig: G2Affine, msg: &[u8]) {
    assert!(Bls12_381::multi_pairing(
        &[pk, G1Affine::generator()],
        &[hasher().hash(msg).unwrap().neg(), sig]
    )
    .is_zero());
}

The BLS signature method uses $sig = hash^{sk}$, and the verification logic is $e(pk, [1]_2) = e(hash, sig)$, where $pk = [sk]_1$.

The public key aggregation is done by simply adding all the public keys, i.e., aggregate_key = new_key + $\sum_{i \in [0..9)} pk_i = [nsk + \sum_{i \in [0..9)} sk_i ]_1$, where each public key $pk_i$ corresponds to the private key $sk_i$, and the private key of new_key is nsk. To achieve successful verification, it is required that the signature satisfies: $sig = [hash]_1 *$ aggregate_sk.

Clearly, to compute the value of sig, one needs to know the value of aggregate_sk, completing the signature verification. According to the algorithm's logic, one would need to know the values of all private keys $sk_i$ and nsk to compute aggregate_sk. However, in practice, since $aggregate_sk = nsk + \sum_{i \in [0..9)} sk_i$, it can be calculated as nsk = aggregate_sk - $\sum_{i \in [0..9)} sk_i$.

To construct an arbitrary aggregate_sk value, it is necessary to obtain $\sum_{i \in [0..9)} sk_i$ to calculate nsk and subsequently construct new_key. PoK verification in the code is used to verify the legality of new_key.

The generation method for PoK proof is: $proof = [rng * (i+1) * sk]_2$, and the verification method is: $e(pk, [rng * (i+1)]_2 = e([1]_1, proof)$. Since we do not know the values of all $sk_i$, we cannot directly obtain nsk. However, we can use $pk_i$ to generate new_key and use the proof $proof_i$ of $pk_i$ to generate the proof of new_key.

To construct $nsk = aggregate_sk -\sum_{i \in [0..9)} sk_i$ corresponding to the public key $new_key = [aggregate_sk]1 = [aggregate_sk - \sum{i \in [0..9)} sk_i]_1 = [aggregate_sk]_1 - \sum{i \in [0..9)} pk_i$.

We can also construct $proof{new_key} = [rng * (new_key_index+1) + nsk]2 = [rng * (new_key_index+1) + (aggregate_sk - \sum{i \in [0..9)} sk_i)]_2 = ([rng * aggregate_sk ]2 + [\sum{i \in [0..9)} sk_i]_2) * (new_key_index+1) = ([rng * aggregate_sk ]2 + [\sum{i \in [0..9)} proof_i * (1/(i+1)) * (new_key_index+1) = ([rng * aggregate_sk ]2 + [\sum{i \in [0..9)} proof_i * (1/(i+1)) * (new_key_index+1) = ([rng]2 * aggregate_sk + [\sum{i \in [0..9)} proof_i * (1/(i+1)) * (new_key_index+1)$, where [rng]_2 can be obtained through the function derive_point_for_pok(0).

With this, we can construct the appropriate new_key and its proof.

To summarize the steps:

  1. Take an arbitrary aggregate_sk value and ensure that nsk satisfies $nsk = aggregate_sk - \sum_{i \in [0..9)} sk_i$.

  2. Calculate new_key

$new_key = [aggregate_sk]1 - \sum{i \in [0..9)} pk_i$.

  1. Calculate $proof_{new_key}$

$proof_{new_key} = ([rng]2 * aggregate_sk + \sum{i \in [0..9)} proof_i * (1/(i+1)) * (new_key_index + 1)$.

  1. Calculate the aggregate signature

$sig = hash(message) * aggregate_sk$.

  1. Verify new_key

$e(new_key, [rng * (i+1)]_2) = e([1]_1, proof{new_key})$.

  1. Calculate the aggregate_key

$aggregate_key = new_key + \sum_{i \in [0..9)} pk_i = [aggregate_sk]1 - \sum_{i \in [0..9)} pk_i + \sum_{i \in [0..9)} pk_i = [aggregate_sk]_1$.

  1. Verify the BLS signature

$e(aggregate_key, hash(message)) = e([1]_1, sig)$ => $e([aggregate_sk]_1, hash(message)) = e([1]_1, hash(message) * aggregate_sk)$.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment