Skip to content

Commit

Permalink
rebase test
Browse files Browse the repository at this point in the history
  • Loading branch information
curiecrypt committed Aug 10, 2022
1 parent 3b736c2 commit a881430
Show file tree
Hide file tree
Showing 7 changed files with 457 additions and 639 deletions.
8 changes: 4 additions & 4 deletions Makefile
@@ -1,18 +1,18 @@
CC=clang
CFLAGS=-Wall -Wno-unused-variable -Wno-unused-function -Wno-unused-command-line-argument -g -lsecp256k1

OBJECTS = src/libmusig2.o src/genmusig2.o
OBJECTS = src/libmusig2.o src/musig2.o

all: musig2test

src/libmusig2.o: src/libmusig2.c src/libmusig2.h src/random.h
$(CC) -c $(CFLAGS) src/libmusig2.c -o src/libmusig2.o

src/genmusig2.o: src/genmusig2.c src/api_musig2.h
$(CC) -c $(CFLAGS) src/genmusig2.c -o src/genmusig2.o
src/musig2.o: src/musig2.c src/api_musig2.h
$(CC) -c $(CFLAGS) src/musig2.c -o src/musig2.o

musig2test: musig2test.c $(OBJECTS)
$(CC) $(CFLAGS) -o $@ $^

clean:
rm -rf *.o musig2test src/libmusig2.o src/genmusig2.o
rm -rf *.o musig2test src/libmusig2.o src/musig2.o
1 change: 1 addition & 0 deletions README.md
Expand Up @@ -48,6 +48,7 @@ ___

- [x] Update the function and parameter namings.
- [x] Prevent reuse of r values.
- [x] Create musig2 context to simplify the API.
- [ ] Tests (Valgrind).


Expand Down
179 changes: 65 additions & 114 deletions musig2test.c
@@ -1,153 +1,104 @@
#include "src/api_musig2.h"

#include "src/config.h"
int main(void) {
unsigned char randomize[SCALAR_BYTES];

int i, return_val;
unsigned char randomize[SCALAR_BYTES];
int return_val;

/* Initialize the secp256k1_context to operate on secp256k1 curve.
* MuSig2 library generates a multi-signature in the form of the schnorr signature obtained by secp256k1_schnorrsig_sign32
* with the library functions of libsecp256k1, however we do not use secp256k1_schnorrsig_sign32 function.
* Thus, we create the context with only SECP256K1_CONTEXT_VERIFY flag instead of using
* SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY. */
secp256k1_context* ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY);
secp256k1_context *ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY);
if (!fill_random(randomize, sizeof(randomize))) {
printf("Failed to generate randomness\n");
return 1;
}
return_val = secp256k1_context_randomize(ctx, randomize);
assert(return_val);

/* Initialize the MUSIG2 parameters. */
MUSIG2_t param;
param.R_LIST = malloc(sizeof(secp256k1_pubkey*) * N * V * NR_MSGS);
param.xonly_X_ = malloc(sizeof(secp256k1_xonly_pubkey));
param.r_LIST = malloc(sizeof(char*) * N * V * NR_MSGS);
param.a_LIST = malloc(sizeof(char*) * N);
param.ser_xonly_X_ = malloc(XONLY_BYTES);
param.STATE = 0;
/* musig2test parameters. */
int i,j,k,l;
int ind;
secp256k1_pubkey pk_list[N]; // Signers' public key list
secp256k1_pubkey batch_list[N*V*NR_MSGS]; // Stores the batches of signers
unsigned char *parsig_list[N]; // The list of partial signatures

/* Initialize a list of N signers. */
SIGNER* signer_LIST = malloc(sizeof (SIGNER) * N);

musig2_context_sig *mcs_list[N]; // Array that holds N musig2_context_sig

