コード例 #1
0
// Generate each party's random numbers. xa is in [0, q), xb is in [1, q).
static void genrand(JPakeUser * user, const JPakeParameters * params)
{
    BIGNUM *qm1;

    // xa in [0, q)
    user->xa = BN_new();
    BN_rand_range(user->xa, params->q);

    // q-1
    qm1 = BN_new();
    BN_copy(qm1, params->q);
    BN_sub_word(qm1, 1);

    // ... and xb in [0, q-1)
    user->xb = BN_new();
    BN_rand_range(user->xb, qm1);
    // [1, q)
    BN_add_word(user->xb, 1);

    // cleanup
    BN_free(qm1);

    // Show
    printf("x%d", user->p.base);
    showbn("", user->xa);
    printf("x%d", user->p.base + 1);
    showbn("", user->xb);
}
コード例 #2
0
static void JPakeParametersInit(JPakeParameters *params)
    {
    params->ctx = BN_CTX_new();

    // For now use p, q, g from Java sample code. Later, generate them.
    params->p = NULL;
    BN_hex2bn(&params->p, "fd7f53811d75122952df4a9c2eece4e7f611b7523cef4400c31e3f80b6512669455d402251fb593d8d58fabfc5f5ba30f6cb9b556cd7813b801d346ff26660b76b9950a5a49f9fe8047b1022c24fbba9d7feb7c61bf83b57e7c6a8a6150f04fb83f6d3c51ec3023554135a169132f675f3ae2b61d72aeff22203199dd14801c7");
    params->q = NULL;
    BN_hex2bn(&params->q, "9760508f15230bccb292b982a2eb840bf0581cf5");
    params->g = NULL;
    BN_hex2bn(&params->g, "f7e1a085d69b3ddecbbcab5c36b857b97994afbbfa3aea82f9574c0b3d0782675159578ebad4594fe67107108180b449167123e84c281613b7cf09328cc8a6e13c167a8b547c8d28e0a3ae1e2bb3a675916ea37f0bfa213562f1fb627a01243bcca4f1bea8519089a883dfe15ae59f06928b665e807b552564014c3bfecf492a");

    showbn("p", params->p);
    showbn("q", params->q);
    showbn("g", params->g);
    }
