Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
3b736c2
commit a881430
Showing
7 changed files
with
457 additions
and
639 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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, ¶m, 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, ¶m, 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; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 ); | ||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
Oops, something went wrong.