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
test_integer_group.c
#include <stdbool.h>
#include <stdio.h>

#include <openssl/bn.h>

#include "integer_group.h"
#include "test_common.h"

void mu_test_IntegerGroup_New()
{
  const int bits = 100;
  IntegerGroup g = IntegerGroup_Generate(bits);
  mu_check(IntegerGroup_GetP(g));
  mu_check(IntegerGroup_GetQ(g));
  mu_check(IntegerGroup_GetG(g));
  mu_check(IntegerGroup_GetH(g));
  IntegerGroup_Free(g);
}

void mu_test_IntegerGroup_Generators() 
{
  const int bits = 100;

  IntegerGroup group = IntegerGroup_Generate(bits);
  const BIGNUM *p = IntegerGroup_GetP(group);
  const BIGNUM *q = IntegerGroup_GetQ(group);
  const BIGNUM *g = IntegerGroup_GetG(group);
  const BIGNUM *h = IntegerGroup_GetH(group);

  mu_ensure(p);
  mu_ensure(q);
  mu_ensure(g);
  mu_ensure(h);
  mu_check(BN_cmp(g, h));

  BN_CTX* ctx = BN_CTX_new();
  BIGNUM* tmp = BN_new();
  mu_ensure(tmp);

  // Check that (g^q == 1  mod p)
  mu_ensure(BN_mod_exp(tmp, g, q, p, ctx));
  mu_check(BN_is_one(tmp));

  // Check that (h^q == 1  mod p)
  mu_ensure(BN_mod_exp(tmp, h, q, p, ctx));
  mu_check(BN_is_one(tmp));

  // Check that (g^2 != 1 mod p)
  mu_ensure(BN_mod_sqr(tmp, g, p, ctx));
  mu_check(!BN_is_one(tmp));

  // Check that (h^2 != 1 mod p)
  mu_ensure(BN_mod_sqr(tmp, h, p, ctx));
  mu_check(!BN_is_one(tmp));

  // Check that p is prime
  mu_check(BN_is_prime(p, BN_prime_checks, NULL, ctx, NULL));

  // Check that q is prime
  mu_check(BN_is_prime(q, BN_prime_checks, NULL, ctx, NULL));

  // Check that 2q+1 = p
  mu_ensure(BN_copy(tmp, q));
  mu_ensure(BN_mul_word(tmp, 2));
  mu_ensure(BN_add_word(tmp, 1));
  mu_check(!BN_cmp(tmp, p));

  BN_free(tmp);

  IntegerGroup_Free(group);
  BN_CTX_free(ctx); 
}


void mu_test_IntegerGroup_Serialize() 
{
  const int bits = 115;
  IntegerGroup group = IntegerGroup_Generate(bits);

  // Save params
  const BIGNUM *p = IntegerGroup_GetP(group);
  const BIGNUM *q = IntegerGroup_GetQ(group);
  const BIGNUM *g = IntegerGroup_GetG(group);
  const BIGNUM *h = IntegerGroup_GetH(group);

  // Write params to temp file
  FILE *file = tmpfile();
  mu_ensure(file);
  mu_ensure(IntegerGroup_Serialize(group, file));

  // Read params from file
  rewind(file);

  IntegerGroup group2 = IntegerGroup_Unserialize(file);
  mu_ensure(group2);

  fclose(file);

  // Make sure params match saved ones
  mu_check(!BN_cmp(p, IntegerGroup_GetP(group2)));
  mu_check(!BN_cmp(q, IntegerGroup_GetQ(group2)));
  mu_check(!BN_cmp(g, IntegerGroup_GetG(group2)));
  mu_check(!BN_cmp(h, IntegerGroup_GetH(group2)));

  // Delete params
  IntegerGroup_Free(group);
  IntegerGroup_Free(group2);
}

void mu_test_IntegerGroup_RandomExponent() 
{
  const int bits = 120;
  IntegerGroup group = IntegerGroup_Generate(bits);

  for(int i=0; i<50; i++) {
    BIGNUM* rnd = IntegerGroup_RandomExponent(group);
    mu_check(BN_cmp(rnd, IntegerGroup_GetQ(group)));
    mu_check(!BN_is_negative(rnd));
    BN_free(rnd);
  }

  IntegerGroup_Free(group);
}