コード例 #3
0
static void computekey(JPakeUser * us, const JPakeParameters * params)
{
    BIGNUM *t1 = BN_new();
    BIGNUM *t2 = BN_new();
    BIGNUM *t3 = BN_new();

    printf("\n%s calculates the shared key:\n\n", us->p.name);

    // K = (X/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, us->p.s1d.gx, us->xb, params->p, params->ctx);
    // t2 = -s = q-s
    BN_sub(t2, params->q, us->secret);
    // t3 = t1^t2 = g^{-xb * xd * s}
    BN_mod_exp(t3, t1, t2, params->p, params->ctx);
    // t1 = X * t3 = X/g^{xb * xd * s}
    BN_mod_mul(t1, us->p.s2.X, t3, params->p, params->ctx);
    // K = t1^{xb}
    us->key = BN_new();
    BN_mod_exp(us->key, t1, us->xb, params->p, params->ctx);

    // show
    showbn("  K", us->key);

    // cleanup
    BN_free(t3);
    BN_free(t2);
    BN_free(t1);
}
コード例 #4
0
static void sendstep1_substep(JPakeStep1 * s1, const BIGNUM *x,
                              const JPakeUser * us,
                              const JPakeParameters * params, int n)
{
    s1->gx = BN_new();
    BN_mod_exp(s1->gx, params->g, x, params->p, params->ctx);
    printf("  g^{x%d}", n);
    showbn("", s1->gx);

    CreateZKP(&s1->zkpx, x, us, params->g, params, n, "");
}
コード例 #5
0
static int VerifyZKP(const JPakeZKP * zkp, BIGNUM *gx,
                     const JPakeUserPublic * them, const BIGNUM *zkpg,
                     const JPakeParameters * params, int n,
                     const char *suffix)
{
    BIGNUM *h = BN_new();
    BIGNUM *t1 = BN_new();
    BIGNUM *t2 = BN_new();
    BIGNUM *t3 = BN_new();
    int ret = 0;

    zkpHash(h, zkp, gx, them, params);

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

    printf("  ZKP(x%d%s)\n", n, suffix);
    showbn("    zkpg", zkpg);
    showbn("    g^r'", t3);

    // verify t3 == g^r
    if (BN_cmp(t3, zkp->gr) == 0)
        ret = 1;

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

    if (ret)
        puts("    OK");
    else
        puts("    FAIL");

    return ret;
}
コード例 #6
0
// Prove knowledge of x
// Note that we don't send g^x because, as it happens, we've always
// sent it elsewhere. Also note that because of that, we could avoid
// calculating it here, but we don't, for clarity...
static void CreateZKP(JPakeZKP * zkp, const BIGNUM *x, const JPakeUser * us,
                      const BIGNUM *zkpg, const JPakeParameters * params,
                      int n, const char *suffix)
{
    BIGNUM *r = BN_new();
    BIGNUM *gx = 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, params->q);
    // g^r
    zkp->gr = BN_new();
    BN_mod_exp(zkp->gr, zkpg, r, params->p, params->ctx);
    // g^x
    BN_mod_exp(gx, zkpg, x, params->p, params->ctx);

    // h=hash...
    zkpHash(h, zkp, gx, &us->p, params);

    // b = r - x*h
    BN_mod_mul(t, x, h, params->q, params->ctx);
    zkp->b = BN_new();
    BN_mod_sub(zkp->b, r, t, params->q, params->ctx);

    // show
    printf("  ZKP(x%d%s)\n", n, suffix);
    showbn("   zkpg", zkpg);
    showbn("    g^x", gx);
    showbn("    g^r", zkp->gr);
    showbn("      b", zkp->b);

    // cleanup
    BN_free(t);
    BN_free(h);
    BN_free(gx);
    BN_free(r);
}
コード例 #7
0
static void sendstep2(const JPakeUser * us, JPakeUserPublic * them,
                      const JPakeParameters * params)
{
    BIGNUM *t1 = BN_new();
    BIGNUM *t2 = BN_new();

    printf("\n%s sends %s:\n\n", us->p.name, them->name);

    // X = g^{(xa + xc + xd) * xb * s}
    // t1 = g^xa
    BN_mod_exp(t1, params->g, us->xa, params->p, params->ctx);
    // t2 = t1 * g^{xc} = g^{xa} * g^{xc} = g^{xa + xc}
    BN_mod_mul(t2, t1, us->p.s1c.gx, params->p, params->ctx);
    // t1 = t2 * g^{xd} = g^{xa + xc + xd}
    BN_mod_mul(t1, t2, us->p.s1d.gx, params->p, params->ctx);
    // t2 = xb * s
    BN_mod_mul(t2, us->xb, us->secret, params->q, params->ctx);
    // X = t1^{t2} = t1^{xb * s} = g^{(xa + xc + xd) * xb * s}
    them->s2.X = BN_new();
    BN_mod_exp(them->s2.X, t1, t2, params->p, params->ctx);

    // Show
    printf("  g^{(x%d + x%d + x%d) * x%d * s)", us->p.base, them->base,
           them->base + 1, us->p.base + 1);
    showbn("", them->s2.X);

    // 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}
    CreateZKP(&them->s2.zkpxbs, t2, us, t1, params, us->p.base + 1, " * s");

    // cleanup
    BN_free(t1);
    BN_free(t2);
}
コード例 #8
0
ファイル: srptest.c プロジェクト: Acidburn0zzz/openssl
static int run_srp(const char *username, const char *client_pass, const char *server_pass)
	{
	int ret=-1;
	BIGNUM *s = NULL;
	BIGNUM *v = NULL;
	BIGNUM *a = NULL;
	BIGNUM *b = NULL;
	BIGNUM *u = NULL;
	BIGNUM *x = NULL;
	BIGNUM *Apub = NULL;
	BIGNUM *Bpub = NULL;
	BIGNUM *Kclient = NULL;
	BIGNUM *Kserver = NULL;
	unsigned char rand_tmp[RANDOM_SIZE];
	/* use builtin 1024-bit params */
	const SRP_gN *GN = SRP_get_default_gN("1024");

	if(GN == NULL)
		{
		fprintf(stderr, "Failed to get SRP parameters\n");
		return -1;
		}
	/* Set up server's password entry */
	if(!SRP_create_verifier_BN(username, server_pass, &s, &v, GN->N, GN->g))
		{
		fprintf(stderr, "Failed to create SRP verifier\n");
		return -1;
		}

	showbn("N", GN->N);
	showbn("g", GN->g);
	showbn("Salt", s);
	showbn("Verifier", v);

	/* Server random */
	RAND_pseudo_bytes(rand_tmp, sizeof(rand_tmp));
	b = BN_bin2bn(rand_tmp, sizeof(rand_tmp), NULL);
	/* TODO - check b != 0 */
	showbn("b", b);

	/* Server's first message */
	Bpub = SRP_Calc_B(b, GN->N, GN->g, v);
	showbn("B", Bpub);

	if(!SRP_Verify_B_mod_N(Bpub, GN->N))
		{
		fprintf(stderr, "Invalid B\n");
		return -1;
		}

	/* Client random */
	RAND_pseudo_bytes(rand_tmp, sizeof(rand_tmp));
	a = BN_bin2bn(rand_tmp, sizeof(rand_tmp), NULL);
	/* TODO - check a != 0 */
	showbn("a", a);

	/* Client's response */
	Apub = SRP_Calc_A(a, GN->N, GN->g);
	showbn("A", Apub);

	if(!SRP_Verify_A_mod_N(Apub, GN->N))
		{
		fprintf(stderr, "Invalid A\n");
		return -1;
		}

	/* Both sides calculate u */
	u = SRP_Calc_u(Apub, Bpub, GN->N);

	/* Client's key */
	x = SRP_Calc_x(s, username, client_pass);
	Kclient = SRP_Calc_client_key(GN->N, Bpub, GN->g, x, a, u);
	showbn("Client's key", Kclient);

	/* Server's key */
	Kserver = SRP_Calc_server_key(Apub, v, u, b, GN->N);
	showbn("Server's key", Kserver);

	if(BN_cmp(Kclient, Kserver) == 0)
		{
		ret = 0;
		}
	else
		{
		fprintf(stderr, "Keys mismatch\n");
		ret = 1;
		}

	BN_clear_free(Kclient);
	BN_clear_free(Kserver);
	BN_clear_free(x);
	BN_free(u);
	BN_free(Apub);
	BN_clear_free(a);
	BN_free(Bpub);
	BN_clear_free(b);
	BN_free(s);
	BN_clear_free(v);

	return ret;
	}
