-
Notifications
You must be signed in to change notification settings - Fork 40
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
(WIP) Discrete logarithm #110
Conversation
This is a first implementation of a discreteLogarithm function. It uses a naive algorithm that is really slow on large moduli. In subsequent commits I will add a benchmark and use a more sophisticated algorithm.
Currently this takes 1.22 seconds on my laptop! Lots of room for improvement
Benchmark gives a result of 7ms, a speed-up of about 175 times!
This test currently fails and needs to be resolved.
@Taneb just a gentle reminder that you intended to resolve remaining issues. Or we can merge as is and restrict inputs of discrete logarithm to primitive roots only. |
Sorry, I've been busier than I expected! 😅 Going to do some work on this tonight, though |
I think we can introduce a newtype
and amend the signature of isPrimitiveRoot
:: KnownNat n => Mod n -> Maybe (PrimitiveRoot n) Consequently, discreteLogarithm :: (KnownNat m, Integral b) => Mod m -> PrimitiveRoot m -> Maybe b This eliminates the current issue with logarithms by non-primitive base (Pollard's algorithm supposes that the base is primitive) without compromising performance or correctness. |
Oooh, that's a good idea. I'll implement that this evening |
…' to use this. I'm not sure about the name for primitiveRootGetMod. Another thing I thought of is it might be nice to have a type for members of the multiplicative group modulo m, that is, the subset of Mod m coprime to m.
-- | 'PrimitiveRoot n' is a type which is only inhabited by primitive roots of | ||
-- n. | ||
newtype PrimitiveRoot n = PrimitiveRoot (Mod n) | ||
deriving (Eq, Ord, Show) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let us define newtype PrimitiveRoot n = PrimitiveRoot { unprimitiveRoot :: Mod n }
and export the type and the accessor, but not the constructor.
@Taneb any chance to finish it soon? |
Closing, superseded by #130. Anyway, thanks for you efforts. |
Sorry I neglected this issue! I'm glad it's been solved by someone, I had... less time and headspace for this than I'd have liked |
It was a pleasure to work with you at ZuriHac. |
This is the work I started at ZuriHac. It implements Pollard's rho algorithm to compute the discrete logarithm. This has the deficiency that there are some solutions it cannot find, such as 2^x == 7 (mod 9), which I would like to resolve before this PR gets merged.