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
crypto_verify_16_bytes(void)10 crypto_verify_16_bytes(void)
11 {
12 return crypto_verify_16_BYTES;
13 }
14
15 size_t
crypto_verify_32_bytes(void)16 crypto_verify_32_bytes(void)
17 {
18 return crypto_verify_32_BYTES;
19 }
20
21 size_t
crypto_verify_64_bytes(void)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
crypto_verify_n(const unsigned char * x_,const unsigned char * y_,const int n)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
crypto_verify_n(const unsigned char * x_,const unsigned char * y_,const int n)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
crypto_verify_16(const unsigned char * x,const unsigned char * y)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
crypto_verify_32(const unsigned char * x,const unsigned char * y)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
crypto_verify_64(const unsigned char * x,const unsigned char * y)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