static mrb_value mrb_ecdsa_sign(mrb_state *mrb, mrb_value self) { ctr_drbg_context *ctr_drbg; unsigned char buf[512], str[1024]; int i, j, len=0, ret=0; ecdsa_context *ecdsa; mrb_value hash, obj; memset(buf, 0, sizeof( buf ) ); mrb_get_args(mrb, "S", &hash); obj = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "@ctr_drbg")); ecdsa = DATA_CHECK_GET_PTR(mrb, self, &mrb_ecdsa_type, ecdsa_context); ctr_drbg = DATA_CHECK_GET_PTR(mrb, obj, &mrb_ctr_drbg_type, ctr_drbg_context); ret = ecdsa_write_signature(ecdsa, RSTRING_PTR(hash), RSTRING_LEN(hash), buf, &len, ctr_drbg_random, ctr_drbg); for(i=0, j=0; i < len; i++,j+=2) { sprintf(&str[j], "%c%c", "0123456789ABCDEF" [buf[i] / 16], "0123456789ABCDEF" [buf[i] % 16] ); } if (ret == 0) { return mrb_str_new(mrb, &str, len*2); } else { return mrb_fixnum_value(ret); } }
static int ecdsa_sign_wrap( void *ctx, md_type_t md_alg, const unsigned char *hash, size_t hash_len, unsigned char *sig, size_t *sig_len, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) { ((void) md_alg); return( ecdsa_write_signature( (ecdsa_context *) ctx, hash, hash_len, sig, sig_len, f_rng, p_rng ) ); }
static int ecdsa_sign_wrap( void *ctx, md_type_t md_alg, const unsigned char *hash, size_t hash_len, unsigned char *sig, size_t *sig_len, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) { /* Use deterministic ECDSA by default if available */ #if defined(POLARSSL_ECDSA_DETERMINISTIC) ((void) f_rng); ((void) p_rng); return( ecdsa_write_signature_det( (ecdsa_context *) ctx, hash, hash_len, sig, sig_len, md_alg ) ); #else ((void) md_alg); return( ecdsa_write_signature( (ecdsa_context *) ctx, hash, hash_len, sig, sig_len, f_rng, p_rng ) ); #endif /* POLARSSL_ECDSA_DETERMINISTIC */ }
int main( int argc, char *argv[] ) { int ret; ecdsa_context ctx_sign, ctx_verify; entropy_context entropy; ctr_drbg_context ctr_drbg; unsigned char hash[] = "This should be the hash of a message."; unsigned char sig[512]; size_t sig_len; const char *pers = "ecdsa"; ((void) argv); ecdsa_init( &ctx_sign ); ecdsa_init( &ctx_verify ); memset(sig, 0, sizeof( sig ) ); ret = 1; if( argc != 1 ) { polarssl_printf( "usage: ecdsa\n" ); #if defined(_WIN32) polarssl_printf( "\n" ); #endif goto exit; } /* * Generate a key pair for signing */ polarssl_printf( "\n . Seeding the random number generator..." ); fflush( stdout ); entropy_init( &entropy ); if( ( ret = ctr_drbg_init( &ctr_drbg, entropy_func, &entropy, (const unsigned char *) pers, strlen( pers ) ) ) != 0 ) { polarssl_printf( " failed\n ! ctr_drbg_init returned %d\n", ret ); goto exit; } polarssl_printf( " ok\n . Generating key pair..." ); fflush( stdout ); if( ( ret = ecdsa_genkey( &ctx_sign, ECPARAMS, ctr_drbg_random, &ctr_drbg ) ) != 0 ) { polarssl_printf( " failed\n ! ecdsa_genkey returned %d\n", ret ); goto exit; } polarssl_printf( " ok (key size: %d bits)\n", (int) ctx_sign.grp.pbits ); dump_pubkey( " + Public key: ", &ctx_sign ); /* * Sign some message hash */ polarssl_printf( " . Signing message..." ); fflush( stdout ); if( ( ret = ecdsa_write_signature( &ctx_sign, hash, sizeof( hash ), sig, &sig_len, ctr_drbg_random, &ctr_drbg ) ) != 0 ) { polarssl_printf( " failed\n ! ecdsa_genkey returned %d\n", ret ); goto exit; } polarssl_printf( " ok (signature length = %u)\n", (unsigned int) sig_len ); dump_buf( " + Hash: ", hash, sizeof hash ); dump_buf( " + Signature: ", sig, sig_len ); /* * Signature is serialized as defined by RFC 4492 p. 20, * but one can also access 'r' and 's' directly from the context */ #ifdef POLARSSL_FS_IO mpi_write_file( " r = ", &ctx_sign.r, 16, NULL ); mpi_write_file( " s = ", &ctx_sign.s, 16, NULL ); #endif /* * Transfer public information to verifying context * * We could use the same context for verification and signatures, but we * chose to use a new one in order to make it clear that the verifying * context only needs the public key (Q), and not the private key (d). */ polarssl_printf( " . Preparing verification context..." ); fflush( stdout ); if( ( ret = ecp_group_copy( &ctx_verify.grp, &ctx_sign.grp ) ) != 0 ) { polarssl_printf( " failed\n ! ecp_group_copy returned %d\n", ret ); goto exit; } if( ( ret = ecp_copy( &ctx_verify.Q, &ctx_sign.Q ) ) != 0 ) { polarssl_printf( " failed\n ! ecp_copy returned %d\n", ret ); goto exit; } ret = 0; /* * Verify signature */ polarssl_printf( " ok\n . Verifying signature..." ); fflush( stdout ); if( ( ret = ecdsa_read_signature( &ctx_verify, hash, sizeof( hash ), sig, sig_len ) ) != 0 ) { polarssl_printf( " failed\n ! ecdsa_read_signature returned %d\n", ret ); goto exit; } polarssl_printf( " ok\n" ); exit: #if defined(_WIN32) polarssl_printf( " + Press Enter to exit this program.\n" ); fflush( stdout ); getchar(); #endif ecdsa_free( &ctx_verify ); ecdsa_free( &ctx_sign ); ctr_drbg_free( &ctr_drbg ); entropy_free( &entropy ); return( ret ); }