[erlang-questions] Dialyzer and how it handles lists in R12B4

Foolish Ewe <>
Sun Nov 16 05:50:36 CET 2008


Hello All:

I appreciate the recent help I've received on the dialyzer.

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
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:
dialyzer --verbose --plt dialyzer.plt -Wunmatched_returns -Wunderspecs -r .
| tee dialyzer.log
  Checking whether the PLT dialyzer.plt is up-to-date... yes
  Proceeding with analysis...
[Stuff Deleted]

The dialyzer complaints in my test case read:
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()
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()

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
example.  For now, as a compromise, I'll post the structure definitions, the
functions and their -spec() statements.


%% @doc key_length is in bits
%% @version $Id$ from $HeadURL$
-record(feldman_vss_parameters, {key_length :: pos_integer(),  %% key length
in bits
                 p          :: pos_integer(),  %% the generator's prime
modulus
                 q          :: pos_integer(),  %% the order of the generator
                 g          :: pos_integer(),  %% a generator of order q
over the integers 0..p-1
                 n          :: pos_integer(),  %% the number of participants
                 t          :: pos_integer()   %% the reconstruction
threshold
                }).

%% @doc The part of the share given visible to other participants
-record(feldman_vss_public_share, {share_holder_id ::
non_neg_integer(),      %% the participand holding this share
                   witness         :: non_neg_integer()   %% the public
witness of the share
                  }).

%% @doc augmented public share containing information not available to all
participants
-record(feldman_vss_private_share, {public_share ::
#feldman_vss_public_share{},
                    secret_share :: non_neg_integer()
                   }).


%% @private
%% @doc Given the parameters a public share and the list of coefficient
witnesses, validates the public share
-spec(public_share_matches_coefficients/3 ::
      ( Parameters::#feldman_vss_parameters{},
PublicShare::#feldman_vss_public_share{},
    CoefficientWitnesses::[ non_neg_integer() ] ) -> bool()).
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))->
    Id = PublicShare#feldman_vss_public_share.share_holder_id,
    ShareWitness = PublicShare#feldman_vss_public_share.witness,
    %% io:format("validate_public_share(Parameters=~w PublicShare=~w
CoefficientWitnesses=~w) ID=~w, ShareWitness=~w~n",
    %%          [Parameters, PublicShare, CoefficientWitnesses, Id,
ShareWitness]),
    ShareWitnessCheckValue =
    compute_witness_check_value(CoefficientWitnesses, Id, 0,
                     Parameters#feldman_vss_parameters.p,
                     Parameters#feldman_vss_parameters.q),
    Result = (ShareWitnessCheckValue == ShareWitness),
    Result.


%% @doc Given the secret sharing encoding parameters, the list of private
shares of an authorized subset and the coefficient witnesses
%% @doc check the shares and if valid reconstruct the secret, throws
invalid_invalid_shares_received exception if corrupted shares are received
-spec(validate_shares_and_reconstruct_secret/3 ::
      (Parameters :: #feldman_vss_parameters{}, ShareList ::
[#feldman_vss_private_share{}],
       CoefficientWitnesses :: [non_neg_integer()])->non_neg_integer()).
validate_shares_and_reconstruct_secret(Parameters, ShareList,
CoefficientWitnesses) when (is_list(ShareList) and is_record(Parameters,
feldman_vss_parameters) and is_list(CoefficientWitnesses))->
    %% io:format("reconstruct_secret(ShareList=~w, Parameters=~w,
CoefficientWitnesses=~w) invoked~n", [ShareList, Parameters,
CoefficientWitnesses]),
    PublicShares = [ Share#feldman_vss_private_share.public_share ||
Share<-ShareList ],
    ShareListIsValid =
    validate_public_shares(Parameters, PublicShares, CoefficientWitnesses),
    %% io:format("reconstruct_secret, ShareListIsValid =~w~n",
[ShareListIsValid]),
    if
    (not ShareListIsValid)->
        throw({invalid_shares_received, [ShareList, Parameters,
CoefficientWitnesses]});
    (ShareListIsValid)->
        Result = reconstruct_secret(Parameters, ShareList),
        Result
    end.

More information could be made availalble if needed.  I would like to know:
1) Am I right that the dialyzer thinks that these functions need non-empty
lists?
2) Why would the dialyzer think that?
3) What can I do to get information out of the dialyzer to get a better hint
as to why it thinks that?

Regards:

Bill M.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20081115/6d728399/attachment.html>


More information about the erlang-questions mailing list