Example #1
0
void ep_mul_sim_gen(ep_t r, const bn_t k, const ep_t q, const bn_t m) {
	ep_t g;

	ep_null(g);

	if (bn_is_zero(k)) {
		ep_mul(r, q, m);
		return;
	}
	if (bn_is_zero(m) || ep_is_infty(q)) {
		ep_mul_gen(r, k);
		return;
	}

	TRY {
		ep_new(g);

		ep_curve_get_gen(g);

#if defined(EP_ENDOM)
#if EP_SIM == INTER && EP_FIX == LWNAF && defined(EP_PRECO)
		if (ep_curve_is_endom()) {
			ep_mul_sim_endom(r, g, k, q, m, ep_curve_get_tab());
		}
#else
		if (ep_curve_is_endom()) {
			ep_mul_sim(r, g, k, q, m);
		}
#endif
#endif

#if defined(EP_PLAIN) || defined(EP_SUPER)
#if EP_SIM == INTER && EP_FIX == LWNAF && defined(EP_PRECO)
		if (!ep_curve_is_endom()) {
			ep_mul_sim_plain(r, g, k, q, m, ep_curve_get_tab());
		}
#else
		if (!ep_curve_is_endom()) {
			ep_mul_sim(r, g, k, q, m);
		}
#endif
#endif
	}
	CATCH_ANY {
		THROW(ERR_CAUGHT);
	}
	FINALLY {
		ep_free(g);
	}
}
Example #2
0
void eb_mul_sim_gen(eb_t r, const bn_t k, const eb_t q, const bn_t m) {
	eb_t g;

	eb_null(g);

	if (bn_is_zero(k)) {
		eb_mul(r, q, m);
		return;
	}
	if (bn_is_zero(m) || eb_is_infty(q)) {
		eb_mul_gen(r, k);
		return;
	}

	TRY {
		eb_new(g);

		eb_curve_get_gen(g);

#if defined(EB_KBLTZ)
#if EB_SIM == INTER && EB_FIX == LWNAF && defined(EB_PRECO)
		if (eb_curve_is_kbltz()) {
			eb_mul_sim_kbltz(r, g, k, q, m, eb_curve_get_tab());
		}
#else
		if (eb_curve_is_kbltz()) {
			eb_mul_sim(r, g, k, q, m);
		}
#endif
#endif

#if defined(EB_PLAIN)
#if EB_SIM == INTER && EB_FIX == LWNAF && defined(EB_PRECO)
		if (!eb_curve_is_kbltz()) {
			eb_mul_sim_plain(r, g, k, q, m, eb_curve_get_tab());
		}
#else
		if (!eb_curve_is_kbltz()) {
			eb_mul_sim(r, g, k, q, m);
		}
#endif
#endif
	}
	CATCH_ANY {
		THROW(ERR_CAUGHT);
	}
	FINALLY {
		eb_free(g);
	}
}
Example #3
0
/**
 * Multiplies a binary elliptic curve point by an integer using the w-NAF
 * method.
 *
 * @param[out] r 				- the result.
 * @param[in] p					- the point to multiply.
 * @param[in] k					- the integer.
 */
