/* Problem Forge, Problem of the Month, rungs 06 and 07: the rule. CC0 1.0 (public domain). Vertices i < j are joined when the first bit of SHA-256(K, i, j) is 1, with K as its 32 bytes and i, j as 8-byte big-endian numbers. Build: cc rule.c -lcrypto Use: ./a.out KEY i j (prints 1 if joined, else 0) */ #include #include #include #include int joined(const unsigned char key[32], uint64_t i, uint64_t j) { unsigned char msg[48], out[32]; if (i > j) { uint64_t t = i; i = j; j = t; } for (int b = 0; b < 32; b++) msg[b] = key[b]; for (int b = 0; b < 8; b++) { msg[32 + b] = (unsigned char)(i >> (56 - 8 * b)); msg[40 + b] = (unsigned char)(j >> (56 - 8 * b)); } SHA256(msg, sizeof msg, out); return out[0] >> 7; } int main(int argc, char **argv) { unsigned char key[32]; if (argc != 4) return 2; for (int b = 0; b < 32; b++) sscanf(argv[1] + 2 * b, "%2hhx", &key[b]); printf("%d\n", joined(key, strtoull(argv[2], 0, 10), strtoull(argv[3], 0, 10))); return 0; }