#include "jpake.h"

#include <openssl/crypto.h>
#include <openssl/sha.h>
#include <openssl/err.h>
#include <memory.h>

/*
 * In the definition, (xa, xb, xc, xd) are Alice's (x1, x2, x3, x4) or
 * Bob's (x3, x4, x1, x2). If you see what I mean.
 */

typedef struct
    {
    char *name;  /* Must be unique */
    char *peer_name;
    BIGNUM *p;
    BIGNUM *g;
    BIGNUM *q;
    BIGNUM *gxc; /* Alice's g^{x3} or Bob's g^{x1} */
    BIGNUM *gxd; /* Alice's g^{x4} or Bob's g^{x2} */
    } JPAKE_CTX_PUBLIC;

struct JPAKE_CTX
    {
    JPAKE_CTX_PUBLIC p;
    BIGNUM *secret;   /* The shared secret */
    BN_CTX *ctx;
    BIGNUM *xa;       /* Alice's x1 or Bob's x3 */
    BIGNUM *xb;       /* Alice's x2 or Bob's x4 */
    BIGNUM *key;      /* The calculated (shared) key */
    };

static void JPAKE_ZKP_init(JPAKE_ZKP *zkp)
    {
    zkp->gr = BN_new();
    zkp->b = BN_new();
    }

static void JPAKE_ZKP_release(JPAKE_ZKP *zkp)
    {
    BN_free(zkp->b);
    BN_free(zkp->gr);
    }

/* Two birds with one stone - make the global name as expected */
#define JPAKE_STEP_PART_init	JPAKE_STEP2_init
#define JPAKE_STEP_PART_release	JPAKE_STEP2_release

void JPAKE_STEP_PART_init(JPAKE_STEP_PART *p)
    {
    p->gx = BN_new();
    JPAKE_ZKP_init(&p->zkpx);
    }

void JPAKE_STEP_PART_release(JPAKE_STEP_PART *p)
    {
    JPAKE_ZKP_release(&p->zkpx);
    BN_free(p->gx);
    }

void JPAKE_STEP1_init(JPAKE_STEP1 *s1)
    {
    JPAKE_STEP_PART_init(&s1->p1);
    JPAKE_STEP_PART_init(&s1->p2);
    }

void JPAKE_STEP1_release(JPAKE_STEP1 *s1)
    {
    JPAKE_STEP_PART_release(&s1->p2);
    JPAKE_STEP_PART_release(&s1->p1);
    }

static void JPAKE_CTX_init(JPAKE_CTX *ctx, const char *name,
			   const char *peer_name, const BIGNUM *p,
			   const BIGNUM *g, const BIGNUM *q,
			   const BIGNUM *secret)
    {
    ctx->p.name = OPENSSL_strdup(name);
    ctx->p.peer_name = OPENSSL_strdup(peer_name);
    ctx->p.p = BN_dup(p);
    ctx->p.g = BN_dup(g);
    ctx->p.q = BN_dup(q);
    ctx->secret = BN_dup(secret);

    ctx->p.gxc = BN_new();
    ctx->p.gxd = BN_new();

    ctx->xa = BN_new();
    ctx->xb = BN_new();
    ctx->key = BN_new();
    ctx->ctx = BN_CTX_new();
    }
    
static void JPAKE_CTX_release(JPAKE_CTX *ctx)
    {
    BN_CTX_free(ctx->ctx);
    BN_clear_free(ctx->key);
    BN_clear_free(ctx->xb);
    BN_clear_free(ctx->xa);

    BN_free(ctx->p.gxd);
    BN_free(ctx->p.gxc);

    BN_clear_free(ctx->secret);
    BN_free(ctx->p.q);
    BN_free(ctx->p.g);
    BN_free(ctx->p.p);
    OPENSSL_free(ctx->p.peer_name);
    OPENSSL_free(ctx->p.name);

    memset(ctx, '\0', sizeof *ctx);
    }
    
JPAKE_CTX *JPAKE_CTX_new(const char *name, const char *peer_name,
			 const BIGNUM *p, const BIGNUM *g, const BIGNUM *q,
			 const BIGNUM *secret)
    {
    JPAKE_CTX *ctx = OPENSSL_malloc(sizeof *ctx);

    JPAKE_CTX_init(ctx, name, peer_name, p, g, q, secret);

    return ctx;
    }

void JPAKE_CTX_free(JPAKE_CTX *ctx)
    {
    JPAKE_CTX_release(ctx);
    OPENSSL_free(ctx);
    }