static void ep2_mul_fix_ordin(ep2_t r, ep2_t *table, bn_t k) {
	int len, i, n;
	int8_t naf[2 * RLC_FP_BITS + 1], *t;

	if (bn_is_zero(k)) {
		ep2_set_infty(r);
		return;
	}

	/* Compute the w-TNAF representation of k. */
	len = 2 * RLC_FP_BITS + 1;
	bn_rec_naf(naf, &len, k, EP_DEPTH);

	t = naf + len - 1;
	ep2_set_infty(r);
	for (i = len - 1; i >= 0; i--, t--) {
		ep2_dbl(r, r);

		n = *t;
		if (n > 0) {
			ep2_add(r, r, table[n / 2]);
		}
		if (n < 0) {
			ep2_sub(r, r, table[-n / 2]);
		}
	}
	/* Convert r to affine coordinates. */
	ep2_norm(r, r);
	if (bn_sign(k) == RLC_NEG) {
		ep2_neg(r, r);
	}
}
Example #4
0
void fp_read_bin(fp_t a, const unsigned char *str, int len) {
        bn_t t;

        bn_null(t);

        TRY {
                bn_new(t);
                bn_read_bin(t, (unsigned char *) str, len);
                if (bn_is_zero(t)) {
                        fp_zero(a);
                } else {
                        if (t->used == 1) {
                                fp_prime_conv_dig(a, t->dp[0]);
                        } else {
                                fp_prime_conv(a, t);
                        }
                }
        }
        CATCH_ANY {
                THROW(ERR_CAUGHT);
        }
        FINALLY {
                bn_free(t);
        }
}
Example #5
0
void fp_read_str(fp_t a, const char *str, int len, int radix) {
	bn_t t;

	bn_null(t);

	TRY {
		bn_new(t);
		bn_read_str(t, str, len, radix);
		if (bn_is_zero(t)) {
			fp_zero(a);
		} else {
			if (t->used == 1) {
				fp_prime_conv_dig(a, t->dp[0]);
			} else {
				fp_prime_conv(a, t);
			}
		}
	}
	CATCH_ANY {
		THROW(ERR_CAUGHT);
	}
	FINALLY {
		bn_free(t);
	}
}
Example #6
0
status_t element_pow_zr(element_t c, element_t a, element_t b)
{
	GroupType type = a->type;
	// c (type) = a (type) ^ b (ZR)
	LEAVE_IF( c->isInitialized != TRUE || a->isInitialized != TRUE, "uninitialized argument.");
	EXIT_IF_NOT_SAME(c, a);
	LEAVE_IF(a->isInitialized != TRUE, "invalid argument.");
	LEAVE_IF(b->isInitialized != TRUE || b->type != ZR, "invalid type.");

	if(type == ZR) {
		bn_mxp(c->bn, a->bn, b->bn, a->order);
	}
	else if(type == G1) {
		g1_mul(c->g1, a->g1, b->bn);
	}
	else if(type == G2) {
		g2_mul(c->g2, a->g2, b->bn);
	}
	else if(type == GT) {
		if(bn_is_zero(b->bn))
			gt_set_unity(c->gt); // GT ^ 0 => identity element (not handled by gt_exp)
		else
			gt_exp(c->gt, a->gt, b->bn);
	}
	else {
		return ELEMENT_INVALID_TYPES;
	}

	return ELEMENT_OK;
}
int cp_ecss_gen(bn_t d, ec_t q) {
	bn_t n;
	int result = STS_OK;

	bn_null(n);

	TRY {
		bn_new(n);

		ec_curve_get_ord(n);

		do {
			bn_rand(d, BN_POS, bn_bits(n));
			bn_mod(d, d, n);
		} while (bn_is_zero(d));

		ec_mul_gen(q, d);
	}
	CATCH_ANY {
		result = STS_ERR;
	}
	FINALLY {
		bn_free(n);
	}
	return result;
}
Example #8
0
void fp_read_bin(fp_t a, const uint8_t *bin, int len) {
	bn_t t;

	bn_null(t);

	if (len != RLC_FP_BYTES) {
		THROW(ERR_NO_BUFFER);
	}

	TRY {
		bn_new(t);
		bn_read_bin(t, bin, len);
		if (bn_is_zero(t)) {
			fp_zero(a);
		} else {
			if (t->used == 1) {
				fp_prime_conv_dig(a, t->dp[0]);
			} else {
				fp_prime_conv(a, t);
			}
		}
	}
	CATCH_ANY {
		THROW(ERR_CAUGHT);
	}
	FINALLY {
		bn_free(t);
	}
}
Example #9
0
// int appears on lhs (1 / [ZR, G1, G2, GT])
status_t element_int_div(element_t c, integer_t a, element_t b)
{
	GroupType type = b->type;
	EXIT_IF_NOT_SAME(c, b);
	LEAVE_IF( c->isInitialized != TRUE || b->isInitialized != TRUE, "uninitialized arguments.");
	LEAVE_IF( c->type != type, "result initialized but invalid type.");

	if(type == ZR) {
		if(bn_is_zero(b->bn)) return ELEMENT_DIV_ZERO;
		element_invert(c, b);
		if(bn_is_one(a)) return ELEMENT_OK;
		integer_t s;
		bn_inits(s);
		bn_mul(s, a, c->bn);
		bn_div_rem(s, c->bn, s, c->order);
//		if(bn_sign(c->bn) == BN_NEG) bn_add(c->bn, c->bn, c->order);
		bn_free(s);
//		bn_div(c->bn, a, b->bn);
//		bn_mod(c->bn, c->bn, c->order);
	}
	else if(type == G1 || type == G2 || type == GT) {
		if(bn_is_one(a)) {
			element_invert(c, b);
		}
		// TODO: other cases: a > 1 (ZR)?
	}

	return ELEMENT_OK;
}
Example #10
0
int cp_ecss_sig(bn_t e, bn_t s, uint8_t *msg, int len, bn_t d) {
	bn_t n, k, x, r;
	ec_t p;
	uint8_t hash[MD_LEN];
	uint8_t m[len + FC_BYTES];
	int result = STS_OK;

	bn_null(n);
	bn_null(k);
	bn_null(x);
	bn_null(r);
	ec_null(p);

	TRY {
		bn_new(n);
		bn_new(k);
		bn_new(x);
		bn_new(r);
		ec_new(p);

		ec_curve_get_ord(n);
		do {
			bn_rand_mod(k, n);
			ec_mul_gen(p, k);
			ec_get_x(x, p);
			bn_mod(r, x, n);
		} while (bn_is_zero(r));

		memcpy(m, msg, len);
		bn_write_bin(m + len, FC_BYTES, r);
		md_map(hash, m, len + FC_BYTES);

		if (8 * MD_LEN > bn_bits(n)) {
			len = CEIL(bn_bits(n), 8);
			bn_read_bin(e, hash, len);
			bn_rsh(e, e, 8 * MD_LEN - bn_bits(n));
		} else {
			bn_read_bin(e, hash, MD_LEN);
		}

		bn_mod(e, e, n);

		bn_mul(s, d, e);
		bn_mod(s, s, n);
		bn_sub(s, n, s);
		bn_add(s, s, k);
		bn_mod(s, s, n);
	}
	CATCH_ANY {
		result = STS_ERR;
	}
	FINALLY {
		bn_free(n);
		bn_free(k);
		bn_free(x);
		bn_free(r);
		ec_free(p);
	}
	return result;
}
Example #11
0
void ed_mul_gen(ed_t r, const bn_t k) {
	if (bn_is_zero(k)) {
		ed_set_infty(r);
		return;
	}
#ifdef ED_PRECO
	ed_mul_fix(r, ed_curve_get_tab(), k);
#else
	ed_t g;

	ed_null(g);

	TRY {
		ed_new(g);
		ed_curve_get_gen(g);
		ed_mul(r, g, k);
	}
	CATCH_ANY {
		THROW(ERR_CAUGHT);
	}
	FINALLY {
		ed_free(g);
	}
#endif
}
Example #12
0
void ed_mul_basic(ed_t r, const ed_t p, const bn_t k) {
	ed_t t;

	ed_null(t);

	if (bn_is_zero(k) || ed_is_infty(p)) {
		ed_set_infty(r);
		return;
	}

	TRY {
		ed_new(t);

		ed_copy(t, p);
		for (int i = bn_bits(k) - 2; i >= 0; i--) {
			ed_dbl(t, t);
			if (bn_get_bit(k, i)) {
				ed_add(t, t, p);
			}
		}

		ed_norm(r, t);
		if (bn_sign(k) == RLC_NEG) {
			ed_neg(r, r);
		}
	}
	CATCH_ANY {
		THROW(ERR_CAUGHT);
	}
	FINALLY {
		ed_free(t);
	}
}
Example #13
0
status_t element_pow_int(element_t c, element_t a, integer_t b)
{
	GroupType type = a->type;
	// TODO: c (type) = a (type) ^ b (ZR)
	LEAVE_IF( c->isInitialized != TRUE || a->isInitialized != TRUE, "uninitialized argument.");
	EXIT_IF_NOT_SAME(c, a);
	LEAVE_IF(b == NULL, "uninitialized integer.");

	status_t result = ELEMENT_OK;
	LEAVE_IF( c->type != type, "result initialized but invalid type.");

	switch(type) {
		case ZR: bn_mxp(c->bn, a->bn, b, a->order);
				 break;
		case G1: g1_mul(c->g1, a->g1, b);
				 break;
		case G2: g2_mul(c->g2, a->g2, b);
				 break;
		case GT: if(bn_is_zero(b)) gt_set_unity(c->gt);
				 else gt_exp(c->gt, a->gt, b);
				 break;
		default:
				 result = ELEMENT_INVALID_TYPES;
				 break;
	}

	return result;

}
Example #14
0
void ep2_mul_fix_combd(ep2_t r, ep2_t *t, bn_t k) {
	int i, j, d, e, w0, w1, n0, p0, p1;
	bn_t n;

	if (bn_is_zero(k)) {
		ep2_set_infty(r);
		return;
	}

	bn_null(n);

	TRY {
		bn_new(n);

		ep2_curve_get_ord(n);
		d = bn_bits(n);
		d = ((d % EP_DEPTH) == 0 ? (d / EP_DEPTH) : (d / EP_DEPTH) + 1);
		e = (d % 2 == 0 ? (d / 2) : (d / 2) + 1);

		ep2_set_infty(r);
		n0 = bn_bits(k);

		p1 = (e - 1) + (EP_DEPTH - 1) * d;
		for (i = e - 1; i >= 0; i--) {
			ep2_dbl(r, r);

			w0 = 0;
			p0 = p1;
			for (j = EP_DEPTH - 1; j >= 0; j--, p0 -= d) {
				w0 = w0 << 1;
				if (p0 < n0 && bn_get_bit(k, p0)) {
					w0 = w0 | 1;
				}
			}

			w1 = 0;
			p0 = p1-- + e;
			for (j = EP_DEPTH - 1; j >= 0; j--, p0 -= d) {
				w1 = w1 << 1;
				if (i + e < d && p0 < n0 && bn_get_bit(k, p0)) {
					w1 = w1 | 1;
				}
			}

			ep2_add(r, r, t[w0]);
			ep2_add(r, r, t[(1 << EP_DEPTH) + w1]);
		}
		ep2_norm(r, r);
		if (bn_sign(k) == RLC_NEG) {
			ep2_neg(r, r);
		}
	}
	CATCH_ANY {
		THROW(ERR_CAUGHT);
	}
	FINALLY {
		bn_free(n);
	}
}
Example #15
0
void ep2_mul_fix_combs(ep2_t r, ep2_t *t, bn_t k) {
	int i, j, l, w, n0, p0, p1;
	bn_t n;

	if (bn_is_zero(k)) {
		ep2_set_infty(r);
		return;
	}

	bn_null(n);

	TRY {
		bn_new(n);

		ep2_curve_get_ord(n);
		l = bn_bits(n);
		l = ((l % EP_DEPTH) == 0 ? (l / EP_DEPTH) : (l / EP_DEPTH) + 1);

		n0 = bn_bits(k);

		p0 = (EP_DEPTH) * l - 1;

		w = 0;
		p1 = p0--;
		for (j = EP_DEPTH - 1; j >= 0; j--, p1 -= l) {
			w = w << 1;
			if (p1 < n0 && bn_get_bit(k, p1)) {
				w = w | 1;
			}
		}
		ep2_copy(r, t[w]);

		for (i = l - 2; i >= 0; i--) {
			ep2_dbl(r, r);

			w = 0;
			p1 = p0--;
			for (j = EP_DEPTH - 1; j >= 0; j--, p1 -= l) {
				w = w << 1;
				if (p1 < n0 && bn_get_bit(k, p1)) {
					w = w | 1;
				}
			}
			if (w > 0) {
				ep2_add(r, r, t[w]);
			}
		}
		ep2_norm(r, r);
		if (bn_sign(k) == RLC_NEG) {
			ep2_neg(r, r);
		}
	}
	CATCH_ANY {
		THROW(ERR_CAUGHT);
	}
	FINALLY {
		bn_free(n);
	}
}
Example #16
0
void ed_mul_lwreg(ed_t r, const ed_t p, const bn_t k) {
	if (bn_is_zero(k) || ed_is_infty(p)) {
		ed_set_infty(r);
		return;
	}

	ed_mul_reg_imp(r, p, k);
}
Example #17
0
void bn_neg(bn_t c, const bn_t a) {
	if (c->dp != a->dp) {
		bn_copy(c, a);
	}
	if (!bn_is_zero(c)) {
		c->sign = a->sign ^ 1;
	}
}
Example #18
0
int bn_is_even(const bn_t a) {
	if (bn_is_zero(a)) {
		return 1;
	}
	if ((a->dp[0] & 0x01) == 0) {
		return 1;
	}
	return 0;
}
Example #19
0
int bn_size_str(const bn_t a, int radix) {
	int digits = 0;
	bn_t t;

	bn_null(t);

	/* Binary case requires the bits, a sign and the null terminator. */
	if (radix == 2) {
		return bn_bits(a) + (a->sign == BN_NEG ? 1 : 0) + 1;
	}

	/* Check the radix. */
	if (radix < 2 || radix > 64) {
		THROW(ERR_NO_VALID);
	}

	if (bn_is_zero(a)) {
		return 2;
	}

	if (a->sign == BN_NEG) {
		digits++;
	}

	TRY {
		bn_new(t);
		bn_copy(t, a);

		t->sign = BN_POS;

		while (!bn_is_zero(t)) {
			bn_div_dig(t, t, (dig_t)radix);
			digits++;
		}
	} CATCH_ANY {
		THROW(ERR_CAUGHT);
	} FINALLY {
		bn_free(t);
	}

	return digits + 1;
}
Example #20
0
void bn_mxp_basic(bn_t c, const bn_t a, const bn_t b, const bn_t m) {
	int i, l;
	bn_t t, u, r;

	if (bn_is_zero(b)) {
		bn_set_dig(c, 1);
		return;
	}

	bn_null(t);
	bn_null(u);
	bn_null(r);

	TRY {
		bn_new(t);
		bn_new(u);
		bn_new(r);

		bn_mod_pre(u, m);

		l = bn_bits(b);

#if BN_MOD == MONTY
		bn_mod_monty_conv(t, a, m);
#else
		bn_copy(t, a);
#endif

		bn_copy(r, t);

		for (i = l - 2; i >= 0; i--) {
			bn_sqr(r, r);
			bn_mod(r, r, m, u);
			if (bn_get_bit(b, i)) {
				bn_mul(r, r, t);
				bn_mod(r, r, m, u);
			}
		}

#if BN_MOD == MONTY
		bn_mod_monty_back(c, r, m);
#else
		bn_copy(c, r);
#endif
	}
	CATCH_ANY {
		THROW(ERR_CAUGHT);
	}
	FINALLY {
		bn_free(t);
		bn_free(u);
		bn_free(r);
	}
}
Example #21
0
/**
 * Applies or removes simple encryption padding.
 *
 * @param[out] m		- the buffer to pad.
 * @param[out] p_len	- the number of added pad bytes.
 * @param[in] m_len		- the message length in bytes.
 * @param[in] k_len		- the key length in bytes.
 * @param[in] operation	- flag to indicate the operation type.
 * @return STS_ERR if errors occurred, STS_OK otherwise.
 */
