Exemple #1
0
int64 pow_mod(int64 x, int64 y, int64 mod) {
	int64 ret = 1, val = x;
	for (; y > 0; y >>= 1) {
		if ((y & 1) == 1)
			ret = multiply_mod(ret, val, mod);
		val = multiply_mod(val, val, mod);
	}
	return ret;
}
// Public library function. Returns NULL if successful, a string starting with "I/O error: "
// if an I/O error occurred (please see perror()), or a string if some other error occurred.
const char *modify_file_crc32(const char *path, uint64_t offset, uint32_t newcrc, bool printstatus) {
	FILE *f = fopen(path, "r+b");
	if (f == NULL)
		return "I/O error: fopen";
	
	// Read entire file and calculate original CRC-32 value.
	// Note: We can't use fseek(f, 0, SEEK_END) + ftell(f) to determine the length of the file, due to undefined behavior.
	// To be portable, we also avoid using POSIX fseeko()+ftello() or Windows GetFileSizeEx()/_filelength().
	uint64_t length;
	uint32_t crc = get_crc32_and_length(f, &length);
	if (offset > UINT64_MAX - 4 || offset + 4 > length) {
		fclose(f);
		return "Error: Byte offset plus 4 exceeds file length";
	}
	if (printstatus)
		fprintf(stdout, "Original CRC-32: %08" PRIX32 "\n", reverse_bits(crc));
	
	// Compute the change to make
	uint32_t delta = crc ^ newcrc;
	delta = (uint32_t)multiply_mod(reciprocal_mod(pow_mod(2, (length - offset) * 8)), delta);
	
	// Patch 4 bytes in the file
	fseek64(f, offset);
	for (int i = 0; i < 4; i++) {
		int b = fgetc(f);
		if (b == EOF) {
			fclose(f);
			return "I/O error: fgetc";
		}
		b ^= (int)((reverse_bits(delta) >> (i * 8)) & 0xFF);
		if (fseek(f, -1, SEEK_CUR) != 0) {
			fclose(f);
			return "I/O error: fseek";
		}
		if (fputc(b, f) == EOF) {
			fclose(f);
			return "I/O error: fputc";
		}
		if (fflush(f) == EOF) {
			fclose(f);
			return "I/O error: fflush";
		}
	}
	if (printstatus)
		fprintf(stdout, "Computed and wrote patch\n");
	
	// Recheck entire file
	bool match = get_crc32_and_length(f, &length) == newcrc;
	fclose(f);
	if (match) {
		if (printstatus)
			fprintf(stdout, "New CRC-32 successfully verified\n");
		return NULL;  // Success
	} else
		return "Assertion error: Failed to update CRC-32 to desired value";
}
Exemple #3
0
int64 pollard_rho(int64 n, int64 c) {
	int64 x = rand() % (n - 1) + 1, y = x;
	for (int head = 1, tail = 2; true; ) {
		x = multiply_mod(x, x, n);
		if ((x += c) >= n)
			x -= n;
		if (x == y)
			return n;
		int64 d = gcd(my_abs(x - y), n);
		if (d > 1 && d < n)
			return d;
		if ((++head) == tail) {
			y = x;
			tail <<= 1;
		}
	}
}