gpt4 book ai didi

ada - 未能断言 libsparkcrypto SHA256 结果相等

转载 作者:行者123 更新时间:2023-12-03 23:00:25 29 4
gpt4 key购买 nike

我的问题总结
我正在使用 libsparkcrypto library对于我的 SHA256 函数。我发现我不能 Assert那个x = y暗示 Sha256(x) = Sha256(y) .任何帮助将不胜感激。
代码
测试包.adb

package body TestPackage with
SPARK_Mode
is

function Is_Equal (X, Y : LSC.Types.Bytes) return Boolean is
begin
if X = Y then
pragma Assert (LSC.SHA2.Hash_SHA256 (X) = LSC.SHA2.Hash_SHA256 (Y));
return True;
end if;
return (LSC.SHA2.Hash_SHA256 (X) = LSC.SHA2.Hash_SHA256 (Y));
end Is_Equal;

end TestPackage;
测试包.ads
with LSC.Types; use LSC.Types;
with LSC.SHA2;

package TestPackage with
SPARK_Mode
is

function Is_Equal (X, Y : LSC.Types.Bytes) return Boolean with
Post => Is_Equal'Result = (LSC.SHA2.Hash_SHA256 (X) = LSC.SHA2.Hash_SHA256 (Y));

end TestPackage;
输出
我收到的错误是:

testpackage.adb:8:25: medium: assertion might fail, cannot proveLSC.SHA2.Hash_SHA256 (X) = LSC.SHA2.Hash_SHA256 (Y) [possibleexplanation: subprogram at testpackage.ads:8 should mention X and Y ina precondition][#0]


我的 gnatprove.out :
Summary of SPARK analysis
=========================

-------------------------------------------------------------------------------------------
SPARK Analysis results Total Flow CodePeer Provers Justified Unproved
-------------------------------------------------------------------------------------------
Data Dependencies . . . . . .
Flow Dependencies . . . . . .
Initialization . . . . . .
Non-Aliasing . . . . . .
Run-time Checks 6 . . 6 (CVC4) . .
Assertions 1 . . . . 1
Functional Contracts 1 . . 1 (CVC4) . .
LSP Verification . . . . . .
Termination . . . . . .
Concurrency . . . . . .
-------------------------------------------------------------------------------------------
Total 8 . . 7 (88%) . 1 (13%)


max steps used for successful proof: 1

Analyzed 2 units
in unit main, 0 subprograms and packages out of 1 analyzed
Main at main.adb:8 skipped
in unit testpackage, 2 subprograms and packages out of 2 analyzed
TestPackage at testpackage.ads:4 flow analyzed (0 errors, 0 checks and 0 warnings) and proved (0 checks)
TestPackage.Is_Equal at testpackage.ads:8 flow analyzed (0 errors, 0 checks and 0 warnings) and not proved, 7 checks out of 8 proved

最佳答案

虽然这不是问题的答案,但对较小示例的一些调查表明该问题并非特定于 LSC.SHA2.Hash_SHA256。 libsparkcrypto 库中的函数。似乎证明具有数组类型参数的函数的“纯度”存在普遍困难。另一方面,带有标量类型参数的函数被证明是符合预期的。
因此,问题可能是阵列上的某些条件缺失、求解器超时太短或只是 SPARK 当前无法证明此类问题(例如,请参见 SPARK UG 中的 7.8.3 部分)。关于缺失的条件:我不确定(还)这些缺失的条件可能是什么,我已经添加了很多,但似乎没有任何帮助。
如果您是证明专家,那么您可以通过检查在手动证明环境中失败的“目标”来进一步调查问题(另请参阅 SPARK UG 中的 7.1.8 部分以了解详细信息)。不幸的是,我在这里缺少合适的博士来理解 SPARK 工具的这一部分并对此有任何帮助;-)。
pkg.ads

package Pkg with SPARK_Mode, Pure is 

--------------------------------------------
-- Functions with a scalar type parameter --
--------------------------------------------

function Fcn_Scalar_1 (X : Integer) return Integer;

function Fcn_Scalar_2 (X : Integer) return Integer
with Pure_Function;