/**** Initialization ****/
for (i=0; i<N; i++){
mcs_list[i] = malloc(sizeof (musig2_context_sig));
mcs_list[i]->mc = malloc(sizeof (musig2_context));
mcs_list[i]->mc->ctx = secp256k1_context_clone(ctx);

printf("--------------------------------------------------------------------------- \n");
printf("----------------------------- MuSig2 started ------------------------------ \n");
printf("--------------------------------------------------------------------------- \n");
printf("* Number of signers\t\t: %d\n", N);
printf("* Number of nonces\t\t: %d \n", V);
printf("* Number of messages\t: %d \n", NR_MSGS);
printf("--------------------------------------------------------------------------- \n");
/* Generate a keypair for the signer and get batch commitments. */
musig2_init_signer(mcs_list[i]);

/* Store the public key of the signer in pk_list */
assert (secp256k1_keypair_pub(ctx, &pk_list[i], &mcs_list[i]->keypair));
l=0;


/* Create a keypair for each signer ******************************/
printf("\n-------- Initialize Signers ----------------------------------------------- \n");
for(i=0; i<N; i++){
signer_LIST[i] = malloc(sizeof (SIGNER));
signer_LIST[i]->keypair = malloc(sizeof (secp256k1_keypair));
MuSig2_KeyGen(ctx, signer_LIST[i]->keypair);
}
printf("* %d Signers initialized.\n", N);
printf("--------------------------------------------------------------------------- \n");
/****************************************************************/



/* Collect signers **********************************************/
printf("\n-------- Collect Signers -------------------------------------------------- \n");
secp256k1_pubkey X_LIST[N]; // Signers' public key list
unsigned char* ser_xonly_XLIST[N]; // The list of signers' serialized public key list
unsigned char L[XONLY_BYTES*N]; // Concatenated ser_xonly_XLIST

/* Store full-size public keys of signers in X_LIST.
* Get x_only version of public keys.
* Store serialized x_only public keys in ser_xonly_XLIST (to compute L).
* Concat the elements of ser_xonly_XLIST in L (to compute a). */
for(i=0; i<N; i++){
secp256k1_xonly_pubkey xonly_TEMP;
ser_xonly_XLIST[i] = malloc(XONLY_BYTES);
if (secp256k1_keypair_pub(ctx, &X_LIST[i], signer_LIST[i]->keypair) &&
secp256k1_keypair_xonly_pub(ctx, &xonly_TEMP, NULL, signer_LIST[i]->keypair))
{
secp256k1_xonly_pubkey_serialize(ctx, ser_xonly_XLIST[i], &xonly_TEMP);
printf("* X%d: ", i+1);
print_hex(ser_xonly_XLIST[i], XONLY_BYTES);
memcpy( &L[i*XONLY_BYTES], ser_xonly_XLIST[i], XONLY_BYTES);
/* Store the batch commitments of the signer in batch_list */
for(k=0; k<NR_MSGS; k++){
for(j=0; j<V; j++,l++) {
ind = N*V*k + j*N + i;
assert(secp256k1_keypair_pub(ctx, &batch_list[ind], mcs_list[i]->commlist[l]));
}
}
}
printf("* %d Signers collected.\n", N);
printf("--------------------------------------------------------------------------- \n");
/****************************************************************/


/**** Aggregate the public key and batch commitments for each signer ****/
for (i=0; i<N; i++) {
mcs_list[i]->mc->state = 0;
musig2_aggregate_pubkey(mcs_list[i]->mc, pk_list, N);
musig2_agg_R(mcs_list[i], batch_list, N);
}

/* Compute exponents of signers => a ****************************/
printf("\n-------- Compute Exponents ------------------------------------------------ \n");
MuSig2_KeyAggCoef(ctx, ser_xonly_XLIST, param.a_LIST, L, N);
printf("* Exponents computed.\n");
printf("--------------------------------------------------------------------------- \n");
/****************************************************************/
/**** Signature ****/
for (i=0; i<N; i++) {
/* Generate the partial signatures */
musig2_sign(mcs_list[i], MSG_1, TAG_1,N);
parsig_list[i] = malloc(SCALAR_BYTES);

/* Collect the partial signatures in parsig_list */
memcpy(&parsig_list[i][0], mcs_list[i]->parsig, SCALAR_BYTES);

/* Check whether all aggregated R is same */
for (j=0; j<i; j++){
if (secp256k1_ec_pubkey_cmp(ctx, &mcs_list[i]->mc->R, &mcs_list[j]->mc->R ) != 0){
return -1;
}
}
}

/* Aggregate public keys ****************************************/
printf("\n-------- Aggregate Public Keys -------------------------------------------- \n");
secp256k1_pubkey X_ ; // Aggregated public key
int parity_X_ = 0; // The parity of xonly_X_
MuSig2_KeyAgg(ctx, X_LIST, &X_, param.xonly_X_, param.ser_xonly_X_, param.a_LIST, &parity_X_, N);
printf("* Public keys aggregated in X_.\n* X_: ");
print_hex(param.ser_xonly_X_, XONLY_BYTES);
param.parity_X_ = parity_X_;
printf("--------------------------------------------------------------------------- \n");
/****************************************************************/

/**** Aggregation ****/
musig2_context_agg *mca = malloc(sizeof (musig2_context_agg));
mca->mc = malloc(sizeof (musig2_context));
mca->mc->ctx = secp256k1_context_clone(ctx);

/* Initialize the aggregator */
musig2_init_aggregator(mca, pk_list,mcs_list[N-1]->mc->R, N);
/* Aggregate the partial signatures */
musig2_aggregate_parsig(mca, parsig_list, N);

/* Batch commitments ********************************************/
printf("\n-------- Generate Commitments --------------------------------------------- \n");
for(i=0; i<N; i++){
signer_LIST[i]->r_LIST = malloc(sizeof (char*) * V * NR_MSGS);
MuSig2_BatchCommitment(ctx, param.R_LIST, signer_LIST[i]->r_LIST, i, N, NR_MSGS, V);
}
printf("* Commitments generated.\n");
printf("--------------------------------------------------------------------------- \n");
/****************************************************************/

/**** Verification ****/
musig2_context_ver *mcv = malloc(sizeof (musig2_context_ver));
mcv->ctx = secp256k1_context_clone(ctx);

/* Initialize the verifier */
musig2_init_verifier(mcv, mca->signature, mca->mc->X_);

/* Signature for MSG_1 ******************************************/
printf("\n*************************************************************************** \n");
printf("--------- Signing Started ------------------------------------------------- \n");
printf("* State\t\t: %d \n", param.STATE+1);
printf("* Message\t: ");
printf("%s\n", MSG_1);
printf("--------------------------------------------------------------------------- \n");
if (Gen_MuSig2(ctx, signer_LIST, &param, MSG_1, TAG_1))
printf("* Musig2 is verified successfully!\n");
else
printf("* Verification failed!\n");
param.STATE++; /* Update state after each signature. */
printf("*************************************************************************** \n");
/****************************************************************/



/* Signature for MSG_2 ******************************************/
printf("\n*************************************************************************** \n");
printf("--------- Signing Started ------------------------------------------------- \n");
printf("* State\t\t: %d \n", param.STATE+1);
printf("* Message\t: ");
printf("%s\n", MSG_2);
printf("--------------------------------------------------------------------------- \n");
if (Gen_MuSig2(ctx, signer_LIST, &param, MSG_2, TAG_2))
printf("* Musig2 is verified successfully!\n");
/* Verify the aggregated signature with secp256k1_schnorrsig_verify */
if (musig2_verify_musig(mcv, MSG_1, TAG_1))
printf("Musig2 is VALID!\n");
else
printf("* Verification failed!\n");
param.STATE++; /* Update state after each signature. */
printf("*************************************************************************** \n");
printf("Failed to verify Musig2!\n");


secp256k1_context_destroy(ctx);
return 0;
}
131 changes: 81 additions & 50 deletions src/api_musig2.h
@@ -1,55 +1,86 @@
#include "config.h"
#include "libmusig2.h"

#define N 5 /* Number of signers */
#define V 2 /* Number of nonce values. Note that V>2 is not working yet. */

#define NR_MSGS (const int)2
#define MSG_1 (const unsigned char *) "Musig2 Schnorr MSG 1"
#define MSG_2 (const unsigned char *) "Musig2 Schnorr MSG 2"
#define TAG_1 (const unsigned char *) "MSG_1"
#define TAG_2 (const unsigned char *) "MSG_2"


/** Pointer : MUSIG2
* Purpose : Stores the parameters used in Musig2 generation.
* Parameters : R_LIST, the secp256k1_pubkey array of public batch commitments.
* : xonly_X_, the x_only aggregated public key of X_.
* : r_LIST, the array of batch nonces of size 32-bytes.
* : a_LIST, the array of exponents of size 32-bytes.
* : ser_xonly_X_, the serialized xonly_X_.
* : parity_X_, the parity of xonly_X_.
* : STATE, the current state of Musig2.


/** Function : musig2_init_signer
* Purpose : Initializes a musig2 signer. Generates the keypair and creates a list of batch commitments for signer.
* Parameters : IN/OUT : mcs, A musig2_context_sig object including parameters of musig2 signer.
* */
void musig2_init_signer(musig2_context_sig *mc);

/** Function : musig2_agg_R
* Purpose : Aggregates the given list of batch commitments of `n` signers for `V` into `agg_R_list`.
* Returns 1 if agg_R_list is created successfully, 0 otherwise.
* Parameters : IN/OUT : mcs, A musig2_context_sig object including parameters of musig2 signer.
* : IN : batch_list: The list of batch commitments.
* : n: Number of signers.
* Returns : 1/0.
* */
typedef struct{
secp256k1_pubkey **R_LIST;
secp256k1_xonly_pubkey *xonly_X_;
unsigned char **r_LIST;
unsigned char **a_LIST;
unsigned char *ser_xonly_X_;
int parity_X_;
int STATE;
}MUSIG2_t, *MUSIG2;

/** Pointer : SIGNER
* Purpose : Stores the parameters of a MuSig2 signer.
* Parameters : keypair, the secp256k1_keypair object holding a keypair on secp256k1 curve.
* : r_LIST, the list to store V secret nonces of size 32-bytes.
int musig2_agg_R(musig2_context_sig *mcs, secp256k1_pubkey *batch_list, int n);

/** Function : musig2_sign
* Purpose : Starts the signature process for signer and calls `musig2_sign_partial`.
* Returns 1 if partial signature is created successfully, 0 otherwise.
* Parameters : IN/OUT : mcs, A musig2_context_sig object including parameters of musig2 signer.
* : IN : msg: The message to be signed.
* : tag: The tag of the message.
* : n: Number of signers.
* Returns : 1/0.
* */
int musig2_sign(musig2_context_sig *mcs, const unsigned char *msg, const unsigned char *tag, int n);

/** Function : musig2_init_aggregator
* Purpose : Initializes the musig2 aggregator. For the given list of public keys, computes aggregated public key.
* Sets the aggregated commitment R.
* Parameters : IN/OUT : mca, A musig2_context_agg object including parameters of musig2 aggregator.
* : IN : pk_list: The list of public keys.
* : R: Aggregated commitment R.
* : n: Number of signers.
* */
typedef struct{
secp256k1_keypair *keypair;
unsigned char **r_LIST;
}SIGNER_t, *SIGNER;


/** Function : Gen_MuSig2
* Purpose : This is the main function to compute a whole process of Musig2 for a specific message and defined parameters.
* It returns 1 if the generated signature is validated by secp256k1_schnorrsig_verify function, 0 otherwise.
* Parameters : IN : ctx, a secp256k1_context object.
* : Signers, the list of secp256k1_keypair objects of signers.
* : msg, the message to be signed.
* : the tag of the hash function for msg.
* : param, is a pointer to parameters of Musig2.
* Returns : 1/0.
void musig2_init_aggregator(musig2_context_agg *mca, secp256k1_pubkey *pk_list, secp256k1_pubkey R, int n);

/** Function : musig2_aggregate_parsig
* Purpose : Aggregates the given list of partial signatures. Sets the musig2 signature.
* Returns 1 if musig2 signature is created successfully, 0 otherwise.
* Parameters : IN/OUT : mca, A musig2_context_agg object including parameters of musig2 aggregator.
* : IN : parsig_list: The list of partial signatures.
* : n: Number of signers.
* Returns : 1/0.
* */
int Gen_MuSig2(secp256k1_context *ctx, SIGNER *Signers, MUSIG2 param, const unsigned char *msg, const unsigned char *tag);
/*----------------------------------------------------------------------------------------------------------*/
int musig2_aggregate_parsig(musig2_context_agg *mca, unsigned char **parsig_list, int n);

/** Function : musig2_init_verifier
* Purpose : Initializes a musig2 verifier.
* Parameters : IN/OUT : mca, A musig2_context_ver object including parameters of musig2 verifier.
* : IN : signature: The list of partial signatures.
* : X: Public key.
* */
void musig2_init_verifier(musig2_context_ver *mcv, unsigned char *signature, secp256k1_pubkey X);

/** Function : musig2_verify_musig
* Purpose : Verifies the musig2 signature with `secp256k1_schnorrsig_verify`.
* Returns 1 if musig2 signature is verified successfully, 0 otherwise.
* Parameters : IN/OUT : mcv, A musig2_context_ver object including parameters of musig2 verifier.
* : IN : msg: The message to be signed.
* : tag: The tag of the message.
* Returns : 1/0.
* */
int musig2_verify_musig(musig2_context_ver *mcv,const unsigned char *msg, const unsigned char *tag );

















0 comments on commit a881430

Please sign in to comment.