#include "jpake.h"

#include <openssl/crypto.h>
#include <openssl/sha.h>
#include <openssl/err.h>
#include <memory.h>
#include <string.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);
    if (ctx == NULL)
        return NULL;

    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 int hashbn(SHA_CTX *sha, const BIGNUM *bn)
    {
    size_t l = BN_num_bytes(bn);
    unsigned char *bin = OPENSSL_malloc(l);

    if (bin == NULL)
	return 0;

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

/* h=hash(g, g^r, g^x, name) */
static int 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);
    if (!hashbn(&sha, zkpg))
	return 0;
    OPENSSL_assert(!BN_is_zero(p->zkpx.gr));
    if (!hashbn(&sha, p->zkpx.gr))
	return 0;
    if (!hashbn(&sha, p->gx))
	return 0;
    hashstring(&sha, proof_name);
    SHA1_Final(md, &sha);
    BN_bin2bn(md, SHA_DIGEST_LENGTH, h);
    return 1;
    }

/*
 * Prove knowledge of x
 * Note that p->gx has already been calculated
 */
static int generate_zkp(JPAKE_STEP_PART *p, const BIGNUM *x,
			 const BIGNUM *zkpg, JPAKE_CTX *ctx)
    {
    int res = 0;
    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... */
    if (!zkp_hash(h, zkpg, p, ctx->p.name))
	goto end;

   /* 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);

    res = 1;
end:
   /* cleanup */
    BN_free(t);
    BN_free(h);
    BN_free(r);
    return res;
    }

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;

    if (!zkp_hash(h, zkpg, p, ctx->p.peer_name))
	goto end;

   /* 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);

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

    return ret;
    }    

static int 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);
    if (!generate_zkp(p, x, g, ctx))
	return 0;
    return 1;
    }

/* 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);
    if (!generate_step_part(&send->p1, ctx->xa, ctx->p.g, ctx))
	return 0;
    if (!generate_step_part(&send->p2, ctx->xb, ctx->p.g, ctx))
	return 0;

    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)
    {
    int ret;

    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}
    */
    ret = generate_step_part(send, t2, t1, ctx);

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

    return ret;
    }

/* 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 int quickhashbn(unsigned char *md, const BIGNUM *bn)
    {
    SHA_CTX sha;

    SHA1_Init(&sha);
    if (!hashbn(&sha, bn))
	return 0;
    SHA1_Final(md, &sha);
    return 1;
    }

void JPAKE_STEP3A_init(JPAKE_STEP3A *s3a)
    {}

int JPAKE_STEP3A_generate(JPAKE_STEP3A *send, JPAKE_CTX *ctx)
    {
    if (!quickhashbn(send->hhk, ctx->key))
	return 0;
    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];

    if (!quickhashbn(hhk, ctx->key))
	return 0;
    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)
    {
    if (!quickhashbn(send->hk, ctx->key))
	return 0;
    return 1;
    }

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

    if (!quickhashbn(hk, ctx->key))
	return 0;
    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;
    }

