Downgrade BN_kronecker to bn_jacobi and unexport.
We only ever compute it for odd (actually, prime) modulus as part of BN_mod_sqrt. If we cared, we could probably drop this from most binaries. This is used to when modular square root needs Tonelli-Shanks. Modular square root is only used for compressed coordinates. Of our supported curves (I'm handwaiving away EC_GROUP_new_curve_GFp here[*]), only P-224 needs the full Tonelli-Shanks algorithm (p is 1 mod 8). That computes the Legendre symbol a bunch to find a non-square mod p. But p is known at compile-time, so we can just hard-code a sample non-square. Sadly, BN_mod_sqrt has some callers outside of crypto/ec, so there's also that. Anyway, it's also not that large of a function. [*] Glancing through SEC 2 and Brainpool, secp224r1 is the only curve listed in either document whose prime is not either 3 mod 4 or 5 mod 8. Even 5 mod 8 is rare: only secp224k1. It's unlikely anyone would notice if we broke annoying primes. Though OpenSSL does support "WTLS" curves which has an additional 1 mod 8 case. Change-Id: If36aa78c0d41253ec024f2d90692949515356cd1 Reviewed-on: https://boringssl-review.googlesource.com/15425 Reviewed-by: Adam Langley <agl@google.com>
This commit is contained in:
parent
0d5bf8d86d
commit
a684152a2f
@ -54,7 +54,7 @@ add_library(
|
||||
exponentiation.c
|
||||
generic.c
|
||||
gcd.c
|
||||
kronecker.c
|
||||
jacobi.c
|
||||
montgomery.c
|
||||
montgomery_inv.c
|
||||
mul.c
|
||||
|
@ -259,6 +259,10 @@ int bn_mod_inverse_prime(BIGNUM *out, const BIGNUM *a, const BIGNUM *p,
|
||||
int bn_mod_inverse_secret_prime(BIGNUM *out, const BIGNUM *a, const BIGNUM *p,
|
||||
BN_CTX *ctx, const BN_MONT_CTX *mont_p);
|
||||
|
||||
/* bn_jacobi returns the Jacobi symbol of |a| and |b| (which is -1, 0 or 1), or
|
||||
* -2 on error. */
|
||||
int bn_jacobi(const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
|
||||
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} /* extern C */
|
||||
|
@ -52,17 +52,15 @@
|
||||
|
||||
#include <openssl/bn.h>
|
||||
|
||||
#include <openssl/err.h>
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
|
||||
/* least significant word */
|
||||
#define BN_lsw(n) (((n)->top == 0) ? (BN_ULONG) 0 : (n)->d[0])
|
||||
|
||||
/* Returns -2 for errors because both -1 and 0 are valid results. */
|
||||
int BN_kronecker(const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) {
|
||||
int i;
|
||||
int ret = -2;
|
||||
BIGNUM *A, *B, *tmp;
|
||||
int bn_jacobi(const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) {
|
||||
/* In 'tab', only odd-indexed entries are relevant:
|
||||
* For any odd BIGNUM n,
|
||||
* tab[BN_lsw(n) & 7]
|
||||
@ -70,9 +68,22 @@ int BN_kronecker(const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) {
|
||||
* Note that the sign of n does not matter. */
|
||||
static const int tab[8] = {0, 1, 0, -1, 0, -1, 0, 1};
|
||||
|
||||
/* The Jacobi symbol is only defined for odd modulus. */
|
||||
if (!BN_is_odd(b)) {
|
||||
OPENSSL_PUT_ERROR(BN, BN_R_CALLED_WITH_EVEN_MODULUS);
|
||||
return -2;
|
||||
}
|
||||
|
||||
/* Require b be positive. */
|
||||
if (BN_is_negative(b)) {
|
||||
OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER);
|
||||
return -2;
|
||||
}
|
||||
|
||||
int ret = -2;
|
||||
BN_CTX_start(ctx);
|
||||
A = BN_CTX_get(ctx);
|
||||
B = BN_CTX_get(ctx);
|
||||
BIGNUM *A = BN_CTX_get(ctx);
|
||||
BIGNUM *B = BN_CTX_get(ctx);
|
||||
if (B == NULL) {
|
||||
goto end;
|
||||
}
|
||||
@ -82,52 +93,11 @@ int BN_kronecker(const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* Kronecker symbol, imlemented according to Henri Cohen,
|
||||
* "A Course in Computational Algebraic Number Theory"
|
||||
* (algorithm 1.4.10). */
|
||||
/* Adapted from logic to compute the Kronecker symbol, originally implemented
|
||||
* according to Henri Cohen, "A Course in Computational Algebraic Number
|
||||
* Theory" (algorithm 1.4.10). */
|
||||
|
||||
/* Cohen's step 1: */
|
||||
|
||||
if (BN_is_zero(B)) {
|
||||
ret = BN_abs_is_word(A, 1);
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* Cohen's step 2: */
|
||||
|
||||
if (!BN_is_odd(A) && !BN_is_odd(B)) {
|
||||
ret = 0;
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* now B is non-zero */
|
||||
i = 0;
|
||||
while (!BN_is_bit_set(B, i)) {
|
||||
i++;
|
||||
}
|
||||
if (!BN_rshift(B, B, i)) {
|
||||
goto end;
|
||||
}
|
||||
if (i & 1) {
|
||||
/* i is odd */
|
||||
/* (thus B was even, thus A must be odd!) */
|
||||
|
||||
/* set 'ret' to $(-1)^{(A^2-1)/8}$ */
|
||||
ret = tab[BN_lsw(A) & 7];
|
||||
} else {
|
||||
/* i is even */
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
if (B->neg) {
|
||||
B->neg = 0;
|
||||
if (A->neg) {
|
||||
ret = -ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* now B is positive and odd, so what remains to be done is to compute the
|
||||
* Jacobi symbol (A/B) and multiply it by 'ret' */
|
||||
ret = 1;
|
||||
|
||||
while (1) {
|
||||
/* Cohen's step 3: */
|
||||
@ -139,7 +109,7 @@ int BN_kronecker(const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) {
|
||||
}
|
||||
|
||||
/* now A is non-zero */
|
||||
i = 0;
|
||||
int i = 0;
|
||||
while (!BN_is_bit_set(A, i)) {
|
||||
i++;
|
||||
}
|
||||
@ -164,7 +134,7 @@ int BN_kronecker(const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) {
|
||||
ret = -2;
|
||||
goto end;
|
||||
}
|
||||
tmp = A;
|
||||
BIGNUM *tmp = A;
|
||||
A = B;
|
||||
B = tmp;
|
||||
tmp->neg = 0;
|
@ -56,6 +56,8 @@
|
||||
|
||||
#include <openssl/err.h>
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
|
||||
BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) {
|
||||
/* Compute a square root of |a| mod |p| using the Tonelli/Shanks algorithm
|
||||
@ -253,7 +255,7 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) {
|
||||
}
|
||||
}
|
||||
|
||||
r = BN_kronecker(y, q, ctx); /* here 'q' is |p| */
|
||||
r = bn_jacobi(y, q, ctx); /* here 'q' is |p| */
|
||||
if (r < -1) {
|
||||
goto end;
|
||||
}
|
||||
|
@ -797,10 +797,6 @@ int BN_mod_inverse_blinded(BIGNUM *out, int *out_no_inverse, const BIGNUM *a,
|
||||
int BN_mod_inverse_odd(BIGNUM *out, int *out_no_inverse, const BIGNUM *a,
|
||||
const BIGNUM *n, BN_CTX *ctx);
|
||||
|
||||
/* BN_kronecker returns the Kronecker symbol of |a| and |b| (which is -1, 0 or
|
||||
* 1), or -2 on error. */
|
||||
OPENSSL_EXPORT int BN_kronecker(const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
|
||||
|
||||
|
||||
/* Montgomery arithmetic. */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user