コード例 #9
0
int main(int argc, char **argv)
{
    JPakeParameters params;
    JPakeUser alice, bob;

    alice.p.name = "Alice";
    alice.p.base = 1;
    bob.p.name = "Bob";
    bob.p.base = 3;

    JPakeParametersInit(&params);

    // Shared secret
    alice.secret = BN_new();
    BN_rand(alice.secret, 32, -1, 0);
    bob.secret = alice.secret;
    showbn("secret", alice.secret);

    assert(BN_cmp(alice.secret, params.q) < 0);

    // Alice's x1, x2
    genrand(&alice, &params);

    // Bob's x3, x4
    genrand(&bob, &params);

    // Now send stuff to each other...
    sendstep1(&alice, &bob.p, &params);
    sendstep1(&bob, &alice.p, &params);

    // And verify what each other sent
    if (!verifystep1(&alice, &bob.p, &params))
        return 1;
    if (!verifystep1(&bob, &alice.p, &params))
        return 2;

    // Second send
    sendstep2(&alice, &bob.p, &params);
    sendstep2(&bob, &alice.p, &params);

    // And second verify
    if (!verifystep2(&alice, &bob.p, &params))
        return 3;
    if (!verifystep2(&bob, &alice.p, &params))
        return 4;

    // Compute common key
    computekey(&alice, &params);
    computekey(&bob, &params);

    // Confirm the common key is identical
    // XXX: if the two secrets are not the same, everything works up
    // to this point, so the only way to detect a failure is by the
    // difference in the calculated keys.
    // Since we're all the same code, just compare them directly. In a
    // real system, Alice sends Bob H(H(K)), Bob checks it, then sends
    // back H(K), which Alice checks, or something equivalent.
    puts("\nAlice and Bob check keys are the same:");
    if (BN_cmp(alice.key, bob.key) == 0)
        puts("  OK");
    else {
        puts("  FAIL");
        return 5;
    }

    return 0;
}
コード例 #10
0
ファイル: jpaketest.c プロジェクト: 1310701102/sl4a
static int run_jpake(JPAKE_CTX *alice, JPAKE_CTX *bob)
    {
    JPAKE_STEP1 alice_s1;
    JPAKE_STEP1 bob_s1;
    JPAKE_STEP2 alice_s2;
    JPAKE_STEP2 bob_s2;
    JPAKE_STEP3A alice_s3a;
    JPAKE_STEP3B bob_s3b;

   /* Alice -> Bob: step 1 */
    puts("A->B s1");
    JPAKE_STEP1_init(&alice_s1);
    JPAKE_STEP1_generate(&alice_s1, alice);
    if(!JPAKE_STEP1_process(bob, &alice_s1))
	{
	printf("Bob fails to process Alice's step 1\n");
	ERR_print_errors_fp(stdout);
	return 1;
	}
    JPAKE_STEP1_release(&alice_s1);

   /* Bob -> Alice: step 1 */
    puts("B->A s1");
    JPAKE_STEP1_init(&bob_s1);
    JPAKE_STEP1_generate(&bob_s1, bob);
    if(!JPAKE_STEP1_process(alice, &bob_s1))
	{
	printf("Alice fails to process Bob's step 1\n");
	ERR_print_errors_fp(stdout);
	return 2;
	}
    JPAKE_STEP1_release(&bob_s1);

   /* Alice -> Bob: step 2 */
    puts("A->B s2");
    JPAKE_STEP2_init(&alice_s2);
    JPAKE_STEP2_generate(&alice_s2, alice);
    if(!JPAKE_STEP2_process(bob, &alice_s2))
	{
	printf("Bob fails to process Alice's step 2\n");
	ERR_print_errors_fp(stdout);
	return 3;
	}
    JPAKE_STEP2_release(&alice_s2);

   /* Bob -> Alice: step 2 */
    puts("B->A s2");
    JPAKE_STEP2_init(&bob_s2);
    JPAKE_STEP2_generate(&bob_s2, bob);
    if(!JPAKE_STEP2_process(alice, &bob_s2))
	{
	printf("Alice fails to process Bob's step 2\n");
	ERR_print_errors_fp(stdout);
	return 4;
	}
    JPAKE_STEP2_release(&bob_s2);

    showbn("Alice's key", JPAKE_get_shared_key(alice));
    showbn("Bob's key  ", JPAKE_get_shared_key(bob));

   /* Alice -> Bob: step 3a */
    puts("A->B s3a");
    JPAKE_STEP3A_init(&alice_s3a);
    JPAKE_STEP3A_generate(&alice_s3a, alice);
    if(!JPAKE_STEP3A_process(bob, &alice_s3a))
	{
	printf("Bob fails to process Alice's step 3a\n");
	ERR_print_errors_fp(stdout);
	return 5;
	}
    JPAKE_STEP3A_release(&alice_s3a);
    
   /* Bob -> Alice: step 3b */
    puts("B->A s3b");
    JPAKE_STEP3B_init(&bob_s3b);
    JPAKE_STEP3B_generate(&bob_s3b, bob);
    if(!JPAKE_STEP3B_process(alice, &bob_s3b))
	{
	printf("Alice fails to process Bob's step 3b\n");
	ERR_print_errors_fp(stdout);
	return 6;
	}
    JPAKE_STEP3B_release(&bob_s3b);

    return 0;
    }
