Alien-libsecp256k1

 view release on metacpan or  search on metacpan

libsecp256k1/examples/musig.c  view on Meta::CPAN


    /* Create a secp256k1 context */
    ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE);
    printf("Creating key pairs......");
    fflush(stdout);
    for (i = 0; i < N_SIGNERS; i++) {
        if (!create_keypair(ctx, &signer_secrets[i], &signers[i])) {
            printf("FAILED\n");
            return 1;
        }
        pubkeys_ptr[i] = &signers[i].pubkey;
    }
    printf("ok\n");

    /* The aggregate public key produced by secp256k1_musig_pubkey_agg depends
     * on the order of the provided public keys. If there is no canonical order
     * of the signers, the individual public keys can optionally be sorted with
     * secp256k1_ec_pubkey_sort to ensure that the aggregate public key is
     * independent of the order of signers. */
    printf("Sorting public keys.....");
    fflush(stdout);
    if (!secp256k1_ec_pubkey_sort(ctx, pubkeys_ptr, N_SIGNERS)) {
        printf("FAILED\n");
        return 1;
    }
    printf("ok\n");

    printf("Combining public keys...");
    fflush(stdout);
    /* If you just want to aggregate and not sign, you can call
     * secp256k1_musig_pubkey_agg with the keyagg_cache argument set to NULL
     * while providing a non-NULL agg_pk argument. */
    if (!secp256k1_musig_pubkey_agg(ctx, NULL, &cache, pubkeys_ptr, N_SIGNERS)) {
        printf("FAILED\n");
        return 1;
    }
    printf("ok\n");
    printf("Tweaking................");
    fflush(stdout);
    /* Optionally tweak the aggregate key */
    if (!tweak(ctx, &agg_pk, &cache)) {
        printf("FAILED\n");
        return 1;
    }
    printf("ok\n");
    printf("Signing message.........");
    fflush(stdout);
    if (!sign(ctx, signer_secrets, signers, &cache, msg, sig)) {
        printf("FAILED\n");
        return 1;
    }
    printf("ok\n");
    printf("Verifying signature.....");
    fflush(stdout);
    if (!secp256k1_schnorrsig_verify(ctx, sig, msg, 32, &agg_pk)) {
        printf("FAILED\n");
        return 1;
    }
    printf("ok\n");

    /* It's best practice to try to clear secrets from memory after using them.
     * This is done because some bugs can allow an attacker to leak memory, for
     * example through "out of bounds" array access (see Heartbleed), or the OS
     * swapping them to disk. Hence, we overwrite secret key material with zeros.
     *
     * Here we are preventing these writes from being optimized out, as any good compiler
     * will remove any writes that aren't used. */
    for (i = 0; i < N_SIGNERS; i++) {
        secure_erase(&signer_secrets[i], sizeof(signer_secrets[i]));
    }
    secp256k1_context_destroy(ctx);
    return 0;
}



( run in 0.747 second using v1.01-cache-2.11-cpan-524268b4103 )