Created
June 27, 2022 04:30
-
-
Save guidovranken/b1c46bd9e42e959519009681b261a896 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <stdint.h> | |
| #include <assert.h> | |
| #include <stdlib.h> | |
| #include <stdio.h> | |
| #include <string.h> | |
| #include <openssl/bn.h> | |
| #if 1 /* Taken from OpenSSL */ | |
| #define BN_MASK2 (0xffffffffffffffffLL) | |
| BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, | |
| int n) | |
| { | |
| BN_ULONG t1, t2; | |
| int c = 0; | |
| assert(n >= 0); | |
| if (n <= 0) | |
| return (BN_ULONG)0; | |
| #ifndef OPENSSL_SMALL_FOOTPRINT | |
| while (n & ~3) { | |
| t1 = a[0]; | |
| t2 = b[0]; | |
| r[0] = (t1 - t2 - c) & BN_MASK2; | |
| if (t1 != t2) | |
| c = (t1 < t2); | |
| t1 = a[1]; | |
| t2 = b[1]; | |
| r[1] = (t1 - t2 - c) & BN_MASK2; | |
| if (t1 != t2) | |
| c = (t1 < t2); | |
| t1 = a[2]; | |
| t2 = b[2]; | |
| r[2] = (t1 - t2 - c) & BN_MASK2; | |
| if (t1 != t2) | |
| c = (t1 < t2); | |
| t1 = a[3]; | |
| t2 = b[3]; | |
| r[3] = (t1 - t2 - c) & BN_MASK2; | |
| if (t1 != t2) | |
| c = (t1 < t2); | |
| a += 4; | |
| b += 4; | |
| r += 4; | |
| n -= 4; | |
| } | |
| #endif | |
| while (n) { | |
| t1 = a[0]; | |
| t2 = b[0]; | |
| r[0] = (t1 - t2 - c) & BN_MASK2; | |
| if (t1 != t2) | |
| c = (t1 < t2); | |
| a++; | |
| b++; | |
| r++; | |
| n--; | |
| } | |
| return c; | |
| } | |
| /* Convenience method for uint64_t. */ | |
| static uint64_t value_barrier_64(uint64_t a) | |
| { | |
| volatile uint64_t r = a; | |
| return r; | |
| } | |
| static uint64_t constant_time_select_64(uint64_t mask, uint64_t a, | |
| uint64_t b) | |
| { | |
| return (value_barrier_64(mask) & a) | (value_barrier_64(~mask) & b); | |
| } | |
| static void bn_select_words(BN_ULONG *r, BN_ULONG mask, | |
| const BN_ULONG *a, | |
| const BN_ULONG *b, size_t num) | |
| { | |
| size_t i; | |
| for (i = 0; i < num; i++) { | |
| r[i] = constant_time_select_64(mask, a[i], b[i]); | |
| } | |
| } | |
| static BN_ULONG bn_reduce_once_in_place(BN_ULONG *r, | |
| BN_ULONG carry, | |
| const BN_ULONG *m, | |
| BN_ULONG *tmp, size_t num) | |
| { | |
| carry -= bn_sub_words(tmp, r, m, num); | |
| bn_select_words(r, carry, r /* tmp < 0 */, tmp /* tmp >= 0 */, num); | |
| return carry; | |
| } | |
| #endif | |
| #define TOTAL_SIZE 1024 | |
| int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { | |
| if ( size < TOTAL_SIZE * 8 * 4 ) { | |
| return 0; | |
| } | |
| BN_ULONG storage[TOTAL_SIZE]; | |
| BN_ULONG res1[TOTAL_SIZE]; | |
| BN_ULONG m1[TOTAL_SIZE]; | |
| BN_ULONG res2[TOTAL_SIZE]; | |
| BN_ULONG m2[TOTAL_SIZE]; | |
| BN_ULONG res1_before[TOTAL_SIZE]; | |
| BN_ULONG res2_before[TOTAL_SIZE]; | |
| memcpy(&res1[0], data + (TOTAL_SIZE * 0), TOTAL_SIZE * 8); | |
| memcpy(&m1[0], data + (TOTAL_SIZE * 1), TOTAL_SIZE * 8); | |
| memcpy(&res2[0], data + (TOTAL_SIZE * 2), TOTAL_SIZE * 8); | |
| memcpy(&m2[0], data + (TOTAL_SIZE * 3), TOTAL_SIZE * 8); | |
| const int res1_gte = res1[TOTAL_SIZE-1] >= m1[TOTAL_SIZE-1]; | |
| const int res2_gte = res2[TOTAL_SIZE-1] >= m2[TOTAL_SIZE-1]; | |
| memcpy(res1_before, res1, sizeof(res1)); | |
| memcpy(res2_before, res2, sizeof(res2)); | |
| bn_reduce_once_in_place(res1, /*carry=*/0, m1, storage, TOTAL_SIZE); | |
| bn_reduce_once_in_place(res2, /*carry=*/0, m2, storage, TOTAL_SIZE); | |
| if ( !res1_gte ) { | |
| assert(memcmp(res1, res1_before, sizeof(res1)) == 0); | |
| } | |
| if ( !res2_gte ) { | |
| assert(memcmp(res2, res2_before, sizeof(res2)) == 0); | |
| } | |
| for (size_t i = 0; i < TOTAL_SIZE; i++) { | |
| assert( | |
| storage[i] == ~(m2[i] - res2_before[i]) || | |
| storage[i] == ~(m2[i] - res2_before[i]) + 1 | |
| ); | |
| assert( | |
| res1[i] == res1_before[i] || | |
| res1[i] == res1_before[i] - m1[i] || | |
| res1[i] == res1_before[i] - m1[i] - 1 | |
| ); | |
| assert( | |
| res2[i] == res2_before[i] || | |
| res2[i] == res2_before[i] - m2[i] || | |
| res2[i] == res2_before[i] - m2[i] - 1 | |
| ); | |
| } | |
| return 0; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment