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

Cryptography 我如何获得一个prolog规则,当它失败时,返回到规则的开头?,cryptography,prolog,logic,gnu,Cryptography,Prolog,Logic,Gnu,我盯着这段序言代码感到头疼,我似乎无法集中精力去做该做的事情 基本上,代码试图破坏给定的协议,这意味着攻击者想要了解一些秘密数据。 所以攻击者试图通过攻击来获取这个秘密。要做到这一点,他必须成功运行协议 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(

我盯着这段序言代码感到头疼,我似乎无法集中精力去做该做的事情

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

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
)
在successfulRun结束时,Prolog尝试返回init或resp,攻击者在那里构建消息。如果Prolog返回resp,则新运行不会从respGet获得攻击知识

我想 1.跑步 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


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

要清除失败尝试中获得的信息,可以使用retractall/1谓词

例如:

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


由于我目前还不完全了解您正在做什么,我现在将留下我的答案,如果我找到了一些有帮助的方法,我会回来,或者添加另一个答案,或者向您发送一条关于它的消息。

是否有必要以这种方式在全球范围内声明获得的信息?在变量中传递这些信息会不会太复杂?我通过将信息存储在变量中而不是断言变量来解决这个问题。谢谢你的帮助,这也会解决问题的。