174 lines
5.2 KiB
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;
|
|
}
|
|
|