Austin Schuh | dace2a6 | 2020-08-18 10:56:48 -0700 | [diff] [blame] | 1 | /* gen-jacobi.c |
| 2 | |
| 3 | Contributed to the GNU project by Niels Möller. |
| 4 | |
| 5 | Copyright 2010 Free Software Foundation, Inc. |
| 6 | |
| 7 | This file is part of the GNU MP Library. |
| 8 | |
| 9 | The GNU MP Library is free software; you can redistribute it and/or modify |
| 10 | it under the terms of either: |
| 11 | |
| 12 | * the GNU Lesser General Public License as published by the Free |
| 13 | Software Foundation; either version 3 of the License, or (at your |
| 14 | option) any later version. |
| 15 | |
| 16 | or |
| 17 | |
| 18 | * the GNU General Public License as published by the Free Software |
| 19 | Foundation; either version 2 of the License, or (at your option) any |
| 20 | later version. |
| 21 | |
| 22 | or both in parallel, as here. |
| 23 | |
| 24 | The GNU MP Library is distributed in the hope that it will be useful, but |
| 25 | WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
| 26 | or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| 27 | for more details. |
| 28 | |
| 29 | You should have received copies of the GNU General Public License and the |
| 30 | GNU Lesser General Public License along with the GNU MP Library. If not, |
| 31 | see https://www.gnu.org/licenses/. */ |
| 32 | |
| 33 | /* Generate the lookup table needed for fast left-to-right computation |
| 34 | of the Jacobi symbol. */ |
| 35 | |
| 36 | #include <assert.h> |
| 37 | #include <stdio.h> |
| 38 | #include <stdlib.h> |
| 39 | |
| 40 | static const struct |
| 41 | { |
| 42 | unsigned char a; |
| 43 | unsigned char b; |
| 44 | } decode_table[13] = { |
| 45 | /* 0 */ { 0, 1 }, |
| 46 | /* 1 */ { 0, 3 }, |
| 47 | /* 2 */ { 1, 1 }, |
| 48 | /* 3 */ { 1, 3 }, |
| 49 | /* 4 */ { 2, 1 }, |
| 50 | /* 5 */ { 2, 3 }, |
| 51 | /* 6 */ { 3, 1 }, |
| 52 | /* 7 */ { 3, 3 }, /* d = 1 */ |
| 53 | /* 8 */ { 1, 0 }, |
| 54 | /* 9 */ { 1, 2 }, |
| 55 | /* 10 */ { 3, 0 }, |
| 56 | /* 11 */ { 3, 2 }, |
| 57 | /* 12 */ { 3, 3 }, /* d = 0 */ |
| 58 | |
| 59 | }; |
| 60 | #define JACOBI_A(bits) (decode_table[(bits)>>1].a) |
| 61 | #define JACOBI_B(bits) (decode_table[(bits)>>1].b) |
| 62 | |
| 63 | #define JACOBI_E(bits) ((bits) & 1) |
| 64 | #define JACOBI_D(bits) (((bits)>>1) == 7) /* Gives 0 for don't care states. */ |
| 65 | |
| 66 | static unsigned |
| 67 | encode (unsigned a, unsigned b, unsigned d) |
| 68 | { |
| 69 | unsigned i; |
| 70 | |
| 71 | assert (d < 2); |
| 72 | assert (a < 4); |
| 73 | assert (b < 4); |
| 74 | assert ( (a | b ) & 1); |
| 75 | |
| 76 | if (a == 3 && b == 3) |
| 77 | return d ? 7 : 12; |
| 78 | |
| 79 | for (i = 0; i < 12; i++) |
| 80 | if (decode_table[i].a == a |
| 81 | && decode_table[i].b == b) |
| 82 | return i; |
| 83 | |
| 84 | abort (); |
| 85 | } |
| 86 | |
| 87 | int |
| 88 | main (int argc, char **argv) |
| 89 | { |
| 90 | unsigned bits; |
| 91 | |
| 92 | for (bits = 0; bits < 208; bits++) |
| 93 | { |
| 94 | unsigned e, a, b, d_old, d, q; |
| 95 | |
| 96 | if (bits && !(bits & 0xf)) |
| 97 | printf("\n"); |
| 98 | |
| 99 | q = bits & 3; |
| 100 | d = (bits >> 2) & 1; |
| 101 | |
| 102 | e = JACOBI_E (bits >> 3); |
| 103 | a = JACOBI_A (bits >> 3); |
| 104 | b = JACOBI_B (bits >> 3); |
| 105 | d_old = JACOBI_D (bits >> 3); |
| 106 | |
| 107 | if (d != d_old && a == 3 && b == 3) |
| 108 | e ^= 1; |
| 109 | |
| 110 | if (d == 1) |
| 111 | { |
| 112 | if (b == 2) |
| 113 | e ^= (q & (a >> 1)) ^ (q >> 1); |
| 114 | a = (a - q * b) & 3; |
| 115 | } |
| 116 | else |
| 117 | { |
| 118 | if (a == 2) |
| 119 | e ^= (q & (b >> 1)) ^ (q >> 1); |
| 120 | b = (b - q * a) & 3; |
| 121 | } |
| 122 | |
| 123 | printf("%2d,", (encode (a, b, d) << 1) | e); |
| 124 | } |
| 125 | printf("\n"); |
| 126 | |
| 127 | return 0; |
| 128 | } |