void mu_test_IntegerGroup_Commit() 
{
  const int bits = 120;
  IntegerGroup group = IntegerGroup_Generate(bits);
  const BIGNUM *p = IntegerGroup_GetP(group);
  const BIGNUM *g = IntegerGroup_GetG(group);
  const BIGNUM *h = IntegerGroup_GetH(group);
  BN_CTX *ctx = BN_CTX_new();

  for(int i=0; i<50; i++) {
    BIGNUM* v = IntegerGroup_RandomExponent(group);
    mu_ensure(v);

    BIGNUM* r = IntegerGroup_RandomExponent(group);
    mu_ensure(r);

    BIGNUM* c = IntegerGroup_Commit(group, v, r);
    mu_ensure(c);

    mu_ensure(BN_mod_exp(v, g, v, p, ctx));
    mu_ensure(BN_mod_exp(r, h, r, p, ctx));
    mu_ensure(BN_mod_mul(v, v, r, p, ctx));

    mu_check(!BN_cmp(v, c));

    BN_free(v);
    BN_free(r);
    BN_free(c);
  }

  IntegerGroup_Free(group);
  BN_CTX_free(ctx);
}

void mu_test_IntegerGroup_Inverse() 
{
  const int bits = 250;
  IntegerGroup group = IntegerGroup_Generate(bits);
  const BIGNUM *p = IntegerGroup_GetP(group);
  BN_CTX *ctx = BN_CTX_new();

  for(int i=0; i<50; i++) {
    BIGNUM* a = IntegerGroup_RandomElement(group);
    mu_ensure(a);
    mu_ensure(IntegerGroup_IsElement(group, a));

    BIGNUM* a_inv = IntegerGroup_Inverse(group, a);
    mu_ensure(a_inv);
    mu_ensure(IntegerGroup_IsElement(group, a_inv));

    mu_ensure(BN_mod_mul(a, a, a_inv, p, ctx));
    mu_ensure(BN_is_one(a));

    BN_free(a);
    BN_free(a_inv);
  }

  IntegerGroup_Free(group);
  BN_CTX_free(ctx);
}

void mu_test_IntegerGroup_Exponentiate() 
{
  const int bits = 120;
  IntegerGroup group = IntegerGroup_Generate(bits);
  const BIGNUM *p = IntegerGroup_GetP(group);
  BN_CTX *ctx = BN_CTX_new();

  for(int i=0; i<50; i++) {
    BIGNUM* g = IntegerGroup_RandomElement(group);
    mu_ensure(g);
    mu_ensure(IntegerGroup_IsElement(group, g));

    BIGNUM* x = IntegerGroup_RandomExponent(group);
    mu_ensure(x);

    BIGNUM* y = IntegerGroup_Exponentiate(group, g, x);
    mu_ensure(y);
    mu_ensure(IntegerGroup_IsElement(group, y));


    mu_ensure(BN_mod_exp(g, g, x, p, ctx));

    mu_check(!BN_cmp(g, y));

    BN_free(g);
    BN_free(x);
    BN_free(y);
  }

  IntegerGroup_Free(group);
  BN_CTX_free(ctx);
}

void mu_test_IntegerGroup_CascadeExponentiate() 
{
  const int bits = 120;
  IntegerGroup group = IntegerGroup_Generate(bits);
  const BIGNUM *p = IntegerGroup_GetP(group);
  BN_CTX *ctx = BN_CTX_new();

  for(int i=0; i<50; i++) {
    BIGNUM* g1 = IntegerGroup_RandomElement(group);
    BIGNUM* g2 = IntegerGroup_RandomElement(group);
    mu_ensure(g1);
    mu_ensure(g2);
    mu_ensure(IntegerGroup_IsElement(group, g1));
    mu_ensure(IntegerGroup_IsElement(group, g2));

    BIGNUM* x1 = IntegerGroup_RandomExponent(group);
    BIGNUM* x2 = IntegerGroup_RandomExponent(group);
    mu_ensure(x1);
    mu_ensure(x2);

    BIGNUM* y = IntegerGroup_CascadeExponentiate(group, g1, x1, g2, x2);
    BIGNUM* r1 = BN_new();
    BIGNUM* r2 = BN_new();
    mu_ensure(y);
    mu_ensure(r1);
    mu_ensure(r2);

    mu_ensure(BN_mod_exp(r1, g1, x1, p, ctx));
    mu_ensure(BN_mod_exp(r2, g2, x2, p, ctx));
    mu_ensure(BN_mod_mul(r1, r1, r2, p, ctx));

    mu_check(!BN_cmp(r1, y));
    mu_ensure(IntegerGroup_IsElement(group, y));

    BN_free(r1);
    BN_free(r2);
    BN_free(g1);
    BN_free(g2);
    BN_free(x1);
    BN_free(x2);
    BN_free(y);
  }

  IntegerGroup_Free(group);
  BN_CTX_free(ctx);
}

back to top