如何获得一个prolog规则,当它失败时,返回到规则的开头?

时间:2011-03-26 00:13:08

标签: cryptography prolog logic gnu

我正在盯着这个prolog代码而头疼,我似乎无法围绕着必须做的事情......

基本上,代码试图打破给定的协议,这意味着攻击者想要了解一些秘密数据。 所以攻击者试图攻击以获得这个秘密。要做到这一点,他必须成功运行协议。

successfulRun(Init_1,Init_2,Init_3,RespGet_1,RespGet_2,RespGet_3,Resp_1,Resp_2,Resp_3,XchdGet_1)

Init,Resp和Xchd是发送的消息的名称。 该谓词基本上表示成功运行是在发送一些Init_X(X是消息部分)时,Init_X的接收者发送RespGet_X作为响应,攻击者截获RespGet_X并自己发送Resp_X,Resp_X的接收者发送XchdGet_X作为响应

然后我有一个完整的运行,我注意到了。

asserta(fullRun(Init_1,Init_2,Init_3,RespGet_1,RespGet_2,RespGet_3,Resp_1,Resp_2,Resp_3,XchdGet_1))

如果攻击者在成功运行后知道秘密,则秘密会泄露。 如果秘密没有泄漏,则必须删除攻击期间获得的知识(因为实际上你不应该能够攻击一次交互的两个实例)。 然后开始新的攻击尝试。

如果攻击成功并且秘密被泄露,则会写一些关于攻击者如何获得秘密的信息。

tryToAttack(Secret) :-
  successfulRun(Init_1,Init_2,Init_3,RespGet_1,RespGet_2,RespGet_3,Resp_1,Resp_2,Resp_3,XchdGet_1),
  asserta(fullRun(Init_1,Init_2,Init_3,RespGet_1,RespGet_2,RespGet_3,Resp_1,Resp_2,Resp_3,XchdGet_1)),
  (
    (
      leaks(Secret),!
    );
    (
      \+leaks(secret),
      (
        deleteAttackKnowledge;
        (
          tryToAttack(Secret),
          true
        )
      )
    )
  ),
  writeAttackPattern(Secret,Init_1,Init_2,Init_3,RespGet_1,RespGet_2,RespGet_3,Resp_1,Resp_2,Resp_3,XchdGet_1).

好的,这是问题的开始: 在成功运行期间,提取攻击知识。这种知识被认为是事实!如果它没有持久性,那就不会有问题。所以另一种选择可能是不要让攻击知识持久化。

如果运行成功,但我们已经完成了这样的完整运行,我想从头开始执行另一次运行,这与上一次运行不同。我还希望在上次运行期间获得的所有攻击知识都被删除。

我看到的问题是:如果我把

(
  fullRun(...),
  deleteAttackKnowledge
)

在successRun结束时,Prolog尝试返回init或resp,攻击者在其中构建他的消息。如果Prolog回到resp,新的运行不会从respGet获得攻击知识。

我想 跑步 2.看看这次运行是否已经完成 3.如果已经完成,请删除所有攻击知识并转到(1),执行不同的运行。

successfulRun(Init_1,Init_2,Init_3,RespGet_1,RespGet_2,RespGet_3,Resp_1,Resp_2,Resp_3,XchdGet_1) :-
  init(Init_1,Init_2,Init_3),
  canBuild(Init_1),
  canBuild(Init_2),
  canBuild(Init_3),
  respGet(RespGet_1,RespGet_2,RespGet_3,Init_1,Init_2,Init_3),
  extractAttackKnowledge(RespGet_1),
  extractAttackKnowledge(RespGet_2),
  extractAttackKnowledge(RespGet_3),
  resp(Resp_1,Resp_2,Resp_3),
  canBuild(Resp_1),
  canBuild(Resp_2),
  canBuild(Resp_3),
  xchdGet(XchdGet_1,Resp_1,Resp_2,Resp_3),
  extractAttackKnowledge(XchdGet_1).

成功运行注意事项: init,resp:攻击者发送的内容 respGet,XchdGet:攻击者发出消息后对方发送的内容 canBuild:攻击者可以根据他的知识(开始知识+攻击知识)构建消息部分吗? extractAttackKnowledge:从消息部分中提取新的攻击知识

提前致谢, 丹尼尔W。

P.S。:如果有任何不清楚的地方,请随时发表评论。

1 个答案:

答案 0 :(得分:0)

要从失败的尝试中删除学到的信息,可以使用retractall / 1谓词。

例如:

deleteAttackKnowledge :- retractall(fullRun(_,_,_,_,_,_,_,_,_,_)).

注意:如果声明fullRun / 10是动态的(通过在代码顶部添加“: - dynamic(fullRun / 10)。”行),解释器将更容易处理。

由于我还不完全明白你到目前为止所做的事情,我现在就打算留下我的答案,如果我找到了可能有用的东西,我会回来再增加一个答案或者给你发一条消息。