Zulip Chat Archive
Stream: maths
Topic: large numbers computations
Jakob von Raumer (Oct 17 2022 at 12:54):
Are there tactics to deal with goals like 10 ^ 18 < 3618502788666131213697322783095070105623107215331596699973092056135872020483
?
Riccardo Brasca (Oct 17 2022 at 12:57):
norm_num
is quite fast for me on this precise example
Jakob von Raumer (Oct 17 2022 at 13:08):
Thanks!
Jakob von Raumer (Oct 17 2022 at 13:08):
Do we have a fast prime checker as well?
Riccardo Brasca (Oct 17 2022 at 13:15):
This is really non trivial, right? I mean, even Pari/GP, or similar software, is very fast because it checks psudoprimality
Jireh Loreaux (Oct 17 2022 at 13:17):
We'll, no one ever really implements AKS, but PRIMES is in P.
Riccardo Brasca (Oct 17 2022 at 13:20):
Sure, but AFAIK AKS is totally useless in practice. I think that in practice if one as primality certificate (given by Pari or whatever) it shouldn't be too hard to formalize primality in Lean. But of course asking Lean to find the certificate is different.
Jakob von Raumer (Oct 17 2022 at 13:23):
Sure would be good to have a decision procedure that's at least faster than just brute force
Riccardo Brasca (Oct 17 2022 at 13:26):
norm_num
also knows about primes, so you can use it, but it is not very fast.
Riccardo Brasca (Oct 17 2022 at 13:29):
On the other hand we have a good implementation of the Jacobi symbol, so checking for example if 2
, 3
and 5
(say) are witness of nonprimality should be fast. And this is already a good pseudoprimality test.
Riccardo Brasca (Oct 17 2022 at 13:33):
Especially if one implements Miller-Rabin rather than Solovay–Strassen. According to Wikipedia, 2
, 3
and 5
are enough up to 25326001
.
Eric Rodriguez (Oct 17 2022 at 13:44):
Riccardo Brasca said:
Especially if one implements Miller-Rabin rather than Solovay–Strassen. According to Wikipedia,
2
,3
and5
are enough up to25326001
.
sure, but then we have to prove that it's enough :)
Eric Rodriguez (Oct 17 2022 at 13:44):
we do have lucas lehmer if you want a mersenne prime though!
Riccardo Brasca (Oct 17 2022 at 13:50):
Yes, I was talking about psuedoprimality. If we want primality I am more or less sure the best we can do is prove that something like a Pratt certificate implies primality (this is surely almost already in mathlib) and then use something else to find the witness.
Riccardo Brasca (Oct 17 2022 at 13:51):
Like what polyrith
does
Eric Rodriguez (Oct 17 2022 at 13:53):
ah, that's a good idea. indeed we do have docs#lucas_primality; in Lean4 I imagine this can be done quite fast
Eric Rodriguez (Oct 17 2022 at 13:53):
maybe with some cached tactics too
Jakob von Raumer (Oct 18 2022 at 12:19):
ECPP prime certificates would be an alternative. Might be a fun project to see what mathematics about elliptic curves is missing to implement a checker
Jakob von Raumer (Oct 19 2022 at 08:13):
Hasse's theorem seems to be the main result it relies on
Kevin Buzzard (Oct 19 2022 at 09:26):
We can't even prove the points form a group. There is a low-level proof of Hasse's theorem due to Manin I think, but only valid in characteristic >= 5 IIRC
Jakob von Raumer (Oct 19 2022 at 12:54):
Well characteristic >= 5 would be enough for the primality check, but it's probably better to go a high-level way and build a good library of elliptic curves first
Bhavik Mehta (Oct 19 2022 at 14:16):
I tried writing a verifier using norm_num and Pratt certificates, the summary was essentially that it works but doesn't seem to be much better than what norm_num already does - in particular it gets a bit further before timing out but not significantly so
Riccardo Brasca (Oct 19 2022 at 14:18):
Even using Pratt certificates recursively? I mean, to prove that all the factors are prime.
Bolton Bailey (Oct 19 2022 at 20:55):
@Bhavik Mehta does it at least work for primes like 15 * 2^27 + 1
? It would be convenient for a project I'm working on to verify this prime in particular.
Bhavik Mehta (Oct 19 2022 at 22:14):
Riccardo Brasca said:
Even using Pratt certificates recursively? I mean, to prove that all the factors are prime.
Yes!
Bhavik Mehta (Oct 19 2022 at 22:15):
Bolton Bailey said:
Bhavik Mehta does it at least work for primes like
15 * 2^27 + 1
? It would be convenient for a project I'm working on to verify this prime in particular.
I will check
Bolton Bailey (Oct 19 2022 at 22:54):
Another comment on primality testing, obviously there are several different approaches - brute force calculation, Pratt certificates, AKS, and all of these are going to have different performance on different number sizes (this is yet another thing that was first pointed out to me by @Mario Carneiro ). It would be cool if we could eventually have a primality tester that selectively applies different tests based on the size of the number being proven, in the same way that big-integer multiplication libraries use different algorithms on different sizes of integers.
Jakob von Raumer (Oct 20 2022 at 09:17):
@Bhavik Mehta I don't really get why it should be that slow? Because the modulo calculations are?
Bhavik Mehta (Oct 20 2022 at 10:02):
One factor to bear in mind is that in computation, Pratt certificates are an improvement because you replace many divisions in the trial division algorithm with multiplication and powmod operations. But when verifying, the cost of a natural division is practically the same as a multiplication, since a proof of division amounts to an inequality proof, addition proof and multiplication proof. So the usual benefit from Pratt certificates is lessened greatly
Riccardo Brasca (Oct 20 2022 at 12:47):
Bolton Bailey said:
Bhavik Mehta does it at least work for primes like
15 * 2^27 + 1
? It would be convenient for a project I'm working on to verify this prime in particular.
This number is not that big. It would be sad if we're not able to prove it's prime...
Riccardo Brasca (Oct 20 2022 at 12:57):
If you really want this specific number I don't see any problem. I just tested and norm_num
is able to compute 31^15
, then one only have to take squares (I hope not by hand...). The prime factors of p-1
are super small so exploiting the condition nat.prime q → q ∣ p - 1
is probably easy (one may need a general result here, unrelated to this number).
Riccardo Brasca (Oct 20 2022 at 13:00):
I think it's more helpful to prove docs#lucas_primality using docs#nat.factorization
Alex J. Best (Oct 20 2022 at 13:40):
Is https://en.wikipedia.org/wiki/Proth%27s_theorem the general result you are thinking of?
Riccardo Brasca (Oct 20 2022 at 13:41):
Ah, this is even better, but I was just thinking that if 3*5*2^27 = n
then we know all prime factors of n
.
Bolton Bailey (Oct 20 2022 at 18:10):
Unfortunately, norm_num
times out on the goal 2 ^ (2 ^ 27 * 15) = 1
in zmod (2 ^ 27 * 15 + 1)
. I think the issue is that exponentiation was not performant. Mario gave us a definition to get around this when we were working on Miller-Rabin (unfortunately that branch has been left hanging for a while, I don't have time to finish it up)
def binpow {M} [has_one M] [has_mul M] (m : M) : ℕ → M :=
nat.binary_rec 1 (λ b _ ih, let ih2 := ih * ih in cond b (m * ih2) ih2)
Riccardo Brasca (Oct 20 2022 at 18:17):
I think you can do it using pow_mul
, helping Lean a little bit.
Riccardo Brasca (Oct 20 2022 at 18:17):
This is of course not the right way of doing it, but a least it should work in this precise case.
Bhavik Mehta (Oct 20 2022 at 20:15):
Bolton Bailey said:
Unfortunately,
norm_num
times out on the goal2 ^ (2 ^ 27 * 15) = 1
inzmod (2 ^ 27 * 15 + 1)
. I think the issue is that exponentiation was not performant. Mario gave us a definition to get around this when we were working on Miller-Rabin (unfortunately that branch has been left hanging for a while, I don't have time to finish it up)def binpow {M} [has_one M] [has_mul M] (m : M) : ℕ → M := nat.binary_rec 1 (λ b _ ih, let ih2 := ih * ih in cond b (m * ih2) ih2)
Yes, the first thing I did when trying to verify using Pratt certificates was convince norm_num to do efficient modular exponentiation
Bhavik Mehta (Oct 20 2022 at 20:44):
@Bolton Bailey update: I can prove that number is prime, and it's relatively fast - around 5 seconds
Bolton Bailey (Oct 20 2022 at 20:45):
Hehe, sweet!
Bolton Bailey (Oct 20 2022 at 20:46):
Is the proof fully automatic, or do you need to hand-solve some goals?
Bhavik Mehta (Oct 20 2022 at 20:46):
bad news is that the original setup I had to do primes in general was pretty dodgy - I adapted it from https://www.isa-afp.org/browser_info/current/AFP/Pratt_Certificate/outline.pdf, namely rules 1 and 2 from page 2, and it seems to be really inefficient in the case of a prime factor appearing multiple times (unsure if this is from the isabelle version or my translation of it)
Bhavik Mehta (Oct 20 2022 at 20:47):
The proof is:
lemma second_bit {x} : x ∈ nat.factors (15 * 2^27 + 1 - 1) ↔ x = 2 ∨ x = 3 ∨ x = 5 :=
begin
norm_num,
end
lemma boltons_prime : prime (15 * 2^27 + 1) :=
begin
refine pratt_rule_2' 31 (by norm_num) (by norm_num) _,
simp only [pratt_predicate, second_bit, forall_eq_or_imp, forall_eq],
change my_pow_mod _ _ _ ≠ 1 ∧ my_pow_mod _ _ _ ≠ 1 ∧ my_pow_mod _ _ _ ≠ 1,
norm_num,
end
with about 100 lines of other stuff before it which I'd written a few months ago
Bhavik Mehta (Oct 20 2022 at 20:48):
what I have right now definitely isn't correctly designed to be usable, which is why I haven't tried to PR it anywhere!
Bolton Bailey (Oct 20 2022 at 20:51):
Still, very cool to have primality proofs for cryptographically important primes.
Bhavik Mehta (Oct 20 2022 at 20:54):
Thought about it a bit more, and the problem with what I had originally is precisely in the case where a prime factor q of p-1 has high multiplicity - the isabelle pratt certificate (and hence mine) do k powmod calculations if q^k | p-1, but it should be enough to only do 1 for each prime
Bhavik Mehta (Oct 20 2022 at 20:54):
(So my original attempt for your prime timed out, but the modified version above is shorter and doesn't time out!)
Bhavik Mehta (Oct 20 2022 at 20:57):
Here are the (average of 1) benchmarks for the four primes I've tested: 199999 takes 2s, 2013265921 (Bolton's prime) takes 3s, 1000000007 takes 5s (despite being smaller than Bolton's prime - maybe because this has the multiplicity problem) and 23509285402367 times out very early
Bolton Bailey (Oct 20 2022 at 20:58):
The "Goldilocks prime" 2^64 -2^32 + 1
is another prime people often use for the convenient hardware properties, which is one more than 18446744069414584320 = 2^32×3×5×17×257×65537
. I imagine your approach be able to prove this relatively quickly as well?
Mario Carneiro (Oct 20 2022 at 21:02):
Do those numbers include finding the certificate?
Bhavik Mehta (Oct 20 2022 at 21:03):
Mario Carneiro said:
Do those numbers include finding the certificate?
No, I found the primitive root 31
here by using wolfram alpha, and the pratt_rule_2' 31
is where I input it
Mario Carneiro (Oct 20 2022 at 21:04):
so the calculation is just a powmod?
Bhavik Mehta (Oct 20 2022 at 21:05):
It's a number of powmods, but yeah - really there's not much more than the powmod implementation I showed you in messages a while back
Mario Carneiro (Oct 20 2022 at 21:05):
are the auxiliary computations all inexpensive?
Mario Carneiro (Oct 20 2022 at 21:06):
e.g. 31
is prime, those _
arguments (which are presumably divisions of the target number by powers of the factors or something)
Bhavik Mehta (Oct 20 2022 at 21:07):
I think so, but I haven't benchmarked - all the norm_num calls which aren't pow_mod are natural division (of a very large number by a very small prime factor), natural subtraction, and a natural non zero proof (or some combination)
Mario Carneiro (Oct 20 2022 at 21:07):
try splitting the powmods into their own lemmas
Bhavik Mehta (Oct 20 2022 at 21:09):
Sorry one second - I just realised I was using a worse powmod implementation one than what I actually did, let me check properly with the better version. It seems that 18446744069414584321
is too big
Bhavik Mehta (Oct 20 2022 at 21:23):
image.png Here's the breakdown for the goldilocks prime
Bhavik Mehta (Oct 20 2022 at 21:24):
In each case the 'tactic execution took' is very close to 80% of the elaboration time showed, so I only showed that
Bhavik Mehta (Oct 20 2022 at 21:26):
thing0
is where any benefit of 'recursive' certificates might give an improvement, but all the factors here are small so I didn't bother optimising that
Bhavik Mehta (Oct 20 2022 at 21:26):
Oh, changing thing2 to use 18446744069414584320
rather than 18446744069414584321 - 1
seems to speed it up by 2x... that's not what I expected!
Bhavik Mehta (Oct 20 2022 at 21:35):
Here's my scratch file: https://github.com/leanprover-community/mathlib/blob/pow_mod/src/pow_mod.lean
Jakob von Raumer (Oct 22 2022 at 11:35):
That's great, I'll try that on 0x800000000000011000000000000000000000000000000000000000000000001
Bhavik Mehta (Oct 22 2022 at 17:30):
Instead of proving the thing about nat.factors
by norm_num
like I did, for that prime you're probably better off showing that the particular list of factors does multiply to p-1, and that each element is a prime, because I guess norm_num might be too slow to verify the larger prime factors of p-1
Bolton Bailey (Oct 23 2022 at 22:55):
Riccardo Brasca said:
I think it's more helpful to prove docs#lucas_primality using docs#nat.factorization
I guess you mean it would be better if the condition docs#lucas_primality were stated as ∀ q ∈ p.factors, ...
, I agree this would look a bit better, and I wouldn't object to someone changing it (although I think docs#factors should probably be named prime_factors
).
Bhavik Mehta (Oct 24 2022 at 16:47):
Why not both? (also ∀ q ∈ (p - 1).factors
)
Riccardo Brasca (Oct 24 2022 at 19:04):
I just mean a formulation such that it's easy to list, in Lean, all the cases.
Bhavik Mehta (Nov 10 2022 at 04:09):
With quite a bit of effort and broken up lemmas, I proved 47867742232066880047611079
is prime. This prime is interesting because it can't be written as the sum or difference of prime powers (from a 1999 result of Sun), and I verified it's not the sum or difference of a power of two and a prime (a 1975 result)
Bhavik Mehta (Nov 10 2022 at 04:11):
Perhaps also worth noting that p-1 here also has a large prime factor q = 90101681149415123
, and q-1 also has a large prime factor 1123145497
, and bare norm_num
can't do this one either, so the certificate starts there
Riccardo Brasca (Nov 10 2022 at 06:31):
Nice work ! Is it somewhere?
Kevin Buzzard (Nov 10 2022 at 07:30):
That's a very philosophical question!
Riccardo Brasca (Nov 10 2022 at 08:02):
I mean, on some repository :sweat_smile:
Bhavik Mehta (Nov 10 2022 at 13:46):
Riccardo Brasca said:
Nice work ! Is it somewhere?
Not yet - if my primality verifying code from earlier is bad, this is atrocious :D
Last updated: Dec 20 2023 at 11:08 UTC