Searches for duplicates in an array of 'sha256_midstate's. * If malloc fails, returns -1. * If no duplicates are found, returns 0. * If duplicates are found, returns a positive value. * * Precondition: const sha256_midstate a[len]; * len <= DAG_LEN_MAX; */
| 263 | * len <= DAG_LEN_MAX; |
| 264 | */ |
| 265 | int simplicity_hasDuplicates(const sha256_midstate* a, uint_fast32_t len) { |
| 266 | if (len < 2) return 0; |
| 267 | static_assert(sizeof(a->s) * CHAR_BIT == 256, "sha256_midstate.s has unnamed padding."); |
| 268 | static_assert(DAG_LEN_MAX <= UINT32_MAX, "DAG_LEN_MAX does not fit in uint32_t."); |
| 269 | static_assert(DAG_LEN_MAX <= SIZE_MAX / sizeof(const sha256_midstate*), "perm array too large."); |
| 270 | simplicity_assert((size_t)len <= SIZE_MAX / sizeof(const sha256_midstate*)); |
| 271 | const sha256_midstate **perm = simplicity_malloc(len * sizeof(const sha256_midstate*)); |
| 272 | uint32_t *stack = simplicity_malloc(((CHAR_COUNT - 1)*(sizeof((*perm)->s)) + 1) * sizeof(uint32_t)); |
| 273 | int result = perm && stack ? 0 : -1; |
| 274 | |
| 275 | if (0 <= result) { |
| 276 | for (uint_fast32_t i = 0; i < len; ++i) { |
| 277 | perm[i] = a + i; |
| 278 | } |
| 279 | |
| 280 | const sha256_midstate *duplicate; |
| 281 | rsort_ex(perm, len, &duplicate, stack); |
| 282 | result = NULL != duplicate; |
| 283 | } |
| 284 | |
| 285 | simplicity_free(perm); |
| 286 | simplicity_free(stack); |
| 287 | return result; |
| 288 | } |