#include extern "C" { #include "../target/include/atms.h" } TEST(multisig, serdeMultiSignature) { const char *msg = "some message"; // Test with 5 parties and threshold 4. SigningKeyPtr sk; PublicKeyPoPPtr key_pop; PublicKeyPtr key; int err; err = atms_generate_keypair(&sk, &key_pop); ASSERT_EQ(err, 0); unsigned char *skey_bytes; unsigned char *key_pop_bytes; unsigned long skey_size; unsigned long key_pop_size; err = serialize_sk(sk, &skey_size, &skey_bytes); err = serialize_pkpop(key_pop, &key_pop_size, &key_pop_bytes); err = deserialize_sk(skey_size, skey_bytes, &sk); ASSERT_EQ(err, 0); err = deserialize_pkpop(key_pop_size, key_pop_bytes, &key_pop); ASSERT_EQ(err, 0); err = atms_pkpop_to_pk(key_pop, &key); ASSERT_EQ(err, 0); unsigned char *key_pk_bytes; unsigned long key_pk_size; err = serialize_pk(key, &key_pk_size, &key_pk_bytes); err = deserialize_pk(key_pk_size, key_pk_bytes, &key); ASSERT_EQ(err, 0); SignaturePtr sig; err = atms_sign(msg, sk, &sig); ASSERT_EQ(err, 0); unsigned char *sig_bytes; unsigned long sig_size; err = serialize_signature(sig, &sig_size, &sig_bytes); err = deserialize_signature(sig_size, sig_bytes, &sig); ASSERT_EQ(err, 0); err = atms_verify(msg, key, sig); ASSERT_EQ(err, 0); } TEST(atms, serdeAtms) { const char *msg = "some message"; // Test with 5 parties and threshold 4. SigningKeyPtr sks[5]; PublicKeyPtr keys[5]; PublicKeyPoPPtr keys_pop[5]; unsigned int nr_signers = 5; unsigned int threshold = 4; int err; for (int i = 0; i < nr_signers; i++) { err = atms_generate_keypair(&sks[i], &keys_pop[i]); atms_pkpop_to_pk(keys_pop[i], &keys[i]); ASSERT_EQ(err, 0); } // The threshold public key can be generated by using the public key parts of the participants. RegistrationPtr registration; AvkPtr avk_pk; err = avk_key_registration(keys_pop, nr_signers, ®istration); ASSERT_EQ(err, 0); err = atms_registration_to_avk(&avk_pk, registration); ASSERT_EQ(err, 0); unsigned char *avk_bytes; unsigned long avk_size; err = serialize_avk(avk_pk, &avk_size, &avk_bytes); err = deserialize_avk(avk_size, avk_bytes, &avk_pk); ASSERT_EQ(err, 0); // Now, signers can produce threshold signatures with respect to `avk_pk`. Now, let's assume that // parties 0-3 generate a signature. SignaturePtr sigs[4]; for (int i = 0; i < 4; i++) { err = atms_sign(msg, sks[i], &sigs[i]); ASSERT_EQ(err, 0); } // Given the four signatures and the public keys from the corresponding signers, any third party (not necessarily // a signer) can aggregate the signatures. It only needs knowledge of the avk key over which it is supposed to be // valid. AggregateSigPtr aggregated_sig; err = atms_aggregate_sigs(msg, sigs, keys, registration, 4, &aggregated_sig); ASSERT_EQ(err, 0); unsigned char *aggr_bytes; unsigned long aggr_size; err = serialize_aggr_sig(aggregated_sig, &aggr_size, &aggr_bytes); err = deserialize_aggr_sig(aggr_size, aggr_bytes, &aggregated_sig); ASSERT_EQ(err, 0); // Finally, we check that the signature is indeed valid. err = atms_verify_aggr(msg, aggregated_sig, avk_pk, threshold); ASSERT_EQ(err, 0); }