mirror of
https://salsa.debian.org/gnuk-team/gnuk/gnuk.git
synced 2024-09-20 10:50:09 +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>
|
2013-07-19 Niibe Yutaka <gniibe@fsij.org>
|
||||||
|
|
||||||
* src/gnuk.ld.in: Layout change following NeuG.
|
* 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
|
* 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>
|
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||||
*
|
*
|
||||||
* This file is a part of Gnuk, a GnuPG USB Token implementation.
|
* 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;
|
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
|
void
|
||||||
bn256_random (bn256 *X)
|
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_zero (const bn256 *X);
|
||||||
int bn256_is_even (const bn256 *X);
|
int bn256_is_even (const bn256 *X);
|
||||||
int bn256_is_ge (const bn256 *A, const bn256 *B);
|
int bn256_is_ge (const bn256 *A, const bn256 *B);
|
||||||
|
int bn256_cmp (const bn256 *A, const bn256 *B);
|
||||||
void bn256_random (bn256 *X);
|
void bn256_random (bn256 *X);
|
||||||
|
@ -77,7 +77,12 @@ ecdsa_compute_public (const uint8_t *key_data)
|
|||||||
p = (uint8_t *)k;
|
p = (uint8_t *)k;
|
||||||
for (i = 0; i < ECDSA_BYTE_SIZE; i++)
|
for (i = 0; i < ECDSA_BYTE_SIZE; i++)
|
||||||
p[ECDSA_BYTE_SIZE - i - 1] = key_data[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;
|
p = p0;
|
||||||
p1 = (uint8_t *)q->x;
|
p1 = (uint8_t *)q->x;
|
||||||
for (i = 0; i < ECDSA_BYTE_SIZE; i++)
|
for (i = 0; i < ECDSA_BYTE_SIZE; i++)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* ec_p256.c - Elliptic curve over GF(p256)
|
* 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>
|
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||||
*
|
*
|
||||||
* This file is a part of Gnuk, a GnuPG USB Token implementation.
|
* 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
|
* @brief X = k * G
|
||||||
*
|
*
|
||||||
* @param K scalar k
|
* @param K scalar k
|
||||||
|
*
|
||||||
|
* Return -1 on error.
|
||||||
|
* Return 0 on success.
|
||||||
*/
|
*/
|
||||||
void
|
int
|
||||||
compute_kG (ac *X, const bn256 *K)
|
compute_kG (ac *X, const bn256 *K)
|
||||||
{
|
{
|
||||||
int i;
|
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
|
* @brief X = k * P
|
||||||
*
|
*
|
||||||
* @param NAF_K NAF representation of k
|
* @param NAF_K NAF representation of k
|
||||||
* @param P P in affin coordiate
|
* @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)
|
compute_kP (ac *X, const naf4_257 *NAF_K, const ac *P)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@ -381,6 +401,10 @@ compute_kP (ac *X, const naf4_257 *NAF_K, const ac *P)
|
|||||||
jpc Q[1];
|
jpc Q[1];
|
||||||
ac P3[1], P5[1], P7[1];
|
ac P3[1], P5[1], P7[1];
|
||||||
const ac *p_Pi[4];
|
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[0] = P;
|
||||||
p_Pi[1] = P3;
|
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_double (Q, Q);
|
||||||
jpc_add_ac (Q1, Q, P);
|
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_double (Q, Q);
|
||||||
jpc_add_ac (Q1, Q, P);
|
jpc_add_ac (Q1, Q, P);
|
||||||
jpc_to_ac (P5, Q1);
|
if (jpc_to_ac (P5, Q1) < 0)
|
||||||
|
Pi_is_infinite[2] = 1;
|
||||||
memcpy (Q->x, P3->x, sizeof (bn256));
|
if (Pi_is_infinite[1] == 0)
|
||||||
memcpy (Q->y, P3->y, sizeof (bn256));
|
{
|
||||||
memset (Q->z, 0, sizeof (bn256));
|
memcpy (Q->x, P3->x, sizeof (bn256));
|
||||||
Q->z->words[0] = 1;
|
memcpy (Q->y, P3->y, sizeof (bn256));
|
||||||
jpc_double (Q, Q);
|
memset (Q->z, 0, sizeof (bn256));
|
||||||
jpc_add_ac (Q1, Q, P);
|
Q->z->words[0] = 1;
|
||||||
jpc_to_ac (P7, Q1);
|
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--)
|
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);
|
jpc_double (Q, Q);
|
||||||
|
|
||||||
k_i = naf4_257_get (NAF_K, i);
|
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)
|
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;
|
} naf4_257;
|
||||||
|
|
||||||
void compute_naf4_257 (naf4_257 *NAF_K, const bn256 *K);
|
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);
|
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_double (jpc *X, const jpc *A);
|
||||||
void jpc_add_ac (jpc *X, const jpc *A, const ac *B);
|
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_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
|
* 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>
|
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||||
*
|
*
|
||||||
* This file is a part of Gnuk, a GnuPG USB Token implementation.
|
* 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 y3_tmp c
|
||||||
#define y1_c_cube a
|
#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);
|
modp256_sqr (a, A->z);
|
||||||
memcpy (b, a, sizeof (bn256));
|
memcpy (b, a, sizeof (bn256));
|
||||||
modp256_mul (a, a, B->x);
|
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
|
else
|
||||||
modp256_mul (b, b, B->y);
|
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 (c, a, A->x);
|
||||||
modp256_sub (d, b, A->y);
|
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 X Destination AC
|
||||||
* @param A JPC
|
* @param A JPC
|
||||||
|
*
|
||||||
|
* Return -1 on error (infinite).
|
||||||
|
* Return 0 on success.
|
||||||
*/
|
*/
|
||||||
void
|
int
|
||||||
jpc_to_ac (ac *X, const jpc *A)
|
jpc_to_ac (ac *X, const jpc *A)
|
||||||
{
|
{
|
||||||
bn256 z_inv[1], z_inv_sqr[1];
|
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_sqr (z_inv_sqr, z_inv);
|
||||||
modp256_mul (z_inv, z_inv, z_inv_sqr);
|
modp256_mul (z_inv, z_inv, z_inv_sqr);
|
||||||
|
|
||||||
modp256_mul (X->x, A->x, z_inv_sqr);
|
modp256_mul (X->x, A->x, z_inv_sqr);
|
||||||
modp256_mul (X->y, A->y, z_inv);
|
modp256_mul (X->y, A->y, z_inv);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* modp256.c -- modulo P256 arithmetic
|
* 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>
|
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||||
*
|
*
|
||||||
* This file is a part of Gnuk, a GnuPG USB Token implementation.
|
* 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
|
* @brief C = (1 / a) mod p256
|
||||||
|
*
|
||||||
|
* Return -1 on error.
|
||||||
|
* Return 0 on success.
|
||||||
*/
|
*/
|
||||||
void
|
int
|
||||||
modp256_inv (bn256 *C, const bn256 *a)
|
modp256_inv (bn256 *C, const bn256 *a)
|
||||||
{
|
{
|
||||||
bn256 u[1], v[1];
|
bn256 u[1], v[1];
|
||||||
bn256 A[1] = { { { 1, 0, 0, 0, 0, 0, 0, 0 } } };
|
bn256 A[1] = { { { 1, 0, 0, 0, 0, 0, 0, 0 } } };
|
||||||
|
|
||||||
|
if (bn256_is_zero (a))
|
||||||
|
return -1;
|
||||||
|
|
||||||
memset (C, 0, sizeof (bn256));
|
memset (C, 0, sizeof (bn256));
|
||||||
memcpy (u, a, sizeof (bn256));
|
memcpy (u, a, sizeof (bn256));
|
||||||
memcpy (v, P256, sizeof (bn256));
|
memcpy (v, P256, sizeof (bn256));
|
||||||
@ -265,6 +271,8 @@ modp256_inv (bn256 *C, const bn256 *a)
|
|||||||
modp256_sub (C, C, 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_reduce (bn256 *X, const bn512 *A);
|
||||||
void modp256_mul (bn256 *X, const bn256 *A, const bn256 *B);
|
void modp256_mul (bn256 *X, const bn256 *A, const bn256 *B);
|
||||||
void modp256_sqr (bn256 *X, const bn256 *A);
|
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);
|
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