static void hashlength(SHA_CTX *sha, size_t l)
    {
    unsigned char b[2];

    OPENSSL_assert(l <= 0xffff);
    b[0] = l >> 8;
    b[1] = l&0xff;
    SHA1_Update(sha, b, 2);
    }

static void hashstring(SHA_CTX *sha, const char *string)
    {
    size_t l = strlen(string);

    hashlength(sha, l);
    SHA1_Update(sha, string, l);
    }

static void hashbn(SHA_CTX *sha, const BIGNUM *bn)
    {
    size_t l = BN_num_bytes(bn);
    unsigned char *bin = OPENSSL_malloc(l);

    hashlength(sha, l);
    BN_bn2bin(bn, bin);
    SHA1_Update(sha, bin, l);
    OPENSSL_free(bin);
    }

/* h=hash(g, g^r, g^x, name) */
static void zkp_hash(BIGNUM *h, const BIGNUM *zkpg, const JPAKE_STEP_PART *p,
		     const char *proof_name)
    {
    unsigned char md[SHA_DIGEST_LENGTH];
    SHA_CTX sha;

   /*
    * XXX: hash should not allow moving of the boundaries - Java code
    * is flawed in this respect. Length encoding seems simplest.
    */
    SHA1_Init(&sha);
    hashbn(&sha, zkpg);
    OPENSSL_assert(!BN_is_zero(p->zkpx.gr));
    hashbn(&sha, p->zkpx.gr);
    hashbn(&sha, p->gx);
    hashstring(&sha, proof_name);
    SHA1_Final(md, &sha);
    BN_bin2bn(md, SHA_DIGEST_LENGTH, h);
    }

/*
 * Prove knowledge of x
 * Note that p->gx has already been calculated
 */
static void generate_zkp(JPAKE_STEP_PART *p, const BIGNUM *x,
			 const BIGNUM *zkpg, JPAKE_CTX *ctx)
    {
    BIGNUM *r = BN_new();
    BIGNUM *h = BN_new();
    BIGNUM *t = BN_new();

   /*
    * r in [0,q)
    * XXX: Java chooses r in [0, 2^160) - i.e. distribution not uniform
    */
    BN_rand_range(r, ctx->p.q);
   /* g^r */
    BN_mod_exp(p->zkpx.gr, zkpg, r, ctx->p.p, ctx->ctx);

   /* h=hash... */
    zkp_hash(h, zkpg, p, ctx->p.name);

   /* b = r - x*h */
    BN_mod_mul(t, x, h, ctx->p.q, ctx->ctx);
    BN_mod_sub(p->zkpx.b, r, t, ctx->p.q, ctx->ctx);

   /* cleanup */
    BN_free(t);
    BN_free(h);
    BN_free(r);
    }

static int verify_zkp(const JPAKE_STEP_PART *p, const BIGNUM *zkpg,
		      JPAKE_CTX *ctx)
    {
    BIGNUM *h = BN_new();
    BIGNUM *t1 = BN_new();
    BIGNUM *t2 = BN_new();
    BIGNUM *t3 = BN_new();
    int ret = 0;

    zkp_hash(h, zkpg, p, ctx->p.peer_name);

   /* t1 = g^b */
    BN_mod_exp(t1, zkpg, p->zkpx.b, ctx->p.p, ctx->ctx);
   /* t2 = (g^x)^h = g^{hx} */
    BN_mod_exp(t2, p->gx, h, ctx->p.p, ctx->ctx);
   /* t3 = t1 * t2 = g^{hx} * g^b = g^{hx+b} = g^r (allegedly) */
    BN_mod_mul(t3, t1, t2, ctx->p.p, ctx->ctx);

   /* verify t3 == g^r */
    if(BN_cmp(t3, p->zkpx.gr) == 0)
	ret = 1;
    else
	JPAKEerr(JPAKE_F_VERIFY_ZKP, JPAKE_R_ZKP_VERIFY_FAILED);

   /* cleanup */
    BN_free(t3);
    BN_free(t2);
    BN_free(t1);
    BN_free(h);

    return ret;
    }    

static void generate_step_part(JPAKE_STEP_PART *p, const BIGNUM *x,
			       const BIGNUM *g, JPAKE_CTX *ctx)
    {
    BN_mod_exp(p->gx, g, x, ctx->p.p, ctx->ctx);
    generate_zkp(p, x, g, ctx);
    }

/* Generate each party's random numbers. xa is in [0, q), xb is in [1, q). */
static void genrand(JPAKE_CTX *ctx)
    {
    BIGNUM *qm1;

   /* xa in [0, q) */
    BN_rand_range(ctx->xa, ctx->p.q);

   /* q-1 */
    qm1 = BN_new();
    BN_copy(qm1, ctx->p.q);
    BN_sub_word(qm1, 1);

   /* ... and xb in [0, q-1) */
    BN_rand_range(ctx->xb, qm1);
   /* [1, q) */
    BN_add_word(ctx->xb, 1);

   /* cleanup */
    BN_free(qm1);
    }

