mirror of
https://salsa.debian.org/gnuk-team/gnuk/gnuk.git
synced 2024-09-20 02:40:08 +00:00
fix ECC
This commit is contained in:
parent
b2fb734d57
commit
ee1e1ac851
15
ChangeLog
15
ChangeLog
@ -1,3 +1,18 @@
|
||||
2013-09-20 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/call-ec_p256.c (ecdsa_compute_public): Handle possible
|
||||
error (where key_data is the order).
|
||||
|
||||
* src/ec_p256.c (on_the_curve): New.
|
||||
(compute_kG, compute_kP): Handle errors.
|
||||
|
||||
* src/jpc.c (jpc_to_ac): Return -1 on error.
|
||||
(jpc_add_ac_signed): Handle the case where A=inf.
|
||||
|
||||
* src/modp256.c (modp256_inv): Handle error case.
|
||||
|
||||
* src/bn.c (bn256_cmp): New.
|
||||
|
||||
2013-07-19 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/gnuk.ld.in: Layout change following NeuG.
|
||||
|
18
src/bn.c
18
src/bn.c
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* bn.c -- 256-bit (and 512-bit) bignum calculation
|
||||
*
|
||||
* Copyright (C) 2011 Free Software Initiative of Japan
|
||||
* Copyright (C) 2011, 2013 Free Software Initiative of Japan
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
*
|
||||
* This file is a part of Gnuk, a GnuPG USB Token implementation.
|
||||
@ -306,6 +306,22 @@ bn256_is_ge (const bn256 *A, const bn256 *B)
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
bn256_cmp (const bn256 *A, const bn256 *B)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = BN256_WORDS - 1; i >= 0; i--)
|
||||
if (A->words[i] > B->words[i])
|
||||
return 1;
|
||||
else if (A->words[i] < B->words[i])
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
bn256_random (bn256 *X)
|
||||
{
|
||||
|
1
src/bn.h
1
src/bn.h
@ -19,4 +19,5 @@ uint32_t bn256_shift (bn256 *X, const bn256 *A, int shift);
|
||||
int bn256_is_zero (const bn256 *X);
|
||||
int bn256_is_even (const bn256 *X);
|
||||
int bn256_is_ge (const bn256 *A, const bn256 *B);
|
||||
int bn256_cmp (const bn256 *A, const bn256 *B);
|
||||
void bn256_random (bn256 *X);
|
||||
|
@ -77,7 +77,12 @@ ecdsa_compute_public (const uint8_t *key_data)
|
||||
p = (uint8_t *)k;
|
||||
for (i = 0; i < ECDSA_BYTE_SIZE; i++)
|
||||
p[ECDSA_BYTE_SIZE - i - 1] = key_data[i];
|
||||
compute_kG (q, k);
|
||||
if (compute_kG (q, k) < 0)
|
||||
{
|
||||
free (p0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
p = p0;
|
||||
p1 = (uint8_t *)q->x;
|
||||
for (i = 0; i < ECDSA_BYTE_SIZE; i++)
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* ec_p256.c - Elliptic curve over GF(p256)
|
||||
*
|
||||
* Copyright (C) 2011 Free Software Initiative of Japan
|
||||
* Copyright (C) 2011, 2013 Free Software Initiative of Japan
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
*
|
||||
* This file is a part of Gnuk, a GnuPG USB Token implementation.
|
||||
@ -227,8 +227,11 @@ static const ac precomputed_2E_KG[15] = {
|
||||
* @brief X = k * G
|
||||
*
|
||||
* @param K scalar k
|
||||
*
|
||||
* Return -1 on error.
|
||||
* Return 0 on success.
|
||||
*/
|
||||
void
|
||||
int
|
||||
compute_kG (ac *X, const bn256 *K)
|
||||
{
|
||||
int i;
|
||||
@ -281,7 +284,7 @@ compute_kG (ac *X, const bn256 *K)
|
||||
}
|
||||
}
|
||||
|
||||
jpc_to_ac (X, Q);
|
||||
return jpc_to_ac (X, Q);
|
||||
}
|
||||
|
||||
|
||||
@ -367,13 +370,30 @@ compute_naf4_257 (naf4_257 *NAF_K, const bn256 *K)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* check if P is on the curve.
|
||||
*
|
||||
* Return -1 on error.
|
||||
* Return 0 on success.
|
||||
*/
|
||||
static int
|
||||
point_is_on_the_curve (const ac *P)
|
||||
{
|
||||
/* y^2 = x^3 + a*x + b */
|
||||
/* XXX: Not yet */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief X = k * P
|
||||
*
|
||||
* @param NAF_K NAF representation of k
|
||||
* @param P P in affin coordiate
|
||||
*
|
||||
* Return -1 on error.
|
||||
* Return 0 on success.
|
||||
*/
|
||||
void
|
||||
int
|
||||
compute_kP (ac *X, const naf4_257 *NAF_K, const ac *P)
|
||||
{
|
||||
int i;
|
||||
@ -381,6 +401,10 @@ compute_kP (ac *X, const naf4_257 *NAF_K, const ac *P)
|
||||
jpc Q[1];
|
||||
ac P3[1], P5[1], P7[1];
|
||||
const ac *p_Pi[4];
|
||||
int Pi_is_infinite[4] = { 0, 0, 0, 0 };
|
||||
|
||||
if (point_is_on_the_curve (P) < 0)
|
||||
return -1;
|
||||
|
||||
p_Pi[0] = P;
|
||||
p_Pi[1] = P3;
|
||||
@ -397,18 +421,28 @@ compute_kP (ac *X, const naf4_257 *NAF_K, const ac *P)
|
||||
|
||||
jpc_double (Q, Q);
|
||||
jpc_add_ac (Q1, Q, P);
|
||||
jpc_to_ac (P3, Q1);
|
||||
if (jpc_to_ac (P3, Q1) < 0)
|
||||
Pi_is_infinite[1] = 1;
|
||||
jpc_double (Q, Q);
|
||||
jpc_add_ac (Q1, Q, P);
|
||||
jpc_to_ac (P5, Q1);
|
||||
|
||||
memcpy (Q->x, P3->x, sizeof (bn256));
|
||||
memcpy (Q->y, P3->y, sizeof (bn256));
|
||||
memset (Q->z, 0, sizeof (bn256));
|
||||
Q->z->words[0] = 1;
|
||||
jpc_double (Q, Q);
|
||||
jpc_add_ac (Q1, Q, P);
|
||||
jpc_to_ac (P7, Q1);
|
||||
if (jpc_to_ac (P5, Q1) < 0)
|
||||
Pi_is_infinite[2] = 1;
|
||||
if (Pi_is_infinite[1] == 0)
|
||||
{
|
||||
memcpy (Q->x, P3->x, sizeof (bn256));
|
||||
memcpy (Q->y, P3->y, sizeof (bn256));
|
||||
memset (Q->z, 0, sizeof (bn256));
|
||||
Q->z->words[0] = 1;
|
||||
jpc_double (Q, Q);
|
||||
jpc_add_ac (Q1, Q, P);
|
||||
if (jpc_to_ac (P7, Q1) < 0)
|
||||
Pi_is_infinite[3] = 1;
|
||||
}
|
||||
else
|
||||
{ /* P7 <= P4 */
|
||||
if (jpc_to_ac (P7, Q) < 0)
|
||||
Pi_is_infinite[3] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 256; i >= 0; i--)
|
||||
@ -419,7 +453,7 @@ compute_kP (ac *X, const naf4_257 *NAF_K, const ac *P)
|
||||
jpc_double (Q, Q);
|
||||
|
||||
k_i = naf4_257_get (NAF_K, i);
|
||||
if (k_i)
|
||||
if (k_i && Pi_is_infinite[NAF_K_INDEX(k_i)] == 0)
|
||||
{
|
||||
if (q_is_infinite)
|
||||
{
|
||||
@ -437,7 +471,7 @@ compute_kP (ac *X, const naf4_257 *NAF_K, const ac *P)
|
||||
}
|
||||
}
|
||||
|
||||
jpc_to_ac (X, Q);
|
||||
return jpc_to_ac (X, Q);
|
||||
}
|
||||
|
||||
|
||||
|
@ -5,8 +5,8 @@ typedef struct naf4_257 {
|
||||
} naf4_257;
|
||||
|
||||
void compute_naf4_257 (naf4_257 *NAF_K, const bn256 *K);
|
||||
void compute_kP (ac *X, const naf4_257 *NAF_K, const ac *P);
|
||||
int compute_kP (ac *X, const naf4_257 *NAF_K, const ac *P);
|
||||
|
||||
void compute_kG (ac *X, const bn256 *K);
|
||||
int compute_kG (ac *X, const bn256 *K);
|
||||
void ecdsa (bn256 *r, bn256 *s, const bn256 *z, const bn256 *d);
|
||||
|
||||
|
@ -20,4 +20,4 @@ typedef struct
|
||||
void jpc_double (jpc *X, const jpc *A);
|
||||
void jpc_add_ac (jpc *X, const jpc *A, const ac *B);
|
||||
void jpc_add_ac_signed (jpc *X, const jpc *A, const ac *B, int minus);
|
||||
void jpc_to_ac (ac *X, const jpc *A);
|
||||
int jpc_to_ac (ac *X, const jpc *A);
|
||||
|
31
src/jpc.c
31
src/jpc.c
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* jpc.c -- arithmetic on Jacobian projective coordinates and Affin coordinates
|
||||
*
|
||||
* Copyright (C) 2011 Free Software Initiative of Japan
|
||||
* Copyright (C) 2011, 2013 Free Software Initiative of Japan
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
*
|
||||
* This file is a part of Gnuk, a GnuPG USB Token implementation.
|
||||
@ -88,6 +88,18 @@ jpc_add_ac_signed (jpc *X, const jpc *A, const ac *B, int minus)
|
||||
#define y3_tmp c
|
||||
#define y1_c_cube a
|
||||
|
||||
if (A->z == 0) /* A is infinite */
|
||||
{
|
||||
memcpy (X->x, B->x, sizeof (bn256));
|
||||
if (minus)
|
||||
bn256_sub (X->y, P256, B->y);
|
||||
else
|
||||
memcpy (X->y, B->y, sizeof (bn256));
|
||||
memset (X->z, 0, sizeof (bn256));
|
||||
X->z->words[0] = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
modp256_sqr (a, A->z);
|
||||
memcpy (b, a, sizeof (bn256));
|
||||
modp256_mul (a, a, B->x);
|
||||
@ -101,6 +113,13 @@ jpc_add_ac_signed (jpc *X, const jpc *A, const ac *B, int minus)
|
||||
else
|
||||
modp256_mul (b, b, B->y);
|
||||
|
||||
if (bn256_cmp (A->x, a) == 0)
|
||||
if (bn256_cmp (A->y, b) == 0)
|
||||
{
|
||||
jpc_double (X, A);
|
||||
return;
|
||||
}
|
||||
|
||||
modp256_sub (c, a, A->x);
|
||||
modp256_sub (d, b, A->y);
|
||||
|
||||
@ -141,16 +160,22 @@ jpc_add_ac (jpc *X, const jpc *A, const ac *B)
|
||||
*
|
||||
* @param X Destination AC
|
||||
* @param A JPC
|
||||
*
|
||||
* Return -1 on error (infinite).
|
||||
* Return 0 on success.
|
||||
*/
|
||||
void
|
||||
int
|
||||
jpc_to_ac (ac *X, const jpc *A)
|
||||
{
|
||||
bn256 z_inv[1], z_inv_sqr[1];
|
||||
|
||||
modp256_inv (z_inv, A->z);
|
||||
if (modp256_inv (z_inv, A->z) < 0)
|
||||
return -1;
|
||||
|
||||
modp256_sqr (z_inv_sqr, z_inv);
|
||||
modp256_mul (z_inv, z_inv, z_inv_sqr);
|
||||
|
||||
modp256_mul (X->x, A->x, z_inv_sqr);
|
||||
modp256_mul (X->y, A->y, z_inv);
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* modp256.c -- modulo P256 arithmetic
|
||||
*
|
||||
* Copyright (C) 2011 Free Software Initiative of Japan
|
||||
* Copyright (C) 2011, 2013 Free Software Initiative of Japan
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
*
|
||||
* This file is a part of Gnuk, a GnuPG USB Token implementation.
|
||||
@ -211,13 +211,19 @@ modp256_sqr (bn256 *X, const bn256 *A)
|
||||
|
||||
/**
|
||||
* @brief C = (1 / a) mod p256
|
||||
*
|
||||
* Return -1 on error.
|
||||
* Return 0 on success.
|
||||
*/
|
||||
void
|
||||
int
|
||||
modp256_inv (bn256 *C, const bn256 *a)
|
||||
{
|
||||
bn256 u[1], v[1];
|
||||
bn256 A[1] = { { { 1, 0, 0, 0, 0, 0, 0, 0 } } };
|
||||
|
||||
if (bn256_is_zero (a))
|
||||
return -1;
|
||||
|
||||
memset (C, 0, sizeof (bn256));
|
||||
memcpy (u, a, sizeof (bn256));
|
||||
memcpy (v, P256, sizeof (bn256));
|
||||
@ -265,6 +271,8 @@ modp256_inv (bn256 *C, const bn256 *a)
|
||||
modp256_sub (C, C, A);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -6,5 +6,5 @@ void modp256_sub (bn256 *X, const bn256 *A, const bn256 *B);
|
||||
void modp256_reduce (bn256 *X, const bn512 *A);
|
||||
void modp256_mul (bn256 *X, const bn256 *A, const bn256 *B);
|
||||
void modp256_sqr (bn256 *X, const bn256 *A);
|
||||
void modp256_inv (bn256 *C, const bn256 *a);
|
||||
void modp256_shift (bn256 *X, const bn256 *A, int shift);
|
||||
int modp256_inv (bn256 *C, const bn256 *a);
|
||||
|
Loading…
Reference in New Issue
Block a user