gateway2/Tongsuo-8.4.0/crypto/zkp/common/zkp_transcript_sha256.c
2026-07-11 13:40:57 +08:00

269 lines
7.3 KiB
C

/*
* Copyright 2023 The Tongsuo Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://github.com/Tongsuo-Project/Tongsuo/blob/master/LICENSE.txt
*/
#include <openssl/err.h>
#include <openssl/zkperr.h>
#include <openssl/evp.h>
#include <openssl/sha.h>
#include "zkp_transcript.h"
#ifndef __bswap_constant_64
# define __bswap_constant_64(x) \
((((x) & 0xff00000000000000ull) >> 56) \
| (((x) & 0x00ff000000000000ull) >> 40) \
| (((x) & 0x0000ff0000000000ull) >> 24) \
| (((x) & 0x000000ff00000000ull) >> 8) \
| (((x) & 0x00000000ff000000ull) << 8) \
| (((x) & 0x0000000000ff0000ull) << 24) \
| (((x) & 0x000000000000ff00ull) << 40) \
| (((x) & 0x00000000000000ffull) << 56))
#endif
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
# define int64_n2l(x) (x)
# define int64_l2n(x) (x)
#else
# define int64_n2l(x) __bswap_constant_64(x)
# define int64_l2n(x) __bswap_constant_64(x)
#endif
typedef struct zkp_transcript_sha256_ctx_st {
EVP_MD *sha256;
EVP_MD_CTX *md_ctx;
} zkp_transcript_sha256_ctx;
static int zkp_transcript_sha256_init(ZKP_TRANSCRIPT *transcript)
{
size_t len;
zkp_transcript_sha256_ctx *ctx = NULL;
if (transcript == NULL) {
ERR_raise(ERR_LIB_ZKP, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
if (!(ctx = OPENSSL_zalloc(sizeof(*ctx)))) {
ERR_raise(ERR_LIB_ZKP, ERR_R_MALLOC_FAILURE);
goto err;
}
ctx->md_ctx = EVP_MD_CTX_new();
if (ctx->md_ctx == NULL) {
ERR_raise(ERR_LIB_ZKP, ERR_R_MALLOC_FAILURE);
goto err;
}
if (!(ctx->sha256 = EVP_MD_fetch(NULL, "sha256", NULL))
|| !EVP_DigestInit(ctx->md_ctx, ctx->sha256))
goto err;
if (transcript->label != NULL) {
len = strlen(transcript->label);
if (!EVP_DigestUpdate(ctx->md_ctx, transcript->label, len))
goto err;
}
transcript->data = ctx;
return 1;
err:
EVP_MD_CTX_free(ctx->md_ctx);
OPENSSL_free(ctx);
return 0;
}
static int zkp_transcript_sha256_reset(ZKP_TRANSCRIPT *transcript)
{
size_t len;
zkp_transcript_sha256_ctx *ctx = NULL;
if (transcript == NULL) {
ERR_raise(ERR_LIB_ZKP, ERR_R_PASSED_INVALID_ARGUMENT);
return 0;
}
ctx = transcript->data;
if (!EVP_DigestInit(ctx->md_ctx, ctx->sha256))
return 0;
if (transcript->label != NULL) {
len = strlen(transcript->label);
if (!EVP_DigestUpdate(ctx->md_ctx, transcript->label, len))
return 0;
}
return 1;
}
static int zkp_transcript_sha256_cleanup(ZKP_TRANSCRIPT *transcript)
{
zkp_transcript_sha256_ctx *ctx = NULL;
if (transcript == NULL) {
ERR_raise(ERR_LIB_ZKP, ERR_R_PASSED_INVALID_ARGUMENT);
return 0;
}
ctx = transcript->data;
EVP_MD_CTX_free(ctx->md_ctx);
return 1;
}
static int zkp_transcript_sha256_append_int64(ZKP_TRANSCRIPT *transcript,
const char *label, const int64_t i64)
{
int64_t num;
zkp_transcript_sha256_ctx *ctx = NULL;
if (transcript == NULL || label == NULL) {
ERR_raise(ERR_LIB_ZKP, ERR_R_PASSED_INVALID_ARGUMENT);
return 0;
}
ctx = transcript->data;
num = int64_l2n(i64);
return EVP_DigestUpdate(ctx->md_ctx, label, strlen(label))
&& EVP_DigestUpdate(ctx->md_ctx, (char *)&num, sizeof(num));
}
static int zkp_transcript_sha256_append_str(ZKP_TRANSCRIPT *transcript,
const char *label,
const char *str, int len)
{
zkp_transcript_sha256_ctx *ctx = NULL;
if (transcript == NULL || str == NULL || len <= 0) {
ERR_raise(ERR_LIB_ZKP, ERR_R_PASSED_INVALID_ARGUMENT);
return 0;
}
ctx = transcript->data;
return EVP_DigestUpdate(ctx->md_ctx, label, strlen(label))
&& EVP_DigestUpdate(ctx->md_ctx, str, len);
}
static int zkp_transcript_sha256_append_point(ZKP_TRANSCRIPT *transcript,
const char *label,
const EC_POINT *point,
const EC_GROUP *group)
{
int ret = 0;
size_t len;
unsigned char buf[128], *str = NULL;
point_conversion_form_t format = POINT_CONVERSION_COMPRESSED;
zkp_transcript_sha256_ctx *ctx = NULL;
if (transcript == NULL || point == NULL || group == NULL) {
ERR_raise(ERR_LIB_ZKP, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
ctx = transcript->data;
len = EC_POINT_point2oct(group, point, format, NULL, 0, NULL);
if (len > sizeof(buf)) {
if (!(str = OPENSSL_zalloc(len))) {
ERR_raise(ERR_LIB_ZKP, ERR_R_MALLOC_FAILURE);
return 0;
}
} else {
str = &buf[0];
}
ret = EVP_DigestUpdate(ctx->md_ctx, label, strlen(label))
&& EC_POINT_point2oct(group, point, format, str, len, NULL) > 0
&& EVP_DigestUpdate(ctx->md_ctx, str, len);
if (len > sizeof(buf))
OPENSSL_free(str);
return ret;
}
static int zkp_transcript_sha256_append_bn(ZKP_TRANSCRIPT *transcript,
const char *label, const BIGNUM *bn)
{
int ret = 0;
size_t len;
unsigned char buf[256] = {0}, *str = NULL;
zkp_transcript_sha256_ctx *ctx = NULL;
if (transcript == NULL || bn == NULL) {
ERR_raise(ERR_LIB_ZKP, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
ctx = transcript->data;
len = BN_is_zero(bn) ? 1 : BN_num_bytes(bn);
if (len > sizeof(buf)) {
if (!(str = OPENSSL_zalloc(len))) {
ERR_raise(ERR_LIB_ZKP, ERR_R_MALLOC_FAILURE);
return 0;
}
} else {
str = &buf[0];
}
ret = EVP_DigestUpdate(ctx->md_ctx, label, strlen(label))
&& BN_bn2binpad(bn, str, len) && EVP_DigestUpdate(ctx->md_ctx, str, len);
if (len > sizeof(buf))
OPENSSL_free(str);
return ret;
}
static int zkp_transcript_sha256_challange(ZKP_TRANSCRIPT *transcript,
const char *label, BIGNUM *out)
{
unsigned char hash_res[SHA256_DIGEST_LENGTH];
zkp_transcript_sha256_ctx *ctx = NULL;
if (transcript == NULL || out == NULL) {
ERR_raise(ERR_LIB_ZKP, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
ctx = transcript->data;
if (!EVP_DigestUpdate(ctx->md_ctx, label, strlen(label))
|| !EVP_DigestFinal(ctx->md_ctx, hash_res, NULL))
return 0;
if (!BN_bin2bn(hash_res, SHA256_DIGEST_LENGTH, out))
return 0;
if (!EVP_DigestInit(ctx->md_ctx, ctx->sha256))
return 0;
return EVP_DigestUpdate(ctx->md_ctx, hash_res, SHA256_DIGEST_LENGTH);
}
const ZKP_TRANSCRIPT_METHOD *ZKP_TRANSCRIPT_METHOD_sha256(void)
{
static const ZKP_TRANSCRIPT_METHOD ret = {
zkp_transcript_sha256_init,
zkp_transcript_sha256_reset,
zkp_transcript_sha256_cleanup,
zkp_transcript_sha256_append_int64,
zkp_transcript_sha256_append_str,
zkp_transcript_sha256_append_point,
zkp_transcript_sha256_append_bn,
zkp_transcript_sha256_challange,
};
return &ret;
}