Last active
July 16, 2022 17:12
-
-
Save maple3142/acf736f336cb303cdf47a3ef18f543dc to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Reference impl: https://github.com/p4-team/crypto-commons/blob/a67b13bb2ed2612d8f41637d4c68223968b0fef0/crypto_commons/rsa/rsa_commons.py#L212 | |
| from collections.abc import Iterable | |
| def inv(a, p): | |
| # wrapping it in int for safely using it in sage | |
| return int(pow(a, -1, p)) | |
| def single_lift(f, df, p, k, rs): | |
| # f(r) = 0 (mod p^k) | |
| # df(r) != 0 (mod p^k) | |
| # returns s such that f(s) = 0 (mod p^(k+1)) | |
| pk = p ** k | |
| pk1 = pk * p | |
| for r in rs: | |
| assert f(r) % pk == 0, (r, k) | |
| # assert df(r) % (p ** k) != 0, (r,k) | |
| if df(r) % p != 0: | |
| a = inv(df(r), p) | |
| s = r - f(r) * a | |
| assert f(s) % pk1 == 0 | |
| yield s | |
| else: | |
| for t in range(0, p): | |
| s = r + t * pk | |
| if f(s) % pk1 == 0: | |
| yield s | |
| def hensel_lift(f, df, p, k, m, rs): | |
| # f(r) = 0 (mod p^k) | |
| # df(r) != 0 (mod p^k) | |
| # returns s such that f(s) = 0 (mod p^m) | |
| if not isinstance(rs, Iterable): | |
| rs = [rs] | |
| assert m >= k | |
| if m == k: | |
| return rs | |
| return hensel_lift(f, df, p, k + 1, m, single_lift(f, df, p, k, rs)) | |
| p = 5 | |
| f = lambda x: x ** 3 - 3 | |
| df = lambda x: 3 * x ** 2 | |
| r = 2 | |
| print(f(r) % p) | |
| r2 = next(single_lift(f, df, p, 1, [r])) | |
| print(r2, f(r2) % (p ** 2)) | |
| r3 = next(single_lift(f, df, p, 2, [r2])) | |
| print(r3, f(r3) % (p ** 3)) | |
| for r7 in hensel_lift(f, df, p, 1, 7, r): | |
| print("r7", r7, f(r7) % (p ** 7)) | |
| a = 1 | |
| b = 73510584564539971804390271186346944020501066603283681904361110056435924213176 | |
| c = 49216479095814386015565420646552416129143124367675256987703613481241139546863 | |
| p = 2 | |
| f = lambda x: a * x * x + b * x + c | |
| df = lambda x: 2 * a * x + b | |
| for x in hensel_lift(f, df, p, 1, 256, 1): | |
| print(x, f(x) % (p ** 256)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment