libcurve/src/lsag.c

174 lines
5.2 KiB
C

#include <lsag.h>
#include <mpztools.h>
#include <sha256.h>
int32_t lsag_sign (char *message, int mlen, mpz_t signKey, ec_point_t* public_keys, int public_keys_len, curve_t curve, mpz_t out_C0, ec_point_t out_Y, mpz_t* out_s)
{
ec_point_t signPubKey;
int signKeyIndex = -1;
curve_point_init( signPubKey );
curve_point_mul( signPubKey, curve->G, signKey, curve );
for (int n=0; n<public_keys_len; n++)
{
if (curve_point_equals(signPubKey, public_keys[n]))
{
signKeyIndex = n;
break;
}
}
if (signKeyIndex < 0)
{
printf("SignKey not found!\n");
return -1;
}
// printf("signing key is %i\n", signKeyIndex);
mpz_field_cleanup( c, public_keys_len );
mpz_cleanup( u );
char pkHash[32];
char msgHash[32];
sha256( message, mlen, msgHash );
sha256_curve_points( public_keys, public_keys_len, curve, pkHash );
// printf("msgHash: %s\n", print_hex(msgHash, 32));
// printf("pkHash: %s\n", print_hex(pkHash, 32));
ec_point_t_cleanup(H);
curve_hash_to_point( H, pkHash, 32, curve );
curve_point_mul( out_Y, H, signKey, curve );
mpz_random_mod( u, curve->n );
ec_point_t_cleanup(a);
ec_point_t_cleanup(b);
ec_point_t_cleanup(t);
curve_point_mul( a, curve->G, u, curve );
curve_point_mul( b, H, u, curve );
lsag_hash_one(pkHash, out_Y, msgHash, a, b, curve, c[ (signKeyIndex+1) % public_keys_len ] );
for (int i=(signKeyIndex+1) % public_keys_len ; i != signKeyIndex ; i = (i+1)%public_keys_len )
{
mpz_random_mod( out_s[i], curve->n );
curve_point_mul( a, curve->G, out_s[i], curve );
curve_point_mul( t, public_keys[i], c[i], curve );
curve_point_add( a, a, t, curve );
curve_point_mul( b, H, out_s[i], curve );
curve_point_mul( t, out_Y, c[i], curve );
curve_point_add( b, b, t, curve );
lsag_hash_one(pkHash, out_Y, msgHash, a, b, curve, c[ (i+1) % public_keys_len ] );
// printf("sign: c[%i] = %s\n", i, mpz_to_string(c[i], 16));
// printf("sign: s[%i] = %s\n", i, mpz_to_string(out_s[i], 16));
}
mpz_set( out_s[signKeyIndex], u );
mpz_submul( out_s[signKeyIndex], signKey, c[signKeyIndex] );
mpz_mod( out_s[signKeyIndex], out_s[signKeyIndex], curve->n );
// printf("sign: c[%i] = %s\n", signKeyIndex, mpz_to_string(c[signKeyIndex], 16));
// printf("sign: s[%i] = %s\n", signKeyIndex, mpz_to_string(out_s[signKeyIndex], 16));
mpz_set( out_C0, c[0] );
return 0;
}
int32_t lsag_verify (char *message, int mlen, ec_point_t* public_keys, int public_keys_len, curve_t curve, mpz_t C0, ec_point_t Y, mpz_t* s)
{
// printf(" --- lsag_verify(): start --- \n");
char msgHash[32];
char pkHash[32];
sha256( message, mlen, msgHash );
sha256_curve_points( public_keys, public_keys_len, curve, pkHash );
// printf("msgHash: %s\n", print_hex(msgHash, 32));
// printf("pkHash: %s\n", print_hex(pkHash, 32));
mpz_field_cleanup( c, public_keys_len + 1 );
mpz_set( c[0], C0 );
// printf(" --- lsag_verify(): mark I --- \n");
ec_point_t_cleanup(H);
// printf(" --- lsag_verify(): mark Ib --- \n");
curve_hash_to_point( H, pkHash, 32, curve );
ec_point_t_cleanup(a);
ec_point_t_cleanup(b);
ec_point_t_cleanup(t);
// printf(" --- lsag_verify(): mark II --- \n");
for (int i=0 ; i < public_keys_len ; i++ )
{
// printf("sign: c[%i] = %s\n", i, mpz_to_string(c[i], 16));
// printf("sign: s[%i] = %s\n", i, mpz_to_string(s[i], 16));
curve_point_mul( a, curve->G, s[i], curve );
curve_point_mul( t, public_keys[i], c[i], curve );
curve_point_add( a, a, t, curve );
curve_point_mul( b, H, s[i], curve );
curve_point_mul( t, Y, c[i], curve );
curve_point_add( b, b, t, curve );
lsag_hash_one(pkHash, Y, msgHash, a, b, curve, c[ i+1 ] );
}
return mpz_cmp(c[0], c[public_keys_len]) == 0;
}
int32_t lsag_hash_one(char *pkHash, ec_point_t y, char *msgHash, ec_point_t a, ec_point_t b, curve_t curve, mpz_t out_H1)
{
char h1[32];
int keysize = curve->bitwidth >> 3;
char tv[keysize];
SHA256_CTX sha;
sha256_init( &sha );
sha256_update( &sha, pkHash, 32 );
sha256_update( &sha, msgHash, 32 );
memset( tv, 0x00, keysize );
mpz_export( tv, NULL, -1, 1, -1, 0, y->x );
sha256_update( &sha, tv, keysize);
memset( tv, 0x00, keysize );
mpz_export( tv, NULL, -1, 1, -1, 0, y->y );
sha256_update( &sha, tv, keysize);
memset( tv, 0x00, keysize );
mpz_export( tv, NULL, -1, 1, -1, 0, a->x );
sha256_update( &sha, tv, keysize);
memset( tv, 0x00, keysize );
mpz_export( tv, NULL, -1, 1, -1, 0, a->y );
sha256_update( &sha, tv, keysize);
memset( tv, 0x00, keysize );
mpz_export( tv, NULL, -1, 1, -1, 0, b->x );
sha256_update( &sha, tv, keysize);
memset( tv, 0x00, keysize );
mpz_export( tv, NULL, -1, 1, -1, 0, b->y );
sha256_update( &sha, tv, keysize);
sha256_final( &sha, h1 );
mpz_import( out_H1, 32, -1, 1, -1, 0, h1 );
mpz_mul_ui( out_H1, out_H1, 0xdeadbeef );
mpz_mod( out_H1, out_H1, curve->p );
return 0;
}