comparison libtommath/bn_mp_is_square.c @ 1739:13d834efc376 fuzz

merge from main
author Matt Johnston <matt@ucc.asn.au>
date Thu, 15 Oct 2020 19:55:15 +0800
parents 1051e4eea25a
children
comparison
equal deleted inserted replaced
1562:768ebf737aa0 1739:13d834efc376
1 #include <tommath_private.h> 1 #include "tommath_private.h"
2 #ifdef BN_MP_IS_SQUARE_C 2 #ifdef BN_MP_IS_SQUARE_C
3 /* LibTomMath, multiple-precision integer library -- Tom St Denis 3 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
4 * 4 /* SPDX-License-Identifier: Unlicense */
5 * LibTomMath is a library that provides multiple-precision
6 * integer arithmetic as well as number theoretic functionality.
7 *
8 * The library was designed directly after the MPI library by
9 * Michael Fromberger but has been written from scratch with
10 * additional optimizations in place.
11 *
12 * The library is free for all purposes without any express
13 * guarantee it works.
14 *
15 * Tom St Denis, [email protected], http://libtom.org
16 */
17 5
18 /* Check if remainders are possible squares - fast exclude non-squares */ 6 /* Check if remainders are possible squares - fast exclude non-squares */
19 static const char rem_128[128] = { 7 static const char rem_128[128] = {
20 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 8 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
21 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 9 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
22 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 10 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
23 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 11 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
24 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 12 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
25 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 13 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
26 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 14 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
27 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1 15 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1
28 }; 16 };
29 17
30 static const char rem_105[105] = { 18 static const char rem_105[105] = {
31 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 19 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1,
32 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 20 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1,
33 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 21 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1,
34 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 22 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1,
35 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 23 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1,
36 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 24 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1,
37 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1 25 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1
38 }; 26 };
39 27
40 /* Store non-zero to ret if arg is square, and zero if not */ 28 /* Store non-zero to ret if arg is square, and zero if not */
41 int mp_is_square(mp_int *arg,int *ret) 29 mp_err mp_is_square(const mp_int *arg, mp_bool *ret)
42 { 30 {
43 int res; 31 mp_err err;
44 mp_digit c; 32 mp_digit c;
45 mp_int t; 33 mp_int t;
46 unsigned long r; 34 unsigned long r;
47 35
48 /* Default to Non-square :) */ 36 /* Default to Non-square :) */
49 *ret = MP_NO; 37 *ret = MP_NO;
50 38
51 if (arg->sign == MP_NEG) { 39 if (arg->sign == MP_NEG) {
52 return MP_VAL; 40 return MP_VAL;
53 } 41 }
54 42
55 /* digits used? (TSD) */ 43 if (MP_IS_ZERO(arg)) {
56 if (arg->used == 0) { 44 return MP_OKAY;
57 return MP_OKAY; 45 }
58 }
59 46
60 /* First check mod 128 (suppose that DIGIT_BIT is at least 7) */ 47 /* First check mod 128 (suppose that MP_DIGIT_BIT is at least 7) */
61 if (rem_128[127 & DIGIT(arg,0)] == 1) { 48 if (rem_128[127u & arg->dp[0]] == (char)1) {
62 return MP_OKAY; 49 return MP_OKAY;
63 } 50 }
64 51
65 /* Next check mod 105 (3*5*7) */ 52 /* Next check mod 105 (3*5*7) */
66 if ((res = mp_mod_d(arg,105,&c)) != MP_OKAY) { 53 if ((err = mp_mod_d(arg, 105uL, &c)) != MP_OKAY) {
67 return res; 54 return err;
68 } 55 }
69 if (rem_105[c] == 1) { 56 if (rem_105[c] == (char)1) {
70 return MP_OKAY; 57 return MP_OKAY;
71 } 58 }
72 59
73 60
74 if ((res = mp_init_set_int(&t,11L*13L*17L*19L*23L*29L*31L)) != MP_OKAY) { 61 if ((err = mp_init_u32(&t, 11u*13u*17u*19u*23u*29u*31u)) != MP_OKAY) {
75 return res; 62 return err;
76 } 63 }
77 if ((res = mp_mod(arg,&t,&t)) != MP_OKAY) { 64 if ((err = mp_mod(arg, &t, &t)) != MP_OKAY) {
78 goto ERR; 65 goto LBL_ERR;
79 } 66 }
80 r = mp_get_int(&t); 67 r = mp_get_u32(&t);
81 /* Check for other prime modules, note it's not an ERROR but we must 68 /* Check for other prime modules, note it's not an ERROR but we must
82 * free "t" so the easiest way is to goto ERR. We know that res 69 * free "t" so the easiest way is to goto LBL_ERR. We know that err
83 * is already equal to MP_OKAY from the mp_mod call 70 * is already equal to MP_OKAY from the mp_mod call
84 */ 71 */
85 if (((1L<<(r%11)) & 0x5C4L) != 0L) goto ERR; 72 if (((1uL<<(r%11uL)) & 0x5C4uL) != 0uL) goto LBL_ERR;
86 if (((1L<<(r%13)) & 0x9E4L) != 0L) goto ERR; 73 if (((1uL<<(r%13uL)) & 0x9E4uL) != 0uL) goto LBL_ERR;
87 if (((1L<<(r%17)) & 0x5CE8L) != 0L) goto ERR; 74 if (((1uL<<(r%17uL)) & 0x5CE8uL) != 0uL) goto LBL_ERR;
88 if (((1L<<(r%19)) & 0x4F50CL) != 0L) goto ERR; 75 if (((1uL<<(r%19uL)) & 0x4F50CuL) != 0uL) goto LBL_ERR;
89 if (((1L<<(r%23)) & 0x7ACCA0L) != 0L) goto ERR; 76 if (((1uL<<(r%23uL)) & 0x7ACCA0uL) != 0uL) goto LBL_ERR;
90 if (((1L<<(r%29)) & 0xC2EDD0CL) != 0L) goto ERR; 77 if (((1uL<<(r%29uL)) & 0xC2EDD0CuL) != 0uL) goto LBL_ERR;
91 if (((1L<<(r%31)) & 0x6DE2B848L) != 0L) goto ERR; 78 if (((1uL<<(r%31uL)) & 0x6DE2B848uL) != 0uL) goto LBL_ERR;
92 79
93 /* Final check - is sqr(sqrt(arg)) == arg ? */ 80 /* Final check - is sqr(sqrt(arg)) == arg ? */
94 if ((res = mp_sqrt(arg,&t)) != MP_OKAY) { 81 if ((err = mp_sqrt(arg, &t)) != MP_OKAY) {
95 goto ERR; 82 goto LBL_ERR;
96 } 83 }
97 if ((res = mp_sqr(&t,&t)) != MP_OKAY) { 84 if ((err = mp_sqr(&t, &t)) != MP_OKAY) {
98 goto ERR; 85 goto LBL_ERR;
99 } 86 }
100 87
101 *ret = (mp_cmp_mag(&t,arg) == MP_EQ) ? MP_YES : MP_NO; 88 *ret = (mp_cmp_mag(&t, arg) == MP_EQ) ? MP_YES : MP_NO;
102 ERR:mp_clear(&t); 89 LBL_ERR:
103 return res; 90 mp_clear(&t);
91 return err;
104 } 92 }
105 #endif 93 #endif
106
107 /* ref: $Format:%D$ */
108 /* git commit: $Format:%H$ */
109 /* commit time: $Format:%ai$ */