static themis_status_t ed_point_sign(uint8_t pos, const uint8_t *scalar, const ge_p3 *point, uint8_t *signature) { uint8_t r[ED25519_GE_LENGTH]; ge_p3 R; uint8_t k[64]; soter_hash_ctx_t hash_ctx; size_t hash_length = 64; themis_status_t res; generate_random_32(r); ge_scalarmult_base(&R, r); ge_p3_tobytes(k, &R); res = soter_hash_init(&hash_ctx, SOTER_HASH_SHA512); if (THEMIS_SUCCESS != res) { return res; } res = soter_hash_update(&hash_ctx, k, ED25519_GE_LENGTH); if (THEMIS_SUCCESS != res) { soter_hash_final(&hash_ctx, k, &hash_length); return res; } ge_scalarmult_blinded(&R, r, point); ge_p3_tobytes(k, &R); res = soter_hash_update(&hash_ctx, k, ED25519_GE_LENGTH); if (THEMIS_SUCCESS != res) { soter_hash_final(&hash_ctx, k, &hash_length); return res; } res = soter_hash_update(&hash_ctx, &pos, sizeof(pos)); if (THEMIS_SUCCESS != res) { soter_hash_final(&hash_ctx, k, &hash_length); return res; } res = soter_hash_final(&hash_ctx, k, &hash_length); if (THEMIS_SUCCESS != res) { return res; } if (THEMIS_SUCCESS == res) { sc_reduce(k); memcpy(signature, k, ED25519_GE_LENGTH); sc_muladd(signature + ED25519_GE_LENGTH, k, scalar, r); } return res; }
static themis_status_t ed_dbl_base_sign(uint8_t pos, const uint8_t *scalar1, const uint8_t *scalar2, const ge_p3 *base1, const ge_p3 *base2, uint8_t *signature) { uint8_t r1[ED25519_GE_LENGTH]; uint8_t r2[ED25519_GE_LENGTH]; ge_p3 R1; ge_p2 R2; uint8_t k[64]; soter_hash_ctx_t hash_ctx; size_t hash_length = 64; themis_status_t res; generate_random_32(r1); generate_random_32(r2); ge_scalarmult_blinded(&R1, r1, base2); ge_double_scalarmult_vartime(&R2, r2, base1, r1); res = soter_hash_init(&hash_ctx, SOTER_HASH_SHA512); if (THEMIS_SUCCESS != res) { return res; } ge_p3_tobytes(k, &R1); res = soter_hash_update(&hash_ctx, k, ED25519_GE_LENGTH); if (THEMIS_SUCCESS != res) { soter_hash_final(&hash_ctx, k, &hash_length); return res; } ge_tobytes(k, &R2); res = soter_hash_update(&hash_ctx, k, ED25519_GE_LENGTH); if (THEMIS_SUCCESS != res) { soter_hash_final(&hash_ctx, k, &hash_length); return res; } res = soter_hash_update(&hash_ctx, &pos, sizeof(pos)); if (THEMIS_SUCCESS != res) { soter_hash_final(&hash_ctx, k, &hash_length); return res; } res = soter_hash_final(&hash_ctx, k, &hash_length); if (THEMIS_SUCCESS == res) { sc_reduce(k); memcpy(signature, k, ED25519_GE_LENGTH); sc_muladd(signature + ED25519_GE_LENGTH, k, scalar1, r1); sc_muladd(signature + (2 * ED25519_GE_LENGTH), k, scalar2, r2); } return res; }
soter_hash_ctx_t* soter_hash_create(soter_hash_algo_t algo) { soter_status_t status; soter_hash_ctx_t *ctx = malloc(sizeof(soter_hash_ctx_t)); if (!ctx) { return NULL; } status = soter_hash_init(ctx, algo); if (SOTER_SUCCESS == status) { return ctx; } else { free(ctx); return NULL; } }