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;
}
Exemple #3
0
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;
	}
}