Custom crossover with structure-aware recombination */
| 100 | |
| 101 | /* Custom crossover with structure-aware recombination */ |
| 102 | size_t LLVMFuzzerCustomCrossOver(const u8 *in1, size_t in1_size, const u8 *in2, size_t in2_size, |
| 103 | u8 *out, size_t max_out_size, unsigned seed) |
| 104 | { |
| 105 | srand(seed); |
| 106 | char *str1 = to_string(tmpctx, in1, in1_size); |
| 107 | char *str2 = to_string(tmpctx, in2, in2_size); |
| 108 | char *fail; |
| 109 | |
| 110 | /* Decode both inputs */ |
| 111 | struct codex32 *p1 = codex32_decode(tmpctx, NULL, str1, &fail); |
| 112 | struct codex32 *p2 = codex32_decode(tmpctx, NULL, str2, &fail); |
| 113 | |
| 114 | /* If both valid, try structure-aware crossover */ |
| 115 | if (p1 && p2) { |
| 116 | /* Create child by combining parts */ |
| 117 | struct codex32 *child = codex32_dup(tmpctx, p1); |
| 118 | |
| 119 | /* Choose crossover method */ |
| 120 | switch(rand() % 3) { |
| 121 | case 0: /* Crossover threshold */ |
| 122 | child->threshold = p2->threshold; |
| 123 | break; |
| 124 | |
| 125 | case 1: /* Crossover ID */ |
| 126 | { |
| 127 | size_t id_len = sizeof(p1->id) - 1; |
| 128 | cross_over((const u8 *)p1->id, id_len, (const u8 *)p2->id, id_len, |
| 129 | (u8 *)child->id, id_len, rand()); |
| 130 | child->id[id_len] = '\0'; |
| 131 | } |
| 132 | break; |
| 133 | |
| 134 | case 2: /* Crossover payload */ |
| 135 | { |
| 136 | size_t p1_len = tal_bytelen(p1->payload); |
| 137 | size_t p2_len = tal_bytelen(p2->payload); |
| 138 | tal_resize(&child->payload, max_out_size); |
| 139 | size_t new_payload_len = cross_over(p1->payload, p1_len, |
| 140 | p2->payload, p2_len, |
| 141 | (u8 *)child->payload, max_out_size, rand()); |
| 142 | tal_resize(&child->payload, new_payload_len); |
| 143 | } |
| 144 | break; |
| 145 | } |
| 146 | |
| 147 | /* Always crossover the HRP to ensure it's valid for encoding. */ |
| 148 | char *new_hrp = tal_arr(child, char, 3); |
| 149 | new_hrp[0] = valid_hrp_chars[rand() % strlen(valid_hrp_chars)]; |
| 150 | new_hrp[1] = valid_hrp_chars[rand() % strlen(valid_hrp_chars)]; |
| 151 | new_hrp[2] = '\0'; |
| 152 | child->hrp = new_hrp; |
| 153 | |
| 154 | char *reencoded; |
| 155 | const char *err = codex32_secret_encode(tmpctx, child->hrp, child->id, |
| 156 | child->threshold, child->payload, |
| 157 | tal_bytelen(child->payload), &reencoded); |
| 158 | if (!err) { |
| 159 | size_t len = strlen(reencoded); |
nothing calls this directly
no test coverage detected