int JPAKE_STEP1_generate(JPAKE_STEP1 *send, JPAKE_CTX *ctx)
    {
    genrand(ctx);
    generate_step_part(&send->p1, ctx->xa, ctx->p.g, ctx);
    generate_step_part(&send->p2, ctx->xb, ctx->p.g, ctx);

    return 1;
    }

/* g^x is a legal value */
static int is_legal(const BIGNUM *gx, const JPAKE_CTX *ctx)
    {
    BIGNUM *t;
    int res;
    
    if(BN_is_negative(gx) || BN_is_zero(gx) || BN_cmp(gx, ctx->p.p) >= 0)
	return 0;

    t = BN_new();
    BN_mod_exp(t, gx, ctx->p.q, ctx->p.p, ctx->ctx);
    res = BN_is_one(t);
    BN_free(t);

    return res;
    }

int JPAKE_STEP1_process(JPAKE_CTX *ctx, const JPAKE_STEP1 *received)
    {
    if(!is_legal(received->p1.gx, ctx))
	{
	JPAKEerr(JPAKE_F_JPAKE_STEP1_PROCESS, JPAKE_R_G_TO_THE_X3_IS_NOT_LEGAL);
	return 0;
	}

    if(!is_legal(received->p2.gx, ctx))
	{
	JPAKEerr(JPAKE_F_JPAKE_STEP1_PROCESS, JPAKE_R_G_TO_THE_X4_IS_NOT_LEGAL);
	return 0;
	}

   /* verify their ZKP(xc) */
    if(!verify_zkp(&received->p1, ctx->p.g, ctx))
	{
	JPAKEerr(JPAKE_F_JPAKE_STEP1_PROCESS, JPAKE_R_VERIFY_X3_FAILED);
	return 0;
	}

   /* verify their ZKP(xd) */
    if(!verify_zkp(&received->p2, ctx->p.g, ctx))
	{
	JPAKEerr(JPAKE_F_JPAKE_STEP1_PROCESS, JPAKE_R_VERIFY_X4_FAILED);
	return 0;
	}

   /* g^xd != 1 */
    if(BN_is_one(received->p2.gx))
	{
	JPAKEerr(JPAKE_F_JPAKE_STEP1_PROCESS, JPAKE_R_G_TO_THE_X4_IS_ONE);
	return 0;
	}

   /* Save the bits we need for later */
    BN_copy(ctx->p.gxc, received->p1.gx);
    BN_copy(ctx->p.gxd, received->p2.gx);

    return 1;
    }


int JPAKE_STEP2_generate(JPAKE_STEP2 *send, JPAKE_CTX *ctx)
    {
    BIGNUM *t1 = BN_new();
    BIGNUM *t2 = BN_new();

   /*
    * X = g^{(xa + xc + xd) * xb * s}
    * t1 = g^xa
    */
    BN_mod_exp(t1, ctx->p.g, ctx->xa, ctx->p.p, ctx->ctx);
   /* t2 = t1 * g^{xc} = g^{xa} * g^{xc} = g^{xa + xc} */
    BN_mod_mul(t2, t1, ctx->p.gxc, ctx->p.p, ctx->ctx);
   /* t1 = t2 * g^{xd} = g^{xa + xc + xd} */
    BN_mod_mul(t1, t2, ctx->p.gxd, ctx->p.p, ctx->ctx);
   /* t2 = xb * s */
    BN_mod_mul(t2, ctx->xb, ctx->secret, ctx->p.q, ctx->ctx);

   /*
    * ZKP(xb * s)
    * XXX: this is kinda funky, because we're using
    *
    * g' = g^{xa + xc + xd}
    *
    * as the generator, which means X is g'^{xb * s}
    * X = t1^{t2} = t1^{xb * s} = g^{(xa + xc + xd) * xb * s}
    */
    generate_step_part(send, t2, t1, ctx);

   /* cleanup */
    BN_free(t1);
    BN_free(t2);

    return 1;
    }

