File Coverage

src/int/i31_reduce.c
Criterion Covered Total %
statement 12 17 70.5
branch 4 8 50.0
condition n/a
subroutine n/a
pod n/a
total 16 25 64.0


line stmt bran cond sub pod time code
1             /*
2             * Copyright (c) 2016 Thomas Pornin
3             *
4             * Permission is hereby granted, free of charge, to any person obtaining
5             * a copy of this software and associated documentation files (the
6             * "Software"), to deal in the Software without restriction, including
7             * without limitation the rights to use, copy, modify, merge, publish,
8             * distribute, sublicense, and/or sell copies of the Software, and to
9             * permit persons to whom the Software is furnished to do so, subject to
10             * the following conditions:
11             *
12             * The above copyright notice and this permission notice shall be
13             * included in all copies or substantial portions of the Software.
14             *
15             * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16             * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17             * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18             * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19             * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20             * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21             * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22             * SOFTWARE.
23             */
24              
25             #include "inner.h"
26              
27             /* see inner.h */
28             void
29 3           br_i31_reduce(uint32_t *x, const uint32_t *a, const uint32_t *m)
30             {
31             uint32_t m_bitlen, a_bitlen;
32             size_t mlen, alen, u;
33              
34 3           m_bitlen = m[0];
35 3           mlen = (m_bitlen + 31) >> 5;
36              
37 3           x[0] = m_bitlen;
38 3 50         if (m_bitlen == 0) {
39 0           return;
40             }
41              
42             /*
43             * If the source is shorter, then simply copy all words from a[]
44             * and zero out the upper words.
45             */
46 3           a_bitlen = a[0];
47 3           alen = (a_bitlen + 31) >> 5;
48 3 50         if (a_bitlen < m_bitlen) {
49 0           memcpy(x + 1, a + 1, alen * sizeof *a);
50 0 0         for (u = alen; u < mlen; u ++) {
51 0           x[u + 1] = 0;
52             }
53 0           return;
54             }
55              
56             /*
57             * The source length is at least equal to that of the modulus.
58             * We must thus copy N-1 words, and input the remaining words
59             * one by one.
60             */
61 3           memcpy(x + 1, a + 2 + (alen - mlen), (mlen - 1) * sizeof *a);
62 3           x[mlen] = 0;
63 6 100         for (u = 1 + alen - mlen; u > 0; u --) {
64 3           br_i31_muladd_small(x, a[u], m);
65             }
66             }