Mercurial > dropbear
view libtommath/bn_mp_is_square.c @ 1659:d32bcb5c557d
Add Ed25519 support (#91)
* Add support for Ed25519 as a public key type
Ed25519 is a elliptic curve signature scheme that offers
better security than ECDSA and DSA and good performance. It may be
used for both user and host keys.
OpenSSH key import and fuzzer are not supported yet.
Initially inspired by Peter Szabo.
* Add curve25519 and ed25519 fuzzers
* Add import and export of Ed25519 keys
author | Vladislav Grishenko <themiron@users.noreply.github.com> |
---|---|
date | Wed, 11 Mar 2020 21:09:45 +0500 |
parents | f52919ffd3b1 |
children | 1051e4eea25a |
line wrap: on
line source
#include "tommath_private.h" #ifdef BN_MP_IS_SQUARE_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * * SPDX-License-Identifier: Unlicense */ /* Check if remainders are possible squares - fast exclude non-squares */ static const char rem_128[128] = { 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1 }; static const char rem_105[105] = { 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1 }; /* Store non-zero to ret if arg is square, and zero if not */ int mp_is_square(const mp_int *arg, int *ret) { int res; mp_digit c; mp_int t; unsigned long r; /* Default to Non-square :) */ *ret = MP_NO; if (arg->sign == MP_NEG) { return MP_VAL; } /* digits used? (TSD) */ if (arg->used == 0) { return MP_OKAY; } /* First check mod 128 (suppose that DIGIT_BIT is at least 7) */ if (rem_128[127u & DIGIT(arg, 0)] == (char)1) { return MP_OKAY; } /* Next check mod 105 (3*5*7) */ if ((res = mp_mod_d(arg, 105uL, &c)) != MP_OKAY) { return res; } if (rem_105[c] == (char)1) { return MP_OKAY; } if ((res = mp_init_set_int(&t, 11L*13L*17L*19L*23L*29L*31L)) != MP_OKAY) { return res; } if ((res = mp_mod(arg, &t, &t)) != MP_OKAY) { goto LBL_ERR; } r = mp_get_int(&t); /* Check for other prime modules, note it's not an ERROR but we must * free "t" so the easiest way is to goto LBL_ERR. We know that res * is already equal to MP_OKAY from the mp_mod call */ if (((1uL<<(r%11uL)) & 0x5C4uL) != 0uL) goto LBL_ERR; if (((1uL<<(r%13uL)) & 0x9E4uL) != 0uL) goto LBL_ERR; if (((1uL<<(r%17uL)) & 0x5CE8uL) != 0uL) goto LBL_ERR; if (((1uL<<(r%19uL)) & 0x4F50CuL) != 0uL) goto LBL_ERR; if (((1uL<<(r%23uL)) & 0x7ACCA0uL) != 0uL) goto LBL_ERR; if (((1uL<<(r%29uL)) & 0xC2EDD0CuL) != 0uL) goto LBL_ERR; if (((1uL<<(r%31uL)) & 0x6DE2B848uL) != 0uL) goto LBL_ERR; /* Final check - is sqr(sqrt(arg)) == arg ? */ if ((res = mp_sqrt(arg, &t)) != MP_OKAY) { goto LBL_ERR; } if ((res = mp_sqr(&t, &t)) != MP_OKAY) { goto LBL_ERR; } *ret = (mp_cmp_mag(&t, arg) == MP_EQ) ? MP_YES : MP_NO; LBL_ERR: mp_clear(&t); return res; } #endif /* ref: HEAD -> master, tag: v1.1.0 */ /* git commit: 08549ad6bc8b0cede0b357a9c341c5c6473a9c55 */ /* commit time: 2019-01-28 20:32:32 +0100 */