Hello All:<br><br>I appreciate the recent help I've received on the dialyzer.<br><br>I'm using the dialyzer from the R12B4 distribution on a larger bit of code than my previous examples and it isn't trivial to<br>
whittle them down, due to functional dependencies. The code passes some preliminary testing. I've got two recurring dialyzer complaints (they look similar) The dialyzer invocation looks like:<br>dialyzer --verbose --plt dialyzer.plt -Wunmatched_returns -Wunderspecs -r . | tee dialyzer.log<br>
Checking whether the PLT dialyzer.plt is up-to-date... yes<br> Proceeding with analysis...<br>[Stuff Deleted]<br><br>The dialyzer complaints in my test case read:<br>test.erl:213: Type specification test:public_share_matches_coefficients/3 :: (Parameters::#feldman_vss_parameters{},PublicShare::#feldman_vss_public_share{},CoefficientWitnesses::[non_neg_integer()]) -> bool() is a supertype of the success typing: (#feldman_vss_parameters{},#feldman_vss_public_share{},[non_neg_integer(),...]) -> bool()<br>
test.erl:231: Type specification test:validate_shares_and_reconstruct_secret/3 :: (Parameters::#feldman_vss_parameters{},ShareList::[#feldman_vss_private_share{}],CoefficientWitnesses::[non_neg_integer()]) -> non_neg_integer() is a supertype of the success typing: (#feldman_vss_parameters{},[#feldman_vss_private_share{}],[non_neg_integer(),...]) -> non_neg_integer()<br>
<br>The whole files are a bit long for a code sample, after some sleep, perhaps I'll have some insights as to how to construct a smaller<br>example. For now, as a compromise, I'll post the structure definitions, the functions and their -spec() statements.<br>
<br><br>
%% @doc key_length is in bits<br>
%% @version $Id$ from $HeadURL$<br>
-record(feldman_vss_parameters, {key_length :: pos_integer(), %% key length in bits<br>
p :: pos_integer(), %% the generator's prime modulus<br>
q :: pos_integer(), %% the order of the generator<br>
g :: pos_integer(), %% a generator of order q over the integers 0..p-1<br>
n :: pos_integer(), %% the number of participants<br>
t :: pos_integer() %% the reconstruction threshold<br>
}).<br>
<br>
%% @doc The part of the share given visible to other participants<br>
-record(feldman_vss_public_share, {share_holder_id :: non_neg_integer(), %% the participand holding this share<br>
witness :: non_neg_integer() %% the public witness of the share<br>
}).<br>
<br>
%% @doc augmented public share containing information not available to all participants<br>
-record(feldman_vss_private_share, {public_share :: #feldman_vss_public_share{},<br>
secret_share :: non_neg_integer()<br>
}).<br>
<br><br>%% @private<br>%% @doc Given the parameters a public share and the list of coefficient witnesses, validates the public share<br>-spec(public_share_matches_coefficients/3 ::<br> ( Parameters::#feldman_vss_parameters{}, PublicShare::#feldman_vss_public_share{},<br>
CoefficientWitnesses::[ non_neg_integer() ] ) -> bool()). <br>public_share_matches_coefficients(Parameters, PublicShare, CoefficientWitnesses) when (is_record(Parameters, feldman_vss_parameters) and is_record(PublicShare, feldman_vss_public_share) and is_list(CoefficientWitnesses))-><br>
Id = PublicShare#feldman_vss_public_share.share_holder_id,<br> ShareWitness = PublicShare#feldman_vss_public_share.witness,<br> %% io:format("validate_public_share(Parameters=~w PublicShare=~w CoefficientWitnesses=~w) ID=~w, ShareWitness=~w~n",<br>
%% [Parameters, PublicShare, CoefficientWitnesses, Id, ShareWitness]),<br> ShareWitnessCheckValue =<br> compute_witness_check_value(CoefficientWitnesses, Id, 0,<br> Parameters#feldman_vss_parameters.p,<br>
Parameters#feldman_vss_parameters.q),<br> Result = (ShareWitnessCheckValue == ShareWitness),<br> Result.<br><br><br>%% @doc Given the secret sharing encoding parameters, the list of private shares of an authorized subset and the coefficient witnesses<br>
%% @doc check the shares and if valid reconstruct the secret, throws invalid_invalid_shares_received exception if corrupted shares are received <br>-spec(validate_shares_and_reconstruct_secret/3 ::<br> (Parameters :: #feldman_vss_parameters{}, ShareList :: [#feldman_vss_private_share{}],<br>
CoefficientWitnesses :: [non_neg_integer()])->non_neg_integer()).<br>validate_shares_and_reconstruct_secret(Parameters, ShareList, CoefficientWitnesses) when (is_list(ShareList) and is_record(Parameters, feldman_vss_parameters) and is_list(CoefficientWitnesses))-><br>
%% io:format("reconstruct_secret(ShareList=~w, Parameters=~w, CoefficientWitnesses=~w) invoked~n", [ShareList, Parameters, CoefficientWitnesses]),<br> PublicShares = [ Share#feldman_vss_private_share.public_share || Share<-ShareList ],<br>
ShareListIsValid =<br> validate_public_shares(Parameters, PublicShares, CoefficientWitnesses),<br> %% io:format("reconstruct_secret, ShareListIsValid =~w~n", [ShareListIsValid]),<br> if<br> (not ShareListIsValid)-><br>
throw({invalid_shares_received, [ShareList, Parameters, CoefficientWitnesses]});<br> (ShareListIsValid)-><br> Result = reconstruct_secret(Parameters, ShareList),<br> Result<br> end.<br><br>More information could be made availalble if needed. I would like to know:<br>
1) Am I right that the dialyzer thinks that these functions need non-empty lists?<br>2) Why would the dialyzer think that?<br>3) What can I do to get information out of the dialyzer to get a better hint as to why it thinks that?<br>
<br>Regards:<br><br>Bill M.<br>