https://github.com/henrycg/earand
Raw File
Tip revision: 362625f3847ddd2e2d5a90cf5f93b4b3ea76e059 authored by Henry Corrigan-Gibbs on 21 May 2018, 19:54:59 UTC
Merge branch 'master' of github.com:henrycg/earand
Tip revision: 362625f
dsa_ea.c
#include <stdio.h>
#include "dsa_ea.h"

struct dsa_ea {
  DsaParams params;

  EC_POINT* commit_x;
  BIGNUM* x_prime;
  X509* cert;
};

DsaEa DsaEa_New(DsaParams params)
{
  DsaEa ea = safe_malloc(sizeof(*ea));
  ea->params = params;
  ea->commit_x = NULL;
  ea->x_prime = NULL;
  ea->cert = NULL;

  return ea;
}

void DsaEa_Free(DsaEa ea)
{
  if(ea->commit_x) EC_POINT_clear_free(ea->commit_x);
  if(ea->x_prime) BN_clear_free(ea->x_prime);
  if(ea->cert) X509_free(ea->cert);

  free(ea);
}

bool DsaEa_SetEntropyRequest(DsaEa ea, const EC_POINT* commit_x)
{
  // Store commitment to x
  return (ea->commit_x = EC_POINT_dup(commit_x, DsaParams_GetCurve(ea->params)));
}

bool DsaEa_GetEntropyResponse(DsaEa ea, BIGNUM** x_prime)
{
  // Pick random x'
  if(ea->x_prime) BN_clear_free(ea->x_prime);
  ea->x_prime = DsaParams_RandomExponent(ea->params);

  // Return x'
  CHECK_CALL(BN_copy(*x_prime, ea->x_prime));

  return true;
}

bool DsaEa_SetCertRequest(DsaEa ea, const_PedersenEvidence ev, X509_REQ* req)
{
  const EC_GROUP* curve = DsaParams_GetCurve(ea->params);
  BN_CTX* ctx = DsaParams_GetCtx(ea->params);

  EVP_PKEY* pkey = X509_REQ_get_pubkey(req);
  CHECK_CALL(pkey);

  EC_KEY* eckey = EVP_PKEY_get1_EC_KEY(pkey);
  CHECK_CALL(eckey);

  const EC_POINT* old_point = EC_KEY_get0_public_key(eckey);
  CHECK_CALL(old_point);

  //EC_DEBUG("pub", EC_KEY_get0_group(eckey), old_point, ctx);

  // Covert to point on our curve
  // Get x, y 
  BIGNUM* x = BN_new();
  BIGNUM* y = BN_new();
  CHECK_CALL(EC_POINT_get_affine_coordinates_GFp(EC_KEY_get0_group(eckey),
        old_point, x, y, ctx));

  // Create new point
  EC_POINT* new_point = EC_POINT_new(curve);
  CHECK_CALL(EC_POINT_set_affine_coordinates_GFp(curve, new_point, x, y, ctx));

  BN_free(x);
  BN_free(y);

  // Get g^x'
  CHECK_CALL(ea->x_prime);
  EC_POINT* tmp = DsaParams_MultiplyG(ea->params, ea->x_prime);
  CHECK_CALL(EC_POINT_invert(DsaParams_GetCurve(ea->params), tmp, ctx));
  CHECK_CALL(tmp);

  // g^x = A / g^x'
  EC_POINT* g_to_the_x = DsaParams_Add(ea->params, tmp, new_point);
  CHECK_CALL(g_to_the_x);

  PedersenStatement st = PedersenStatement_New(curve,
      DsaParams_GetG(ea->params), DsaParams_GetH(ea->params), 
      ea->commit_x, g_to_the_x);
  EC_DEBUG("g_to_the_x", curve, g_to_the_x, ctx);
  EC_DEBUG("pk", curve, new_point, ctx);
  EC_DEBUG("commit_x", curve, ea->commit_x, ctx);

  if(!PedersenEvidence_Verify(ev, st))
    fatal("Evidence failed to verify!");

  ea->cert = RequestToCertificate(req, DsaParams_GetEaPrivateKey(ea->params));
  CHECK_CALL(ea->cert);

  PedersenStatement_Free(st);
  EC_POINT_free(g_to_the_x);
  EC_POINT_free(tmp);
  EC_POINT_free(new_point);
  EC_KEY_free(eckey);
  EVP_PKEY_free(pkey);
  return true;
}

bool DsaEa_GetCertResponse(DsaEa ea, X509** cert)
{
  //X509_print_fp(stderr, ea->cert);
  *cert = X509_dup(ea->cert);
  return (*cert != NULL);
}

back to top