static int pad_basic(bn_t m, int *p_len, int m_len, int k_len, int operation) {
	uint8_t pad = 0;
	int result = STS_OK;
	bn_t t;

	TRY {
		bn_null(t);
		bn_new(t);

		switch (operation) {
			case RSA_ENC:
			case RSA_SIG:
			case RSA_SIG_HASH:
				/* EB = 00 | FF | D. */
				bn_zero(m);
				bn_lsh(m, m, 8);
				bn_add_dig(m, m, RSA_PAD);
				/* Make room for the real message. */
				bn_lsh(m, m, m_len * 8);
				break;
			case RSA_DEC:
			case RSA_VER:
			case RSA_VER_HASH:
				/* EB = 00 | FF | D. */
				m_len = k_len - 1;
				bn_rsh(t, m, 8 * m_len);
				if (!bn_is_zero(t)) {
					result = STS_ERR;
				}
				*p_len = 1;
				do {
					(*p_len)++;
					m_len--;
					bn_rsh(t, m, 8 * m_len);
					pad = (uint8_t)t->dp[0];
				} while (pad == 0);
				if (pad != RSA_PAD) {
					result = STS_ERR;
				}
				bn_mod_2b(m, m, (k_len - *p_len) * 8);
				break;
		}
	}
	CATCH_ANY {
		result = STS_ERR;
	}
	FINALLY {
		bn_free(t);
	}
	return result;
}
Example #22
0
void eb_mul_sim_inter(eb_t r, const eb_t p, const bn_t k, const eb_t q,
		const bn_t m) {

	if (bn_is_zero(k) || eb_is_infty(p)) {
		eb_mul(r, q, m);
		return;
	}
	if (bn_is_zero(m) || eb_is_infty(q)) {
		eb_mul(r, p, k);
		return;
	}

#if defined(EB_KBLTZ)
	if (eb_curve_is_kbltz()) {
		eb_mul_sim_kbltz(r, p, k, q, m, NULL);
		return;
	}
#endif

#if defined(EB_PLAIN)
	eb_mul_sim_plain(r, p, k, q, m, NULL);
#endif
}
Example #23
0
void ep_mul_sim_inter(ep_t r, const ep_t p, const bn_t k, const ep_t q,
		const bn_t m) {

	if (bn_is_zero(k) || ep_is_infty(p)) {
		ep_mul(r, q, m);
		return;
	}
	if (bn_is_zero(m) || ep_is_infty(q)) {
		ep_mul(r, p, k);
		return;
	}

#if defined(EP_ENDOM)
	if (ep_curve_is_endom()) {
		ep_mul_sim_endom(r, p, k, q, m, NULL);
		return;
	}
#endif

#if defined(EP_PLAIN) || defined(EP_SUPER)
	ep_mul_sim_plain(r, p, k, q, m, NULL);
#endif
}
Example #24
0
void ed_mul_monty(ed_t r, const ed_t p, const bn_t k) {
	ed_t t[2];

	ed_null(t[0]);
	ed_null(t[1]);

	if (bn_is_zero(k) || ed_is_infty(p)) {
		ed_set_infty(r);
		return;
	}

	TRY {
		ed_new(t[0]);
		ed_new(t[1]);

		ed_set_infty(t[0]);
		ed_copy(t[1], p);

		for (int i = bn_bits(k) - 1; i >= 0; i--) {
			int j = bn_get_bit(k, i);

			dv_swap_cond(t[0]->x, t[1]->x, RLC_FP_DIGS, j ^ 1);
			dv_swap_cond(t[0]->y, t[1]->y, RLC_FP_DIGS, j ^ 1);
			dv_swap_cond(t[0]->z, t[1]->z, RLC_FP_DIGS, j ^ 1);
#if ED_ADD == EXTND
			dv_swap_cond(t[0]->t, t[1]->t, RLC_FP_DIGS, j ^ 1);
#endif
			ed_add(t[0], t[0], t[1]);
			ed_dbl(t[1], t[1]);
			dv_swap_cond(t[0]->x, t[1]->x, RLC_FP_DIGS, j ^ 1);
			dv_swap_cond(t[0]->y, t[1]->y, RLC_FP_DIGS, j ^ 1);
			dv_swap_cond(t[0]->z, t[1]->z, RLC_FP_DIGS, j ^ 1);
#if ED_ADD == EXTND
			dv_swap_cond(t[0]->t, t[1]->t, RLC_FP_DIGS, j ^ 1);
#endif
		}

		ed_norm(r, t[0]);
		if (bn_sign(k) == RLC_NEG) {
			ed_neg(r, r);
		}
	} CATCH_ANY {
		THROW(ERR_CAUGHT);
	}
	FINALLY {
		ed_free(t[1]);
		ed_free(t[0]);
	}
}
Example #25
0
int hdnode_from_xprv(uint32_t depth, uint32_t fingerprint, uint32_t child_num, const uint8_t *chain_code, const uint8_t *private_key, HDNode *out)
{
	bignum256 a;
	bn_read_be(private_key, &a);
	if (bn_is_zero(&a) || !bn_is_less(&a, &order256k1)) { // == 0 or >= order
		return 0;
	}
	out->depth = depth;
	out->fingerprint = fingerprint;
	out->child_num = child_num;
	memcpy(out->chain_code, chain_code, 32);
	memcpy(out->private_key, private_key, 32);
	hdnode_fill_public_key(out);
	return 1;
}
Example #26
0
int cp_bdpe_enc(uint8_t *out, int *out_len, dig_t in, bdpe_t pub) {
	bn_t m, u;
	int size, result = STS_OK;

	bn_null(m);
	bn_null(u);

	size = bn_size_bin(pub->n);

	if (in > pub->t) {
		return STS_ERR;
	}

	TRY {
		bn_new(m);
		bn_new(u);

		bn_set_dig(m, in);

		do {
			bn_rand(u, BN_POS, bn_bits(pub->n));
			bn_mod(u, u, pub->n);
		} while (bn_is_zero(u));

		bn_mxp(m, pub->y, m, pub->n);
		bn_mxp_dig(u, u, pub->t, pub->n);
		bn_mul(m, m, u);
		bn_mod(m, m, pub->n);

		if (size <= *out_len) {
			*out_len = size;
			memset(out, 0, *out_len);
			bn_write_bin(out, size, m);
		} else {
			result = STS_ERR;
		}
	}
	CATCH_ANY {
		result = STS_ERR;
	}
	FINALLY {
		bn_free(m);
		bn_free(u);
	}

	return result;
}
Example #27
0
status_t element_div(element_t c, element_t a, element_t b)
{
	GroupType type = a->type;
	EXIT_IF_NOT_SAME(a, b);
	LEAVE_IF(a->isInitialized != TRUE || b->isInitialized != TRUE || c->isInitialized != TRUE, "uninitialized arguments.");
	LEAVE_IF( c->type != type, "result initialized but invalid type.");

	if(type == ZR) {
		if(bn_is_zero(b->bn)) return ELEMENT_DIV_ZERO;
		// c = (1 / b) mod order
		element_invert(c, b);
		if(bn_is_one(a->bn))  return ELEMENT_OK;
//		bn_div(c->bn, a->bn, b->bn);
//		bn_mod(c->bn, c->bn, c->order);
		// remainder of ((a * c) / order)
		integer_t s;
		bn_inits(s);
		// c = (a * c) / order (remainder only)
		bn_mul(s, a->bn, c->bn);
		bn_div_rem(s, c->bn, s, a->order);
//		if(bn_sign(c->bn) == BN_NEG) bn_add(c->bn, c->bn, a->order);
		bn_free(s);


	}
	else if(type == G1) {
		g1_sub(c->g1, a->g1, b->g1);
		g1_norm(c->g1, c->g1);
	}
	else if(type == G2) {
		g2_sub(c->g2, a->g2, b->g2);
		g2_norm(c->g2, c->g2);
	}
	else if(type == GT) {
		gt_t t;
		gt_inits(t);
		gt_inv(t, b->gt);
		gt_mul(c->gt, a->gt, t);
		gt_free(t);
	}
	else {
		return ELEMENT_INVALID_TYPES;
	}

	return ELEMENT_OK;
}
Example #28
0
int hdnode_private_ckd(HDNode *inout, uint32_t i)
{
	uint8_t data[1 + 32 + 4];
	uint8_t I[32 + 32];
	uint8_t fingerprint[32];
	bignum256 a, b;

	if (i & 0x80000000) { // private derivation
		data[0] = 0;
		memcpy(data + 1, inout->private_key, 32);
	} else { // public derivation
		memcpy(data, inout->public_key, 33);
	}
	write_be(data + 33, i);

	sha256_Raw(inout->public_key, 33, fingerprint);
	ripemd160(fingerprint, 32, fingerprint);
	inout->fingerprint = (fingerprint[0] << 24) + (fingerprint[1] << 16) + (fingerprint[2] << 8) + fingerprint[3];

	bn_read_be(inout->private_key, &a);

	hmac_sha512(inout->chain_code, 32, data, sizeof(data), I);
	memcpy(inout->chain_code, I + 32, 32);
	memcpy(inout->private_key, I, 32);

	bn_read_be(inout->private_key, &b);

	if (!bn_is_less(&b, &order256k1)) { // >= order
		return 0;
	}

	bn_addmod(&a, &b, &order256k1);

	if (bn_is_zero(&a)) {
		return 0;
	}

	inout->depth++;
	inout->child_num = i;
	bn_write_be(&a, inout->private_key);

	hdnode_fill_public_key(inout);

	return 1;
}
Example #29
0
void bn_div_rem_dig(bn_t c, dig_t *d, const bn_t a, dig_t b) {
	bn_t q;
	dig_t r;

	bn_null(q);

	if (b == 0) {
		THROW(ERR_NO_VALID);
	}

	if (b == 1 || bn_is_zero(a) == 1) {
		if (d != NULL) {
			*d = 0;
		}
		if (c != NULL) {
			bn_copy(c, a);
		}
		return;
	}

	TRY {
		bn_new(q);
		int size = a->used;
		const dig_t *ap = a->dp;

		bn_div1_low(q->dp, &r, ap, size, b);

		if (c != NULL) {
			q->used = a->used;
			q->sign = a->sign;
			bn_trim(q);
			bn_copy(c, q);
		}

		if (d != NULL) {
			*d = r;
		}
	}
	CATCH_ANY {
		THROW(ERR_CAUGHT);
	}
	FINALLY {
		bn_free(q);
	}
}
Example #30
0
int hdnode_from_seed(const uint8_t *seed, int seed_len, HDNode *out)
{
	uint8_t I[32 + 32];
	memset(out, 0, sizeof(HDNode));
	out->depth = 0;
	out->fingerprint = 0x00000000;
	out->child_num = 0;
	hmac_sha512((uint8_t *)"Bitcoin seed", 12, seed, seed_len, I);
	memcpy(out->private_key, I, 32);
	bignum256 a;
	bn_read_be(out->private_key, &a);
	if (bn_is_zero(&a) || !bn_is_less(&a, &order256k1)) { // == 0 or >= order
		return 0;
	}
	memcpy(out->chain_code, I + 32, 32);
	hdnode_fill_public_key(out);
	return 1;
}