/* gx = g^{xc + xa + xb} * xd * s */
static int compute_key(JPAKE_CTX *ctx, const BIGNUM *gx)
    {
    BIGNUM *t1 = BN_new();
    BIGNUM *t2 = BN_new();
    BIGNUM *t3 = BN_new();

   /*
    * K = (gx/g^{xb * xd * s})^{xb}
    *   = (g^{(xc + xa + xb) * xd * s - xb * xd *s})^{xb}
    *   = (g^{(xa + xc) * xd * s})^{xb}
    *   = g^{(xa + xc) * xb * xd * s}
    * [which is the same regardless of who calculates it]
    */

   /* t1 = (g^{xd})^{xb} = g^{xb * xd} */
    BN_mod_exp(t1, ctx->p.gxd, ctx->xb, ctx->p.p, ctx->ctx);
   /* t2 = -s = q-s */
    BN_sub(t2, ctx->p.q, ctx->secret);
   /* t3 = t1^t2 = g^{-xb * xd * s} */
    BN_mod_exp(t3, t1, t2, ctx->p.p, ctx->ctx);
   /* t1 = gx * t3 = X/g^{xb * xd * s} */
    BN_mod_mul(t1, gx, t3, ctx->p.p, ctx->ctx);
   /* K = t1^{xb} */
    BN_mod_exp(ctx->key, t1, ctx->xb, ctx->p.p, ctx->ctx);

   /* cleanup */
    BN_free(t3);
    BN_free(t2);
    BN_free(t1);

    return 1;
    }

int JPAKE_STEP2_process(JPAKE_CTX *ctx, const JPAKE_STEP2 *received)
    {
    BIGNUM *t1 = BN_new();
    BIGNUM *t2 = BN_new();
    int ret = 0;

   /*
    * g' = g^{xc + xa + xb} [from our POV]
    * t1 = xa + xb
    */
    BN_mod_add(t1, ctx->xa, ctx->xb, ctx->p.q, ctx->ctx);
   /* t2 = g^{t1} = g^{xa+xb} */
    BN_mod_exp(t2, ctx->p.g, t1, ctx->p.p, ctx->ctx);
   /* t1 = g^{xc} * t2 = g^{xc + xa + xb} */
    BN_mod_mul(t1, ctx->p.gxc, t2, ctx->p.p, ctx->ctx);

    if(verify_zkp(received, t1, ctx))
	ret = 1;
    else
	JPAKEerr(JPAKE_F_JPAKE_STEP2_PROCESS, JPAKE_R_VERIFY_B_FAILED);

    compute_key(ctx, received->gx);

   /* cleanup */
    BN_free(t2);
    BN_free(t1);

    return ret;
    }

static void quickhashbn(unsigned char *md, const BIGNUM *bn)
    {
    SHA_CTX sha;

    SHA1_Init(&sha);
    hashbn(&sha, bn);
    SHA1_Final(md, &sha);
    }

void JPAKE_STEP3A_init(JPAKE_STEP3A *s3a)
    {}

int JPAKE_STEP3A_generate(JPAKE_STEP3A *send, JPAKE_CTX *ctx)
    {
    quickhashbn(send->hhk, ctx->key);
    SHA1(send->hhk, sizeof send->hhk, send->hhk);

    return 1;
    }

int JPAKE_STEP3A_process(JPAKE_CTX *ctx, const JPAKE_STEP3A *received)
    {
    unsigned char hhk[SHA_DIGEST_LENGTH];

    quickhashbn(hhk, ctx->key);
    SHA1(hhk, sizeof hhk, hhk);
    if(memcmp(hhk, received->hhk, sizeof hhk))
	{
	JPAKEerr(JPAKE_F_JPAKE_STEP3A_PROCESS, JPAKE_R_HASH_OF_HASH_OF_KEY_MISMATCH);
	return 0;
	}
    return 1;
    }

void JPAKE_STEP3A_release(JPAKE_STEP3A *s3a)
    {}

void JPAKE_STEP3B_init(JPAKE_STEP3B *s3b)
    {}

int JPAKE_STEP3B_generate(JPAKE_STEP3B *send, JPAKE_CTX *ctx)
    {
    quickhashbn(send->hk, ctx->key);

    return 1;
    }

int JPAKE_STEP3B_process(JPAKE_CTX *ctx, const JPAKE_STEP3B *received)
    {
    unsigned char hk[SHA_DIGEST_LENGTH];

    quickhashbn(hk, ctx->key);
    if(memcmp(hk, received->hk, sizeof hk))
	{
	JPAKEerr(JPAKE_F_JPAKE_STEP3B_PROCESS, JPAKE_R_HASH_OF_KEY_MISMATCH);
	return 0;
	}
    return 1;
    }

void JPAKE_STEP3B_release(JPAKE_STEP3B *s3b)
    {}

const BIGNUM *JPAKE_get_shared_key(JPAKE_CTX *ctx)
    {
    return ctx->key;
    }