コード例 #11
0
ファイル: jpaketest.c プロジェクト: 1310701102/sl4a
int main(int argc, char **argv)
    {
    JPAKE_CTX *alice;
    JPAKE_CTX *bob;
    BIGNUM *p = NULL;
    BIGNUM *g = NULL;
    BIGNUM *q = NULL;
    BIGNUM *secret = BN_new();
    BIO *bio_err;

    bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);

    CRYPTO_malloc_debug_init();
    CRYPTO_dbg_set_options(V_CRYPTO_MDEBUG_ALL);
    CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);

    ERR_load_crypto_strings();

    /*
    BN_hex2bn(&p, "fd7f53811d75122952df4a9c2eece4e7f611b7523cef4400c31e3f80b6512669455d402251fb593d8d58fabfc5f5ba30f6cb9b556cd7813b801d346ff26660b76b9950a5a49f9fe8047b1022c24fbba9d7feb7c61bf83b57e7c6a8a6150f04fb83f6d3c51ec3023554135a169132f675f3ae2b61d72aeff22203199dd14801c7");
    BN_hex2bn(&g, "f7e1a085d69b3ddecbbcab5c36b857b97994afbbfa3aea82f9574c0b3d0782675159578ebad4594fe67107108180b449167123e84c281613b7cf09328cc8a6e13c167a8b547c8d28e0a3ae1e2bb3a675916ea37f0bfa213562f1fb627a01243bcca4f1bea8519089a883dfe15ae59f06928b665e807b552564014c3bfecf492a");
    BN_hex2bn(&q, "9760508f15230bccb292b982a2eb840bf0581cf5");
    */
    /*
    p = BN_new();
    BN_generate_prime(p, 1024, 1, NULL, NULL, NULL, NULL);
    */
   /* Use a safe prime for p (that we found earlier) */
    BN_hex2bn(&p, "F9E5B365665EA7A05A9C534502780FEE6F1AB5BD4F49947FD036DBD7E905269AF46EF28B0FC07487EE4F5D20FB3C0AF8E700F3A2FA3414970CBED44FEDFF80CE78D800F184BB82435D137AADA2C6C16523247930A63B85661D1FC817A51ACD96168E95898A1F83A79FFB529368AA7833ABD1B0C3AEDDB14D2E1A2F71D99F763F");
    showbn("p", p);
    g = BN_new();
    BN_set_word(g, 2);
    showbn("g", g);
    q = BN_new();
    BN_rshift1(q, p);
    showbn("q", q);

    BN_rand(secret, 32, -1, 0);

   /* A normal run, expect this to work... */
    alice = JPAKE_CTX_new("Alice", "Bob", p, g, q, secret);
    bob = JPAKE_CTX_new("Bob", "Alice", p, g, q, secret);

    if(run_jpake(alice, bob) != 0)
	{
	fprintf(stderr, "Plain JPAKE run failed\n");
	return 1;
	}

    JPAKE_CTX_free(bob);
    JPAKE_CTX_free(alice);

   /* Now give Alice and Bob different secrets */
    alice = JPAKE_CTX_new("Alice", "Bob", p, g, q, secret);
    BN_add_word(secret, 1);
    bob = JPAKE_CTX_new("Bob", "Alice", p, g, q, secret);

    if(run_jpake(alice, bob) != 5)
	{
	fprintf(stderr, "Mismatched secret JPAKE run failed\n");
	return 1;
	}

    JPAKE_CTX_free(bob);
    JPAKE_CTX_free(alice);

    BN_free(secret);
    BN_free(q);
    BN_free(g);
    BN_free(p);

    CRYPTO_cleanup_all_ex_data();
    ERR_remove_state(0);
    ERR_free_strings();
    CRYPTO_mem_leaks(bio_err);

    return 0;
    }
