1 
2 #include <stddef.h>
3 #include <stdint.h>
4 
5 #include "crypto_verify_16.h"
6 #include "crypto_verify_32.h"
7 #include "crypto_verify_64.h"
8 
9 size_t
10 crypto_verify_16_bytes(void)
11 {
12     return crypto_verify_16_BYTES;
13 }
14 
15 size_t
16 crypto_verify_32_bytes(void)
17 {
18     return crypto_verify_32_BYTES;
19 }
20 
21 size_t
22 crypto_verify_64_bytes(void)
23 {
24     return crypto_verify_64_BYTES;
25 }
26 
27 #if defined(HAVE_EMMINTRIN_H) && defined(__SSE2__)
28 
29 # ifdef __GNUC__
30 #  pragma GCC target("sse2")
31 # endif
32 # include <emmintrin.h>
33 
34 static inline int
35 crypto_verify_n(const unsigned char *x_, const unsigned char *y_,
36                 const int n)
37 {
38     const    __m128i zero = _mm_setzero_si128();
39     volatile __m128i v1, v2, z;
40     volatile int     m;
41     int              i;
42 
43     const volatile __m128i *volatile x =
44         (const volatile __m128i *volatile) (const void *) x_;
45     const volatile __m128i *volatile y =
46         (const volatile __m128i *volatile) (const void *) y_;
47     v1 = _mm_loadu_si128((const __m128i *) &x[0]);
48     v2 = _mm_loadu_si128((const __m128i *) &y[0]);
49     z = _mm_xor_si128(v1, v2);
50     for (i = 1; i < n / 16; i++) {
51         v1 = _mm_loadu_si128((const __m128i *) &x[i]);
52         v2 = _mm_loadu_si128((const __m128i *) &y[i]);
53         z = _mm_or_si128(z, _mm_xor_si128(v1, v2));
54     }
55     m = _mm_movemask_epi8(_mm_cmpeq_epi32(z, zero));
56     v1 = zero; v2 = zero; z = zero;
57 
58     return (int) (((uint32_t) m + 1U) >> 16) - 1;
59 }
60 
61 #else
62 
63 static inline int
64 crypto_verify_n(const unsigned char *x_, const unsigned char *y_,
65                 const int n)
66 {
67     const volatile unsigned char *volatile x =
68         (const volatile unsigned char *volatile) x_;
69     const volatile unsigned char *volatile y =
70         (const volatile unsigned char *volatile) y_;
71     volatile uint_fast16_t d = 0U;
72     int i;
73 
74     for (i = 0; i < n; i++) {
75         d |= x[i] ^ y[i];
76     }
77     return (1 & ((d - 1) >> 8)) - 1;
78 }
79 
80 #endif
81 
82 int
83 crypto_verify_16(const unsigned char *x, const unsigned char *y)
84 {
85     return crypto_verify_n(x, y, crypto_verify_16_BYTES);
86 }
87 
88 int
89 crypto_verify_32(const unsigned char *x, const unsigned char *y)
90 {
91     return crypto_verify_n(x, y, crypto_verify_32_BYTES);
92 }
93 
94 int
95 crypto_verify_64(const unsigned char *x, const unsigned char *y)
96 {
97     return crypto_verify_n(x, y, crypto_verify_64_BYTES);
98 }
99