-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathOTSM.ec
141 lines (114 loc) · 3.54 KB
/
OTSM.ec
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
require import FSet Int Real SmtMap Distr List DInterval BasicProps.
(* Here we develop an auxiliary scheme where M one-time keypairs are
generated and adversary wins if they manage to forge a signature for
at least one of the keypair. *)
abstract theory OTSM_Theory.
type pkey, skey, message, sig.
op otsKey : int -> pkey * skey.
op M : int.
op dR : int distr.
op otsSig : skey -> message -> sig.
op otsVer : pkey option -> message -> sig -> bool.
op otsSigMany : (int -> skey option) -> int -> message -> sig
= fun skf i m => otsSig (oget (skf i)) m.
op otsVerMany : (int -> pkey option) -> int -> message -> sig -> bool
= fun pkf i m s => otsVer (pkf i) m s.
require IdealPRF.
clone export IdealPRF as NP with type D <- int,
type R <- int,
type K <- int,
op dR <- dR,
op dK <- dR.
require import KeyGen.
clone export KeyGen with type pkey <- (int -> pkey option),
type skey <- (int -> skey option),
op dR <- dR.
module KeyGenOTSM (F : PRF_Hiding) : KeyGenT = {
proc keyGen() : (int -> pkey option) * (int -> skey option) = {
var pkf : (int -> pkey option);
var skf : (int -> skey option);
var i : int;
var pk : pkey;
var sk : skey;
var rs : int;
F.init();
pkf <- fun _ => None;
skf <- fun _ => None;
i <- 1;
while (i < M + 1){
rs <@ F.f(i);
(pk, sk) <- otsKey rs;
pkf <- fun x => if x = i then Some pk else pkf x;
skf <- fun x => if x = i then Some sk else skf x;
i <- i + 1;
}
return (pkf, skf);
}
}.
module OTSMKeysIdeal : KeyGenT = KeyGenOTSM (RandomFunction).
module type OTSMOracleT = {
proc init(pk : int -> pkey option, sk : int -> skey option) : unit
proc sign(n : int, m : message) : sig option
proc fresh(i : int, m : message) : bool
proc getMsgLog() : (int, message) fmap
proc getSigLog() : (int, sig) fmap
proc getPK() : int -> pkey option
}.
module OTSMOracle = {
var used : (int, unit) fmap
var skf : int -> skey option
var pkf : int -> pkey option
var log : (int, message) fmap
var slog : (int, sig) fmap
proc init(pkf : int -> pkey option, skf : int -> skey option) = {
OTSMOracle.skf <- skf;
OTSMOracle.pkf <- pkf;
used <- empty;
log <- empty;
slog <- empty;
}
proc sign(n : int, m : message) : sig option = {
var r;
if(used.[n] = Some ()){
r <- None;
}else{
r <- Some (otsSigMany skf n m);
log <- log.[n <- m];
slog <- slog.[n <- (otsSigMany skf n m)];
}
used <- used.[n <- ()];
return r;
}
proc fresh(i : int, m : message) : bool = {
return (Some m) <> log.[i];
}
proc getSigLog() : (int , sig) fmap = {
return slog;
}
proc getMsgLog() : (int , message) fmap = {
return log;
}
proc getPK() : int -> pkey option = {
return pkf;
}
}.
module type AdvOTSM (O : OTSMOracleT) = {
proc forge(pk : int -> pkey option) : int * message * sig {O.sign, O.getMsgLog ,
O.getSigLog, O.getPK}
}.
module GameOTSM(O : OTSMOracleT, A : AdvOTSM, K : KeyGenT) = {
module A = A(O)
var i : int
var s : sig
var m : message
proc main() : bool = {
var pk, sk, forged, fresh;
(pk, sk) <@ K.keyGen();
O.init(pk, sk);
(i, m, s) <@ A.forge(pk);
forged <- otsVerMany pk i m s;
fresh <@ O.fresh(i, m);
return 0 < i /\ i <= M /\ forged /\ fresh;
}
}.
end OTSM_Theory.