1e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu#include "jpake.h" 2e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 3e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu#include <openssl/crypto.h> 4e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu#include <openssl/sha.h> 5e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu#include <openssl/err.h> 6e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu#include <memory.h> 7e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 8e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu/* 9e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu * In the definition, (xa, xb, xc, xd) are Alice's (x1, x2, x3, x4) or 10e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu * Bob's (x3, x4, x1, x2). If you see what I mean. 11e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu */ 12e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 13e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugutypedef struct 14e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu { 15e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu char *name; /* Must be unique */ 16e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu char *peer_name; 17e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BIGNUM *p; 18e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BIGNUM *g; 19e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BIGNUM *q; 20e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BIGNUM *gxc; /* Alice's g^{x3} or Bob's g^{x1} */ 21e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BIGNUM *gxd; /* Alice's g^{x4} or Bob's g^{x2} */ 22e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu } JPAKE_CTX_PUBLIC; 23e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 24e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugustruct JPAKE_CTX 25e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu { 26e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu JPAKE_CTX_PUBLIC p; 27e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BIGNUM *secret; /* The shared secret */ 28e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BN_CTX *ctx; 29e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BIGNUM *xa; /* Alice's x1 or Bob's x3 */ 30e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BIGNUM *xb; /* Alice's x2 or Bob's x4 */ 31e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BIGNUM *key; /* The calculated (shared) key */ 32e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu }; 33e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 34e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugustatic void JPAKE_ZKP_init(JPAKE_ZKP *zkp) 35e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu { 36e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu zkp->gr = BN_new(); 37e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu zkp->b = BN_new(); 38e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu } 39e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 40e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugustatic void JPAKE_ZKP_release(JPAKE_ZKP *zkp) 41e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu { 42e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BN_free(zkp->b); 43e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BN_free(zkp->gr); 44e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu } 45e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 46e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu/* Two birds with one stone - make the global name as expected */ 47e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu#define JPAKE_STEP_PART_init JPAKE_STEP2_init 48e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu#define JPAKE_STEP_PART_release JPAKE_STEP2_release 49e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 50e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modaduguvoid JPAKE_STEP_PART_init(JPAKE_STEP_PART *p) 51e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu { 52e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu p->gx = BN_new(); 53e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu JPAKE_ZKP_init(&p->zkpx); 54e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu } 55e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 56e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modaduguvoid JPAKE_STEP_PART_release(JPAKE_STEP_PART *p) 57e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu { 58e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu JPAKE_ZKP_release(&p->zkpx); 59e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BN_free(p->gx); 60e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu } 61e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 62e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modaduguvoid JPAKE_STEP1_init(JPAKE_STEP1 *s1) 63e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu { 64e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu JPAKE_STEP_PART_init(&s1->p1); 65e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu JPAKE_STEP_PART_init(&s1->p2); 66e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu } 67e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 68e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modaduguvoid JPAKE_STEP1_release(JPAKE_STEP1 *s1) 69e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu { 70e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu JPAKE_STEP_PART_release(&s1->p2); 71e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu JPAKE_STEP_PART_release(&s1->p1); 72e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu } 73e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 74e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugustatic void JPAKE_CTX_init(JPAKE_CTX *ctx, const char *name, 75e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu const char *peer_name, const BIGNUM *p, 76e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu const BIGNUM *g, const BIGNUM *q, 77e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu const BIGNUM *secret) 78e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu { 79e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu ctx->p.name = OPENSSL_strdup(name); 80e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu ctx->p.peer_name = OPENSSL_strdup(peer_name); 81e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu ctx->p.p = BN_dup(p); 82e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu ctx->p.g = BN_dup(g); 83e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu ctx->p.q = BN_dup(q); 84e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu ctx->secret = BN_dup(secret); 85e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 86e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu ctx->p.gxc = BN_new(); 87e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu ctx->p.gxd = BN_new(); 88e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 89e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu ctx->xa = BN_new(); 90e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu ctx->xb = BN_new(); 91e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu ctx->key = BN_new(); 92e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu ctx->ctx = BN_CTX_new(); 93e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu } 94e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 95e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugustatic void JPAKE_CTX_release(JPAKE_CTX *ctx) 96e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu { 97e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BN_CTX_free(ctx->ctx); 98e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BN_clear_free(ctx->key); 99e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BN_clear_free(ctx->xb); 100e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BN_clear_free(ctx->xa); 101e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 102e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BN_free(ctx->p.gxd); 103e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BN_free(ctx->p.gxc); 104e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 105e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BN_clear_free(ctx->secret); 106e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BN_free(ctx->p.q); 107e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BN_free(ctx->p.g); 108e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BN_free(ctx->p.p); 109e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu OPENSSL_free(ctx->p.peer_name); 110e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu OPENSSL_free(ctx->p.name); 111e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 112e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu memset(ctx, '\0', sizeof *ctx); 113e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu } 114e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 115e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra ModaduguJPAKE_CTX *JPAKE_CTX_new(const char *name, const char *peer_name, 116e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu const BIGNUM *p, const BIGNUM *g, const BIGNUM *q, 117e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu const BIGNUM *secret) 118e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu { 119e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu JPAKE_CTX *ctx = OPENSSL_malloc(sizeof *ctx); 120e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 121e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu JPAKE_CTX_init(ctx, name, peer_name, p, g, q, secret); 122e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 123e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu return ctx; 124e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu } 125e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 126e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modaduguvoid JPAKE_CTX_free(JPAKE_CTX *ctx) 127e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu { 128e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu JPAKE_CTX_release(ctx); 129e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu OPENSSL_free(ctx); 130e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu } 131e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 132e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugustatic void hashlength(SHA_CTX *sha, size_t l) 133e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu { 134e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu unsigned char b[2]; 135e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 136221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom OPENSSL_assert(l <= 0xffff); 137e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu b[0] = l >> 8; 138e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu b[1] = l&0xff; 139e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu SHA1_Update(sha, b, 2); 140e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu } 141e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 142e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugustatic void hashstring(SHA_CTX *sha, const char *string) 143e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu { 144e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu size_t l = strlen(string); 145e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 146e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu hashlength(sha, l); 147e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu SHA1_Update(sha, string, l); 148e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu } 149e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 150e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugustatic void hashbn(SHA_CTX *sha, const BIGNUM *bn) 151e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu { 152e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu size_t l = BN_num_bytes(bn); 153e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu unsigned char *bin = OPENSSL_malloc(l); 154e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 155e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu hashlength(sha, l); 156e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BN_bn2bin(bn, bin); 157e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu SHA1_Update(sha, bin, l); 158e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu OPENSSL_free(bin); 159e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu } 160e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 161e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu/* h=hash(g, g^r, g^x, name) */ 162e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugustatic void zkp_hash(BIGNUM *h, const BIGNUM *zkpg, const JPAKE_STEP_PART *p, 163e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu const char *proof_name) 164e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu { 165e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu unsigned char md[SHA_DIGEST_LENGTH]; 166e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu SHA_CTX sha; 167e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 168e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu /* 169e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu * XXX: hash should not allow moving of the boundaries - Java code 170e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu * is flawed in this respect. Length encoding seems simplest. 171e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu */ 172e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu SHA1_Init(&sha); 173e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu hashbn(&sha, zkpg); 174221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom OPENSSL_assert(!BN_is_zero(p->zkpx.gr)); 175e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu hashbn(&sha, p->zkpx.gr); 176e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu hashbn(&sha, p->gx); 177e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu hashstring(&sha, proof_name); 178e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu SHA1_Final(md, &sha); 179e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BN_bin2bn(md, SHA_DIGEST_LENGTH, h); 180e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu } 181e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 182e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu/* 183e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu * Prove knowledge of x 184e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu * Note that p->gx has already been calculated 185e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu */ 186e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugustatic void generate_zkp(JPAKE_STEP_PART *p, const BIGNUM *x, 187e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu const BIGNUM *zkpg, JPAKE_CTX *ctx) 188e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu { 189e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BIGNUM *r = BN_new(); 190e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BIGNUM *h = BN_new(); 191e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BIGNUM *t = BN_new(); 192e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 193e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu /* 194e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu * r in [0,q) 195e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu * XXX: Java chooses r in [0, 2^160) - i.e. distribution not uniform 196e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu */ 197e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BN_rand_range(r, ctx->p.q); 198e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu /* g^r */ 199e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BN_mod_exp(p->zkpx.gr, zkpg, r, ctx->p.p, ctx->ctx); 200e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 201e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu /* h=hash... */ 202e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu zkp_hash(h, zkpg, p, ctx->p.name); 203e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 204e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu /* b = r - x*h */ 205e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BN_mod_mul(t, x, h, ctx->p.q, ctx->ctx); 206e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BN_mod_sub(p->zkpx.b, r, t, ctx->p.q, ctx->ctx); 207e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 208e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu /* cleanup */ 209e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BN_free(t); 210e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BN_free(h); 211e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BN_free(r); 212e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu } 213e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 214e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugustatic int verify_zkp(const JPAKE_STEP_PART *p, const BIGNUM *zkpg, 215e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu JPAKE_CTX *ctx) 216e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu { 217e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BIGNUM *h = BN_new(); 218e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BIGNUM *t1 = BN_new(); 219e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BIGNUM *t2 = BN_new(); 220e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BIGNUM *t3 = BN_new(); 221e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu int ret = 0; 222e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 223e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu zkp_hash(h, zkpg, p, ctx->p.peer_name); 224e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 225e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu /* t1 = g^b */ 226e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BN_mod_exp(t1, zkpg, p->zkpx.b, ctx->p.p, ctx->ctx); 227e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu /* t2 = (g^x)^h = g^{hx} */ 228e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BN_mod_exp(t2, p->gx, h, ctx->p.p, ctx->ctx); 229e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu /* t3 = t1 * t2 = g^{hx} * g^b = g^{hx+b} = g^r (allegedly) */ 230e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BN_mod_mul(t3, t1, t2, ctx->p.p, ctx->ctx); 231e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 232e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu /* verify t3 == g^r */ 233e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu if(BN_cmp(t3, p->zkpx.gr) == 0) 234e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu ret = 1; 235e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu else 236e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu JPAKEerr(JPAKE_F_VERIFY_ZKP, JPAKE_R_ZKP_VERIFY_FAILED); 237e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 238e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu /* cleanup */ 239e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BN_free(t3); 240e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BN_free(t2); 241e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BN_free(t1); 242e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BN_free(h); 243e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 244e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu return ret; 245e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu } 246e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 247e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugustatic void generate_step_part(JPAKE_STEP_PART *p, const BIGNUM *x, 248e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu const BIGNUM *g, JPAKE_CTX *ctx) 249e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu { 250e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BN_mod_exp(p->gx, g, x, ctx->p.p, ctx->ctx); 251e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu generate_zkp(p, x, g, ctx); 252e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu } 253e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 254e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu/* Generate each party's random numbers. xa is in [0, q), xb is in [1, q). */ 255e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugustatic void genrand(JPAKE_CTX *ctx) 256e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu { 257e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BIGNUM *qm1; 258e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 259e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu /* xa in [0, q) */ 260e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BN_rand_range(ctx->xa, ctx->p.q); 261e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 262e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu /* q-1 */ 263e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu qm1 = BN_new(); 264e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BN_copy(qm1, ctx->p.q); 265e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BN_sub_word(qm1, 1); 266e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 267e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu /* ... and xb in [0, q-1) */ 268e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BN_rand_range(ctx->xb, qm1); 269e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu /* [1, q) */ 270e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BN_add_word(ctx->xb, 1); 271e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 272e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu /* cleanup */ 273e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BN_free(qm1); 274e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu } 275e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 276e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modaduguint JPAKE_STEP1_generate(JPAKE_STEP1 *send, JPAKE_CTX *ctx) 277e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu { 278e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu genrand(ctx); 279e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu generate_step_part(&send->p1, ctx->xa, ctx->p.g, ctx); 280e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu generate_step_part(&send->p2, ctx->xb, ctx->p.g, ctx); 281e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 282e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu return 1; 283e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu } 284e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 285976a034585c7e8ff9dda5ebe032f399b78887f70Brian Carlstrom/* g^x is a legal value */ 286976a034585c7e8ff9dda5ebe032f399b78887f70Brian Carlstromstatic int is_legal(const BIGNUM *gx, const JPAKE_CTX *ctx) 287976a034585c7e8ff9dda5ebe032f399b78887f70Brian Carlstrom { 288976a034585c7e8ff9dda5ebe032f399b78887f70Brian Carlstrom BIGNUM *t; 289976a034585c7e8ff9dda5ebe032f399b78887f70Brian Carlstrom int res; 290976a034585c7e8ff9dda5ebe032f399b78887f70Brian Carlstrom 291976a034585c7e8ff9dda5ebe032f399b78887f70Brian Carlstrom if(BN_is_negative(gx) || BN_is_zero(gx) || BN_cmp(gx, ctx->p.p) >= 0) 292976a034585c7e8ff9dda5ebe032f399b78887f70Brian Carlstrom return 0; 293976a034585c7e8ff9dda5ebe032f399b78887f70Brian Carlstrom 294976a034585c7e8ff9dda5ebe032f399b78887f70Brian Carlstrom t = BN_new(); 295976a034585c7e8ff9dda5ebe032f399b78887f70Brian Carlstrom BN_mod_exp(t, gx, ctx->p.q, ctx->p.p, ctx->ctx); 296976a034585c7e8ff9dda5ebe032f399b78887f70Brian Carlstrom res = BN_is_one(t); 297976a034585c7e8ff9dda5ebe032f399b78887f70Brian Carlstrom BN_free(t); 298976a034585c7e8ff9dda5ebe032f399b78887f70Brian Carlstrom 299976a034585c7e8ff9dda5ebe032f399b78887f70Brian Carlstrom return res; 300976a034585c7e8ff9dda5ebe032f399b78887f70Brian Carlstrom } 301976a034585c7e8ff9dda5ebe032f399b78887f70Brian Carlstrom 302e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modaduguint JPAKE_STEP1_process(JPAKE_CTX *ctx, const JPAKE_STEP1 *received) 303e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu { 304976a034585c7e8ff9dda5ebe032f399b78887f70Brian Carlstrom if(!is_legal(received->p1.gx, ctx)) 305976a034585c7e8ff9dda5ebe032f399b78887f70Brian Carlstrom { 306976a034585c7e8ff9dda5ebe032f399b78887f70Brian Carlstrom JPAKEerr(JPAKE_F_JPAKE_STEP1_PROCESS, JPAKE_R_G_TO_THE_X3_IS_NOT_LEGAL); 307976a034585c7e8ff9dda5ebe032f399b78887f70Brian Carlstrom return 0; 308976a034585c7e8ff9dda5ebe032f399b78887f70Brian Carlstrom } 309976a034585c7e8ff9dda5ebe032f399b78887f70Brian Carlstrom 310976a034585c7e8ff9dda5ebe032f399b78887f70Brian Carlstrom if(!is_legal(received->p2.gx, ctx)) 311976a034585c7e8ff9dda5ebe032f399b78887f70Brian Carlstrom { 312976a034585c7e8ff9dda5ebe032f399b78887f70Brian Carlstrom JPAKEerr(JPAKE_F_JPAKE_STEP1_PROCESS, JPAKE_R_G_TO_THE_X4_IS_NOT_LEGAL); 313976a034585c7e8ff9dda5ebe032f399b78887f70Brian Carlstrom return 0; 314976a034585c7e8ff9dda5ebe032f399b78887f70Brian Carlstrom } 315976a034585c7e8ff9dda5ebe032f399b78887f70Brian Carlstrom 316e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu /* verify their ZKP(xc) */ 317e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu if(!verify_zkp(&received->p1, ctx->p.g, ctx)) 318e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu { 319e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu JPAKEerr(JPAKE_F_JPAKE_STEP1_PROCESS, JPAKE_R_VERIFY_X3_FAILED); 320e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu return 0; 321e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu } 322e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 323e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu /* verify their ZKP(xd) */ 324e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu if(!verify_zkp(&received->p2, ctx->p.g, ctx)) 325e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu { 326e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu JPAKEerr(JPAKE_F_JPAKE_STEP1_PROCESS, JPAKE_R_VERIFY_X4_FAILED); 327e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu return 0; 328e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu } 329e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 330e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu /* g^xd != 1 */ 331e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu if(BN_is_one(received->p2.gx)) 332e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu { 333e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu JPAKEerr(JPAKE_F_JPAKE_STEP1_PROCESS, JPAKE_R_G_TO_THE_X4_IS_ONE); 334e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu return 0; 335e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu } 336e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 337e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu /* Save the bits we need for later */ 338e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BN_copy(ctx->p.gxc, received->p1.gx); 339e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BN_copy(ctx->p.gxd, received->p2.gx); 340e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 341e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu return 1; 342e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu } 343e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 344e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 345e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modaduguint JPAKE_STEP2_generate(JPAKE_STEP2 *send, JPAKE_CTX *ctx) 346e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu { 347e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BIGNUM *t1 = BN_new(); 348e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BIGNUM *t2 = BN_new(); 349e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 350e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu /* 351e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu * X = g^{(xa + xc + xd) * xb * s} 352e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu * t1 = g^xa 353e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu */ 354e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BN_mod_exp(t1, ctx->p.g, ctx->xa, ctx->p.p, ctx->ctx); 355e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu /* t2 = t1 * g^{xc} = g^{xa} * g^{xc} = g^{xa + xc} */ 356e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BN_mod_mul(t2, t1, ctx->p.gxc, ctx->p.p, ctx->ctx); 357e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu /* t1 = t2 * g^{xd} = g^{xa + xc + xd} */ 358e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BN_mod_mul(t1, t2, ctx->p.gxd, ctx->p.p, ctx->ctx); 359e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu /* t2 = xb * s */ 360e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BN_mod_mul(t2, ctx->xb, ctx->secret, ctx->p.q, ctx->ctx); 361e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 362e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu /* 363e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu * ZKP(xb * s) 364e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu * XXX: this is kinda funky, because we're using 365e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu * 366e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu * g' = g^{xa + xc + xd} 367e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu * 368e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu * as the generator, which means X is g'^{xb * s} 369e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu * X = t1^{t2} = t1^{xb * s} = g^{(xa + xc + xd) * xb * s} 370e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu */ 371e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu generate_step_part(send, t2, t1, ctx); 372e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 373e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu /* cleanup */ 374e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BN_free(t1); 375e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BN_free(t2); 376e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 377e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu return 1; 378e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu } 379e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 380e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu/* gx = g^{xc + xa + xb} * xd * s */ 381e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugustatic int compute_key(JPAKE_CTX *ctx, const BIGNUM *gx) 382e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu { 383e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BIGNUM *t1 = BN_new(); 384e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BIGNUM *t2 = BN_new(); 385e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BIGNUM *t3 = BN_new(); 386e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 387e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu /* 388e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu * K = (gx/g^{xb * xd * s})^{xb} 389e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu * = (g^{(xc + xa + xb) * xd * s - xb * xd *s})^{xb} 390e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu * = (g^{(xa + xc) * xd * s})^{xb} 391e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu * = g^{(xa + xc) * xb * xd * s} 392e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu * [which is the same regardless of who calculates it] 393e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu */ 394e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 395e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu /* t1 = (g^{xd})^{xb} = g^{xb * xd} */ 396e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BN_mod_exp(t1, ctx->p.gxd, ctx->xb, ctx->p.p, ctx->ctx); 397e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu /* t2 = -s = q-s */ 398e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BN_sub(t2, ctx->p.q, ctx->secret); 399e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu /* t3 = t1^t2 = g^{-xb * xd * s} */ 400e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BN_mod_exp(t3, t1, t2, ctx->p.p, ctx->ctx); 401e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu /* t1 = gx * t3 = X/g^{xb * xd * s} */ 402e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BN_mod_mul(t1, gx, t3, ctx->p.p, ctx->ctx); 403e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu /* K = t1^{xb} */ 404e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BN_mod_exp(ctx->key, t1, ctx->xb, ctx->p.p, ctx->ctx); 405e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 406e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu /* cleanup */ 407e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BN_free(t3); 408e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BN_free(t2); 409e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BN_free(t1); 410e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 411e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu return 1; 412e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu } 413e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 414e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modaduguint JPAKE_STEP2_process(JPAKE_CTX *ctx, const JPAKE_STEP2 *received) 415e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu { 416e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BIGNUM *t1 = BN_new(); 417e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BIGNUM *t2 = BN_new(); 418e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu int ret = 0; 419e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 420e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu /* 421e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu * g' = g^{xc + xa + xb} [from our POV] 422e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu * t1 = xa + xb 423e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu */ 424e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BN_mod_add(t1, ctx->xa, ctx->xb, ctx->p.q, ctx->ctx); 425e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu /* t2 = g^{t1} = g^{xa+xb} */ 426e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BN_mod_exp(t2, ctx->p.g, t1, ctx->p.p, ctx->ctx); 427e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu /* t1 = g^{xc} * t2 = g^{xc + xa + xb} */ 428e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BN_mod_mul(t1, ctx->p.gxc, t2, ctx->p.p, ctx->ctx); 429e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 430e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu if(verify_zkp(received, t1, ctx)) 431e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu ret = 1; 432e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu else 433e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu JPAKEerr(JPAKE_F_JPAKE_STEP2_PROCESS, JPAKE_R_VERIFY_B_FAILED); 434e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 435e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu compute_key(ctx, received->gx); 436e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 437e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu /* cleanup */ 438e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BN_free(t2); 439e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu BN_free(t1); 440e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 441e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu return ret; 442e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu } 443e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 444e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugustatic void quickhashbn(unsigned char *md, const BIGNUM *bn) 445e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu { 446e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu SHA_CTX sha; 447e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 448e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu SHA1_Init(&sha); 449e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu hashbn(&sha, bn); 450e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu SHA1_Final(md, &sha); 451e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu } 452e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 453e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modaduguvoid JPAKE_STEP3A_init(JPAKE_STEP3A *s3a) 454e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu {} 455e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 456e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modaduguint JPAKE_STEP3A_generate(JPAKE_STEP3A *send, JPAKE_CTX *ctx) 457e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu { 458e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu quickhashbn(send->hhk, ctx->key); 459e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu SHA1(send->hhk, sizeof send->hhk, send->hhk); 460e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 461e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu return 1; 462e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu } 463e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 464e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modaduguint JPAKE_STEP3A_process(JPAKE_CTX *ctx, const JPAKE_STEP3A *received) 465e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu { 466e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu unsigned char hhk[SHA_DIGEST_LENGTH]; 467e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 468e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu quickhashbn(hhk, ctx->key); 469e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu SHA1(hhk, sizeof hhk, hhk); 470e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu if(memcmp(hhk, received->hhk, sizeof hhk)) 471e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu { 472e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu JPAKEerr(JPAKE_F_JPAKE_STEP3A_PROCESS, JPAKE_R_HASH_OF_HASH_OF_KEY_MISMATCH); 473e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu return 0; 474e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu } 475e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu return 1; 476e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu } 477e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 478e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modaduguvoid JPAKE_STEP3A_release(JPAKE_STEP3A *s3a) 479e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu {} 480e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 481e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modaduguvoid JPAKE_STEP3B_init(JPAKE_STEP3B *s3b) 482e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu {} 483e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 484e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modaduguint JPAKE_STEP3B_generate(JPAKE_STEP3B *send, JPAKE_CTX *ctx) 485e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu { 486e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu quickhashbn(send->hk, ctx->key); 487e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 488e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu return 1; 489e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu } 490e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 491e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modaduguint JPAKE_STEP3B_process(JPAKE_CTX *ctx, const JPAKE_STEP3B *received) 492e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu { 493e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu unsigned char hk[SHA_DIGEST_LENGTH]; 494e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 495e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu quickhashbn(hk, ctx->key); 496e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu if(memcmp(hk, received->hk, sizeof hk)) 497e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu { 498e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu JPAKEerr(JPAKE_F_JPAKE_STEP3B_PROCESS, JPAKE_R_HASH_OF_KEY_MISMATCH); 499e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu return 0; 500e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu } 501e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu return 1; 502e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu } 503e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 504e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modaduguvoid JPAKE_STEP3B_release(JPAKE_STEP3B *s3b) 505e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu {} 506e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 507e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modaduguconst BIGNUM *JPAKE_get_shared_key(JPAKE_CTX *ctx) 508e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu { 509e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu return ctx->key; 510e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu } 511e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 512