コード例 #12
0
ファイル: srptest.c プロジェクト: dgervais/openssl
static int run_srp(const char *username, const char *client_pass,
                   const char *server_pass)
{
    int ret = 0;
    BIGNUM *s = NULL;
    BIGNUM *v = NULL;
    BIGNUM *a = NULL;
    BIGNUM *b = NULL;
    BIGNUM *u = NULL;
    BIGNUM *x = NULL;
    BIGNUM *Apub = NULL;
    BIGNUM *Bpub = NULL;
    BIGNUM *Kclient = NULL;
    BIGNUM *Kserver = NULL;
    unsigned char rand_tmp[RANDOM_SIZE];
    /* use builtin 1024-bit params */
    const SRP_gN *GN;
    
    if (!TEST_ptr(GN = SRP_get_default_gN("1024")))
        return 0;

    /* Set up server's password entry */
    if (!TEST_true(SRP_create_verifier_BN(username, server_pass,
                                          &s, &v, GN->N, GN->g)))
        goto end;

    showbn("N", GN->N);
    showbn("g", GN->g);
    showbn("Salt", s);
    showbn("Verifier", v);

    /* Server random */
    RAND_bytes(rand_tmp, sizeof(rand_tmp));
    b = BN_bin2bn(rand_tmp, sizeof(rand_tmp), NULL);
    if (!TEST_BN_ne_zero(b))
        goto end;
    showbn("b", b);

    /* Server's first message */
    Bpub = SRP_Calc_B(b, GN->N, GN->g, v);
    showbn("B", Bpub);

    if (!TEST_true(SRP_Verify_B_mod_N(Bpub, GN->N)))
        goto end;

    /* Client random */
    RAND_bytes(rand_tmp, sizeof(rand_tmp));
    a = BN_bin2bn(rand_tmp, sizeof(rand_tmp), NULL);
    if (!TEST_BN_ne_zero(a))
        goto end;
    showbn("a", a);

    /* Client's response */
    Apub = SRP_Calc_A(a, GN->N, GN->g);
    showbn("A", Apub);

    if (!TEST_true(SRP_Verify_A_mod_N(Apub, GN->N)))
        goto end;

    /* Both sides calculate u */
    u = SRP_Calc_u(Apub, Bpub, GN->N);

    /* Client's key */
    x = SRP_Calc_x(s, username, client_pass);
    Kclient = SRP_Calc_client_key(GN->N, Bpub, GN->g, x, a, u);
    showbn("Client's key", Kclient);

    /* Server's key */
    Kserver = SRP_Calc_server_key(Apub, v, u, b, GN->N);
    showbn("Server's key", Kserver);

    if (!TEST_BN_eq(Kclient, Kserver))
        goto end;

    ret = 1;

end:
    BN_clear_free(Kclient);
    BN_clear_free(Kserver);
    BN_clear_free(x);
    BN_free(u);
    BN_free(Apub);
    BN_clear_free(a);
    BN_free(Bpub);
    BN_clear_free(b);
    BN_free(s);
    BN_clear_free(v);

    return ret;
}