-
Notifications
You must be signed in to change notification settings - Fork 144
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
Support for large finite fields #851
Comments
Unfortunately, the synthesis time of the current code seems to be exponential in the number of limbs (for WBW Montgomery) or at least cubic (for unsaturated Solinas), for unclear reasons. Our 12-limb example takes around 8 minutes, and just a couple more limbs brings us up to an hour. 3072-bit primes on 64-bit machines would involve 48 limbs, which is much more than the code can handle at this point. There are two issues, here:
Super-linear time in positional->associational->positional: CodeRequire Import Coq.Lists.List Coq.ZArith.ZArith.
Require Import Crypto.ArithmeticCPS.Core.
Require Import Crypto.ArithmeticCPS.ModOps.
Import ListNotations.
Open Scope Z_scope.
Open Scope nat_scope.
Open Scope list_scope.
Module RT_ExtraAx := Core.RT_Extra Core.RuntimeAxioms.
Module ModOpsAx := ModOps.ModOps Core.RuntimeAxioms.
Module PositionalAx := ArithmeticCPS.Core.Positional Core.RuntimeAxioms.
Definition test (nlimbs : nat) (f : list Z) : list Z
:= let wt := weight 64 1 in
let p := PositionalAx.to_associational wt nlimbs (RT_ExtraAx.expand_list 0%Z f nlimbs) in
PositionalAx.from_associational_cps wt nlimbs p _ id.
Import RuntimeAxioms.
Ltac timetest n := idtac "n=" n; time (idtac; let x := (eval vm_compute in (test n)) in idtac).
Ltac timetest_up_to n :=
lazymatch n with
| O => idtac
| S ?n => timetest_up_to n
end;
timetest n.
Goal True. timetest_up_to 35. Abort. Table of timing as a function of limbs
Super-linear time in chained-carries: CodeRequire Import Coq.Lists.List Coq.ZArith.ZArith.
Require Import Crypto.ArithmeticCPS.Core.
Require Import Crypto.ArithmeticCPS.ModOps.
Require Crypto.UnsaturatedSolinasHeuristics.
Import ListNotations.
Open Scope Z_scope.
Open Scope nat_scope.
Open Scope list_scope.
Module RT_ExtraAx := Core.RT_Extra Core.RuntimeAxioms.
Module ModOpsAx := ModOps.ModOps Core.RuntimeAxioms.
Module PositionalAx := ArithmeticCPS.Core.Positional Core.RuntimeAxioms.
Definition test2 (nlimbs : nat) (f : list Z) : list Z
:= let wt := weight 64 1 in
let s := (2^(64 * Z.of_nat nlimbs - 1))%Z in
let c := [(1, 1)]%Z in
let idxs := UnsaturatedSolinasHeuristics.carry_chains nlimbs s c in
let p := PositionalAx.chained_carries_cps wt nlimbs s c (RT_ExtraAx.expand_list 0%Z f nlimbs) idxs _ id in
p.
Import RuntimeAxioms.
Ltac timetest2 n :=
idtac "n=" n;
restart_timer;
let x := (eval vm_compute in (test2 n)) in
finish_timing ("Tactic call vm_compute");
restart_timer;
let x := (eval vm_compute in x) in
finish_timing ("Tactic call noop-vm_compute").
Ltac timetest2_up_to n :=
lazymatch n with
| O => idtac
| S ?n => timetest2_up_to n
end;
timetest2 n.
Goal True. timetest2_up_to 15. Abort. Table of timing as a function of limbs
Super-linear time in WBW Montgomery multiplication: CodeRequire Import Coq.Lists.List Coq.ZArith.ZArith.
Require Import Crypto.ArithmeticCPS.Core.
Require Import Crypto.ArithmeticCPS.ModOps.
Require Import Crypto.ArithmeticCPS.WordByWordMontgomery.
Require Import Crypto.Util.ZUtil.ModInv.
Import ListNotations.
Open Scope Z_scope.
Open Scope nat_scope.
Open Scope list_scope.
Module Import RT_ExtraAx := Core.RT_Extra Core.RuntimeAxioms.
Module ModOpsAx := ModOps.ModOps Core.RuntimeAxioms.
Module PositionalAx := ArithmeticCPS.Core.Positional Core.RuntimeAxioms.
Module WordByWordMontgomeryAx := ArithmeticCPS.WordByWordMontgomery.WordByWordMontgomery Core.RuntimeAxioms.
Definition test3 (nlimbs : nat) (f g : list Z) : list Z
:= let wt := weight 64 1 in
let m := (2^(64 * Z.of_nat nlimbs - 1) - 1)%Z in
let m' := match Z.modinv (-m) (2^64) with
| Some m' => m'
| None => 0%Z
end in
WordByWordMontgomeryAx.mulmod 64 nlimbs m m' (expand_list 0%Z f nlimbs) (expand_list 0%Z g nlimbs).
Import RuntimeAxioms.
Ltac timetest3 n :=
idtac "n=" n;
restart_timer;
let x := (eval vm_compute in (test3 n)) in
finish_timing ("Tactic call vm_compute");
restart_timer;
let x := (eval vm_compute in x) in
finish_timing ("Tactic call noop-vm_compute").
Ltac timetest3_up_to n :=
lazymatch n with
| O => idtac
| S ?n => timetest3_up_to n
end;
timetest3 n.
Goal True. timetest3_up_to 9. Abort. Table of timing as a function of limbs
N.B. This code runs with commit 4c54bbb of our project. I expect it'll continue working for some time, but I'm leaving this commit hash here so it's easy to dig up a working version if we need to. |
I see. Thanks for the quick and detailed response. I think then it's obviously then it's currently not interesting for us but I'll watch the issue of course. Unfortunately I don't have the resources to help. |
As far as I understand, the focus of this project is ECC, even though other uses of finite field arithmetic are supported (Poly1305). Is it easily possible to support finite fields large enough that DLog is hard in them, e.g., primes of size ~ 3072 bits?
I know the cool kids use ECC nowadays but finite field DLog is not dead either. I'm specifically asking because Bitcoin is looking into MuHash [1] for incremental hashing for sets and finite field DLog is slightly more efficient for this use case in this context [2,3]. I wonder if fiat-crypto could be useful here. Specifically the linked PR implements finite field arithmetic for 2^3072 - 1103717 but since this a new feature, the choice of the prime is not set in stone.
[1] http://cseweb.ucsd.edu/~Mihir/papers/inchash.pdf
[2] https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2017-May/014337.html
[3] bitcoin/bitcoin#19055
The text was updated successfully, but these errors were encountered: