Skip to content

Commit

Permalink
Vinegars with signature and verification
Browse files Browse the repository at this point in the history
  • Loading branch information
pdeperth authored Oct 29, 2019
1 parent 6386b13 commit 302f904
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 36 deletions.
8 changes: 4 additions & 4 deletions HFE_main.m
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
for i in [1..#bin_iter] do
completion[n-m-i+1][1] := bin_iter[#bin_iter-i+1];
end for;
iter +:= 1;
iter +:= 1;
invT_d := Matrix(F2,n,1,[&+[d[i]*invT[k,i] : i in [1..m]] + &+ [completion[i]*invT[k,i+m] : i in [1..n-m]] : k in [1..n]]);
MPF2n_invT_d := invert_phi(invT_d, n);
roots := Roots(univF-MPF2n_invT_d);
Expand All @@ -64,12 +64,12 @@

sign := function(message, univF, S, T, n, m)
H := Intseq(Hash(message),2);
Si := Matrix(F2,n,1,[0 : k in [1..n]]);
Si := Matrix(F2,m,1,[0 : k in [1..m]]);
found_inverse := false;
iter := 1;
while found_inverse eq false do
D := Matrix(F2,n,1,[0 : k in [1..n]]);
for k in [1..Minimum(n,#H)] do
D := Matrix(F2,m,1,[0 : k in [1..m]]);
for k in [1..Minimum(m,#H)] do
D[k][1] := H[k];
end for;
DxorSi := D + Si; // addition in F2 is a xor operation.
Expand Down
21 changes: 11 additions & 10 deletions HFEv-_generate_keys.m
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

n := 20; // messages length. // from 21 and on, Zech log tables are used ; for lesser n values, the exponents go up without any limitation.
n := 27; // messages length. // from 21 and on, Zech log tables are used ; for lesser n values, the exponents go up without any limitation.
D := 8; // degree of the F polynom.
m := n-4; // number of equations in the f polynomial system.
v := 5; // number of vinegar variables.
Expand Down Expand Up @@ -38,11 +38,11 @@
end function;

make_A := function(D,n)
A := Matrix(F2n,n,n,[0 : i,j in [1..n]]); // upper triangular matrix
A := Matrix(F2n,D-1,D-1,[0 : i,j in [1..D-1]]); // upper triangular matrix
for j in [2..n] do
for i in [1..(j-1)] do
if 2^(i-1)+2^(j-1) le D then
A[i,j] := Random(F2n);
A[2^(i-1),2^(j-1)] := Random(F2n);
end if;
end for;
end for;
Expand All @@ -58,13 +58,14 @@
catch e
"There is only one vinegar variable"; // we have an error if v eq 1 because then the sum quadratic sequence is null.
end try;
multivariateF := &+ [ &+ [ A[i+1,j+1]*X_exp_2_exp_i(n,i)*X_exp_2_exp_i(n,j) : i in [0..j] ] : j in [0..(n-1)] ] + &+ [ (&+ [B[i+1,(k-n)]*MPF2n.k : k in [n+1..n+v]])*X_exp_2_exp_i(n,i) : i in [0..n-1]] + C;
univariateF := &+ [ &+ [ A[i+1,j+1]*PF2n.1^(2^i+2^j) : i in [0..j] ] : j in [0..(n-1)] ] + &+ [(&+ [B[i+1,k-1]*PF2n.k : k in [2..v+1]])*PF2n.1^(2^i) : i in [0..n-1]] + MPF2n_to_PF2n(C);
multivariateF := &+ [ &+ [ A[2^i,2^j]*X_exp_2_exp_i(n,i)*X_exp_2_exp_i(n,j) : i in [0..j] ] : j in [0..(Floor(Log(D-1)/Log(2))-1)] ] + &+ [ (&+ [B[i+1,(k-n)]*MPF2n.k : k in [n+1..n+v]])*X_exp_2_exp_i(n,i) : i in [0..n-1]] + C;
univariateF := &+ [ &+ [ A[2^i,2^j]*PF2n.1^(2^i+2^j) : i in [0..j] ] : j in [0..(Floor(Log(D-1)/Log(2))-1)] ] + &+ [(&+ [B[i+1,k-1]*PF2n.k : k in [2..v+1]])*PF2n.1^(2^i) : i in [0..n-1]] + MPF2n_to_PF2n(C);
return multivariateF, univariateF;
end function;

F, univF := make_F(D,n,v);
print "F(X) = ", univF;
print "F(X)";
// print "F(X) = ", univF;

// Draft for changing F entirely, gave it up; anyways it wasn't necessary at all.
// MPF2 := PolynomialRing(PF2,n);
Expand Down Expand Up @@ -101,7 +102,7 @@

pol_sys_fi := get_pol_sys_fi(F,n);
print("Système polynomial f : ");
pol_sys_fi;
// pol_sys_fi;


S := RandomMatrix(F2,n+v,n+v);
Expand All @@ -115,9 +116,9 @@
S := ChangeRing(S, MPF2n); // to allow multiplication with elements in MPF2n
T := ChangeRing(T, MPF2n);
print("Matrice de changement de variables S : ");
S;
// S;
print("Matrice de mélange d'équations T : ");
T;
// T;


//////////////////////////////////
Expand Down Expand Up @@ -146,4 +147,4 @@

public_key := Matrix(m,1,[(T*pol_sys_fiSx)[i,1] : i in [1..m]]);
print("Clé publique : ");
public_key;
// public_key;
64 changes: 42 additions & 22 deletions HFEv-_main.m
Original file line number Diff line number Diff line change
Expand Up @@ -43,33 +43,53 @@
// T^(-1)*d; // incompatible coefficient rings
roots := [];
invT := T^(-1);
iter := 0;
vinegar := [0 : k in [1..v]]; // TODO: change from Random to ordered logic
F_with_these_Vs := PF2n_to_UPF2n(Evaluate(univF, [PF2n.1] cat [vinegar[k] : k in [1..v]]));
while #roots eq 0 do
completion := Matrix(n-m, 1, [Random(F2) : i in [1..n-m]]);
completion := Matrix(n-m, 1, [0 : i in [1..n-m]]);
new_vinegar := [0 : k in [1..v]];
bin_iter := Intseq(iter, 2);
for i in [1..Minimum(n-m, #bin_iter)] do
completion[n-m-i+1][1] := bin_iter[#bin_iter-i+1];
end for;
if #bin_iter gt (n-m) then
for i in [(n-m+1)..Minimum(#bin_iter,n-m+v)] do
new_vinegar[i-n+m] := bin_iter[#bin_iter-i+1];
end for;
end if;
iter +:= 1;
MPF2n_invT_d := invert_phi(Matrix(F2,n,1,[&+[d[i]*invT[k,i] : i in [1..m]] + &+[completion[i]*invT[k,i+m] : i in [1..n-m]] : k in [1..n]]), n);
vinegar := [Random(F2) : k in [1..v]]; // TODO: change from Random to ordered logic
F_with_these_Vs := PF2n_to_UPF2n(Evaluate(univF, [PF2n.1] cat [vinegar[k] : k in [1..v]]));
if new_vinegar ne vinegar then
F_with_these_Vs := PF2n_to_UPF2n(Evaluate(univF, [PF2n.1] cat [new_vinegar[k] : k in [1..v]]));
vinegar := new_vinegar;
end if;
try
roots := Roots(F_with_these_Vs-MPF2n_invT_d);
catch e
print e; // if F_with_these_Vs-MPF2n_invT_d is null, an error will be displayed.
end try;
end while;
r := Random(roots); // maybe we should give more weight to roots with higher multiplicity? -> TODO
vect_r := Matrix(n+v, 1, [phi(r[1],n)[k][1]:k in [1..n]] cat vinegar); // vertical matrix in F2; // TODO: include vinegars here.
vect_r := Matrix(n+v, 1, [phi(r[1],n)[k][1]:k in [1..n]] cat vinegar); // vertical matrix in F2;
print iter, " complétion.s testée.s pour l'inversion.";
invS := S^(-1);
return Matrix(F2,n+v,1,[&+[vect_r[i][1]*invS[k,i] : i in [1..n+v]] : k in [1..n+v]]), vinegar;
end function;

sign := function(message, univF, S, T, n, m)
sign := function(message, univF, S, T, n, m, v)
H := Intseq(Hash(message),2);
Si := Matrix(F2,n,1,[0 : k in [1..n]]);
Si := Matrix(F2,m,1,[0 : k in [1..m]]);
found_inverse := false;
iter := 1;
while found_inverse eq false do
D := Matrix(F2,n,1,[H[k] : k in [1..n]]);
D := Matrix(F2,m,1,[0 : k in [1..m]]);
for k in [1..Minimum(m,#H)] do
D[k][1] := H[k];
end for;
DxorSi := D + Si; // addition in F2 is a xor operation.
try
Si := invert(DxorSi, univF, S, T, n, m);
Si := invert(DxorSi, univF, S, T, n, m, v);
found_inverse := true;
catch e
print Transpose(DxorSi), " n'est pas inversible.";
Expand All @@ -80,7 +100,7 @@
return Si, iter;
end function;

check_signature := function(signature, message, public_key, nb_ite, m)
check_signature := function(signature, message, public_key, nb_ite, m, n, v)
H := Intseq(Hash(message),2);
Si := signature;
// D := Matrix(F2, nb_ite, n, [0 : k in [1..n*nb_ite]]);
Expand All @@ -92,7 +112,7 @@
// for i in [(nb_ite-1)..0] do
// Si := Matrix(F2,n,1,[Evaluate(public_key, [Si[k]: k in [1..n]])[k] : k in [1..n]]) + D[i];
// end for;
Si := Matrix(F2,m,1,[Evaluate(public_key, [Si[l][1]: l in [1..n]])[k] : k in [1..m]]) + D;
Si := Matrix(F2,m,1,[Evaluate(public_key, [Si[l][1]: l in [1..n+v]])[k] : k in [1..m]]) + D;
if Si eq Matrix(F2,m,1,[0 : k in [1..m]]) then
return "La signature est valide.";
else
Expand Down Expand Up @@ -125,15 +145,15 @@
Transpose(cipher([inverted_cipher_m[k][1] : k in [1..n]], public_key, [inverted_cipher_m[k][1] : k in [n+1..n+v]], m));
// Transpose(cipher([inverted_cipher_m[k][1] : k in [1..n]], public_key, inverted_cipher_m_vinegars, m));

// // nb_ite := 4;
// m_signature, m_sign_iters := sign(message, univF, S, T, n, m);
// if m_sign_iters eq 1 then
// print "signature du message, en 1 itération : ";
// else
// print "signature du message, en ", m_sign_iters, " itérations : ";
// end if;
// Transpose(m_signature);
//
// // Signature verification :
// verif := check_signature(m_signature, message, public_key, m_sign_iters, m);
// print verif;
// nb_ite := 4;
m_signature, m_sign_iters := sign(message, univF, S, T, n, m, v);
if m_sign_iters eq 1 then
print "signature du message, en 1 itération : ";
else
print "signature du message, en ", m_sign_iters, " itérations : ";
end if;
Transpose(m_signature);

// Signature verification :
verif := check_signature(m_signature, message, public_key, m_sign_iters, m, n, v);
print verif;

0 comments on commit 302f904

Please sign in to comment.