function Fcn_Scalar_3 (X : Integer) return Integer
with
Global => null,
Depends => (Fcn_Scalar_3'Result => X);

function Fcn_Scalar_4 (X : Integer) return Integer
with Post => Fcn_Scalar_4'Result = X;

--------------------------------------------
-- Functions with an array type parameter --
--------------------------------------------

type Arr is array (Natural range <>) of Integer;

function Fcn_Array_1 (X : Arr) return Integer;

function Fcn_Array_2 (X : Arr) return Integer
with Pure_Function;

function Fcn_Array_3 (X : Arr) return Integer
with
Global => null,
Depends => (Fcn_Array_3'Result => X);

function Fcn_Array_4 (X : Arr) return Arr
with Post => Fcn_Array_4'Result = X;

end Pkg;
测试广告
with Pkg; use Pkg;

package Test with SPARK_Mode is

-- Is_Equal_Scalar_1 : Postcondition proved.
-- Is_Equal_Scalar_2 : Postcondition proved.
-- Is_Equal_Scalar_3 : Postcondition proved.
-- Is_Equal_Scalar_4 : Postcondition proved.

function Is_Equal_Scalar_1 (X, Y : Integer) return Boolean is
(if X = Y then True else Fcn_Scalar_1 (X) = Fcn_Scalar_1 (Y))
with Post => Is_Equal_Scalar_1'Result = (Fcn_Scalar_1 (X) = Fcn_Scalar_1 (Y));

function Is_Equal_Scalar_2 (X, Y : Integer) return Boolean is
(if X = Y then True else Fcn_Scalar_2 (X) = Fcn_Scalar_2 (Y))
with Post => Is_Equal_Scalar_2'Result = (Fcn_Scalar_2 (X) = Fcn_Scalar_2 (Y));

function Is_Equal_Scalar_3 (X, Y : Integer) return Boolean is
(if X = Y then True else Fcn_Scalar_3 (X) = Fcn_Scalar_3(Y))
with Post => Is_Equal_Scalar_3'Result = (Fcn_Scalar_3 (X) = Fcn_Scalar_3 (Y));

function Is_Equal_Scalar_4 (X, Y : Integer) return Boolean is
(if X = Y then True else Fcn_Scalar_4 (X) = Fcn_Scalar_4(Y))
with Post => Is_Equal_Scalar_4'Result = (Fcn_Scalar_4 (X) = Fcn_Scalar_4 (Y));

-- Is_Equal_Array_1 : Postcondition NOT proved.
-- Is_Equal_Array_2 : Postcondition NOT proved.
-- Is_Equal_Array_3 : Postcondition NOT proved.
-- Is_Equal_Array_4 : Postcondition proved, but only because of the postcondition on Fcn_Array_4.

function Is_Equal_Array_1 (X, Y : Arr) return Boolean is
(if X = Y then True else Fcn_Array_1 (X) = Fcn_Array_1 (Y))
Pre => X'First = 0 and Y'First = 0 and X'Length = Y'Length and X'Length > 0 and Y'Length > 0,
Post => Is_Equal_Array_1'Result = (Fcn_Array_1 (X) = Fcn_Array_1 (Y));

function Is_Equal_Array_2 (X, Y : Arr) return Boolean is
(if X = Y then True else Fcn_Array_2 (X) = Fcn_Array_2 (Y))
with
Pre => X'First = 0 and Y'First = 0 and X'Length = Y'Length and X'Length > 0 and Y'Length > 0,
Post => Is_Equal_Array_2'Result = (Fcn_Array_2 (X) = Fcn_Array_2 (Y));

function Is_Equal_Array_3 (X, Y : Arr) return Boolean is
(if X = Y then True else Fcn_Array_3 (X) = Fcn_Array_3 (Y))
with
Pre => X'First = 0 and Y'First = 0 and X'Length = Y'Length and X'Length > 0 and Y'Length > 0,
Post => Is_Equal_Array_3'Result = (Fcn_Array_3 (X) = Fcn_Array_3 (Y));

function Is_Equal_Array_4 (X, Y : Arr) return Boolean is
(if X = Y then True else Fcn_Array_4 (X) = Fcn_Array_4 (Y))
with Post => Is_Equal_Array_4'Result = (Fcn_Array_4 (X) = Fcn_Array_4 (Y));

end Test;
输出 (证明)
$ gnatprove -Pdefault.gpr --level=2 -j0 -u test.ads --report=statistics
Phase 1 of 2: generation of Global contracts ...
Phase 2 of 2: flow analysis and proof ...
test.ads:12:21: info: postcondition proved (CVC4: 2 VC in max 0.0 seconds and 1 step)
test.ads:16:21: info: postcondition proved (CVC4: 2 VC in max 0.0 seconds and 1 step)
test.ads:20:21: info: postcondition proved (CVC4: 2 VC in max 0.0 seconds and 1 step)
test.ads:24:21: info: postcondition proved (CVC4: 2 VC in max 0.0 seconds and 1 step)
test.ads:35:18: medium: postcondition might fail, cannot prove Is_Equal_Array_1'Result = (Fcn_Array_1 (X) = Fcn_Array_1 (Y)) (e.g. when X = (others => 0) and X'First = 0 and X'Last = 0 and Y = (others => 0) and Y'First = 0 and Y'Last = 0)
test.ads:41:18: medium: postcondition might fail, cannot prove Is_Equal_Array_2'Result = (Fcn_Array_2 (X) = Fcn_Array_2 (Y)) (e.g. when X = (others => 0) and X'First = 0 and X'Last = 0 and Y = (others => 0) and Y'First = 0 and Y'Last = 0)
test.ads:47:18: medium: postcondition might fail, cannot prove Is_Equal_Array_3'Result = (Fcn_Array_3 (X) = Fcn_Array_3 (Y)) (e.g. when X = (others => 0) and X'First = 0 and X'Last = 0 and Y = (others => 0) and Y'First = 0 and Y'Last = 0)
test.ads:51:21: info: postcondition proved (CVC4: 2 VC in max 0.0 seconds and 1 step)
Summary logged in /obj/gnatprove/gnatprove.out


更新
仔细想想,还有更多。虽然仍然无法解决问题,但我意识到 Is_Equal 上的前提条件在数组类型的情况下,函数是必需的。这是因为数组的相等运算符在 Ada 中的行为方式。数组上的相等运算符 不是 考虑到索引边界( RM 4.5.2 (18) ),它只检查数组长度及其组件值。因此,以下数组 A1A2 , 被认为是相等的:
type Arr is array (Natural range <>) of Integer;

A1 : constant Arr (0 .. 3) := (1, 2, 3, 4);
A2 : constant Arr (1 .. 4) := (1, 2, 3, 4); -- Bounds on index differ.
现在定义简单的函数 First_Index作为:
function First_Index (A : Arr) return Integer is (A'First);
此函数返回数组的索引下限。不幸的是 gnatprove将无法证明 Is_Equal此功能 First_Index出于显而易见的原因,仅具有后置条件的函数。
function Is_Equal (X, Y : Arr) return Boolean is
(if X = Y then True else First_Index (X) = First_Index (Y))
with Post => Is_Equal'Result = (First_Index (X) = First_Index (Y));
因此,前提条件是强制性的,因为“纯”函数的结果可能取决于数组的边界。有了这个前提条件,就可以证明该功能(见下文)。对于前面示例中的情况,这不起作用。
main.adb
with Ada.Text_IO; use Ada.Text_IO;

procedure Main with SPARK_Mode is

type Arr is array (Natural range <>) of Integer;

function First_Index (A : Arr) return Integer is (A'First);

function Is_Equal (X, Y : Arr) return Boolean is
(if X = Y then True else First_Index (X) = First_Index (Y))
with
Pre => X'First = 0 and Y'First = 0,
Post => Is_Equal'Result = (First_Index (X) = First_Index (Y));

A1 : constant Arr (0 .. 3) := (1, 2, 3, 4);
A2 : constant Arr (1 .. 4) := (1, 2, 3, 4); -- Bounds on index differ.

begin
if (A1 = A2) then
Put_Line ("Equal");
else
Put_Line ("Not Equal");
end if;
end Main;
输出 (主要的)
Equal
输出 (证明)
$ gnatprove -Pdefault.gpr --level=1 -j0 -u main.adb --report=statistics
Phase 1 of 2: generation of Global contracts ...
Phase 2 of 2: flow analysis and proof ...
main.adb:16:18: info: postcondition proved (CVC4: 2 VC in max 0.0 seconds and 1 step)
Summary logged in obj/gnatprove/gnatprove.out

关于ada - 未能断言 libsparkcrypto SHA256 结果相等,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66279968/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com