/* Author: Pate Williams (c) 1997 Exercise "6.10 Suppose Bob is using the Chaum-van Antwerpen Undenible Signature Scheme as in Example 6.5. That is, p = 467, alpha = 4, a = 101 and beta = 449. Suppose Bob is presented with the signature y = 25 on the message x = 157 and he wishes to prove it is a forgery. Suppose Alice's random numbers are e1 = 46, e2 = 123, f1 = 198, and f2 = 11 in the disavowel protocol. Compute Alice's challenges, c and d, and Bob responses, C and D, and show that Alice's consistency check will succeed." -Douglas R. Stinson- See "Cryptography: Theory and Practice" by Douglas R. Stinson page 232. */ #include long exp_mod(long x, long b, long n) /* returns x ^ b mod n */ { long a = 1l, s = x; while (b != 0) { if (b & 1l) a = (a * s) % n; b >>= 1; if (b != 0) s = (s * s) % n; } if (a < 0) a += n; return a; } long Extended_Euclidean(long b, long n) { long b0 = b, n0 = n, t = 1, t0 = 0, temp, q, r; q = n0 / b0; r = n0 - q * b0; while (r > 0) { temp = t0 - q * t; if (temp >= 0) temp = temp % n; else temp = n - (- temp % n); t0 = t; t = temp; n0 = b0; b0 = r; q = n0 / b0; r = n0 - q * b0; } if (b0 != 1) return 0; else return t % n; } int main(void) { long a = 101, alpha = 4, beta = 449, e1 = 46; long e2 = 123, f1 = 198, f2 = 11, i, j, p = 467; long q, x = 157, y = 25, c, d, C, D, r, s, t; q = (p - 1) >> 1; printf("a = %ld\n", a); printf("alpha = %ld\n", alpha); printf("beta = %ld\n", beta); printf("e1 = %ld\n", e1); printf("e2 = %ld\n", e2); printf("f1 = %ld\n", f1); printf("f2 = %ld\n", f2); printf("p = %ld\n", p); printf("q = %ld\n", q); printf("x = %ld\n", x); printf("y = %ld\n", y); i = Extended_Euclidean(a, q); c = (exp_mod(y, e1, p) * exp_mod(beta, e2, p)) % p; d = exp_mod(c, i, p); printf("Alice's challenge c = %ld\n", c); printf("Bob's response d = %ld\n", d); if (d != (exp_mod(x, e1, p) * exp_mod(alpha, e2, p)) % p) printf("d != x ^ e1 * alpha ^ e2 mod p\n"); else printf("d == x ^ e1 * alpha ^ e2 mod p\n"); C = (exp_mod(y, f1, p) * exp_mod(beta, f2, p)) % p; D = exp_mod(C, i, p); printf("Alice's challenge C = %ld\n", C); printf("Bob's response D = %ld\n", D); if (D != (exp_mod(x, f1, p) * exp_mod(alpha, f2, p)) % p) printf("D != x ^ f1 * alpha ^ f2 mod p\n"); else printf("D == x ^ f1 * alpha ^ f2 mod p\n"); i = q - e2; if (i < 0) i += q; j = q - f2; if (j < 0) j += q; r = (d * exp_mod(alpha, i, p)) % p; s = exp_mod(r, f1, p); r = (D * exp_mod(alpha, j, p)) % p; t = exp_mod(r, e1, p); if (s == t) printf("Alice concludes y is a forgery\n"); else printf("Alice does not conclude y is a forgery\n"); return 0; }