@@ -16,6 +16,9 @@ module BA = struct
16
16
17
17
let compare a b =
18
18
compare_rec a b 0 (length a) (length b)
19
+
20
+ let create len =
21
+ Bigarray. (create char c_layout len)
19
22
end
20
23
21
24
type buffer = (char , Bigarray .int8_unsigned_elt , Bigarray .c_layout ) Bigarray.Array1 .t
@@ -49,137 +52,253 @@ module Secret = struct
49
52
external verify :
50
53
Context .t -> buffer -> bool = " ml_secp256k1_ec_seckey_verify"
51
54
55
+ let length = 32
56
+
52
57
type t = buffer
53
58
54
59
let compare = BA. compare
55
60
56
- let of_bytes ctx buf =
57
- if BA. length buf <> 32 then
58
- invalid_arg " Secret.of_bytes: inputs must be 32 bytes long" ;
61
+ let of_bytes ctx ?(pos =0 ) buf =
62
+ let buflen = BA. length buf in
63
+ if pos < 0 || pos > buflen - length then
64
+ invalid_arg " Secret.of_bytes: pos < 0 or pos + 32 > buflen" ;
65
+ let buf = BA. sub buf pos length in
59
66
match verify ctx buf with
60
67
| true -> Some buf
61
68
| false -> None
62
69
63
- let of_bytes_exn ctx buf =
70
+ let of_bytes_exn ctx ? pos buf =
64
71
match of_bytes ctx buf with
65
72
| None -> failwith " Secret.of_bytes_exn"
66
73
| Some sk -> sk
74
+
75
+ let to_bytes t = t
76
+
77
+ let write buf ?(pos =0 ) t =
78
+ let buflen = BA. length buf in
79
+ if pos < 0 || pos > buflen - length then
80
+ invalid_arg " Secret.write: pos < 0 or pos + 32 > buflen" ;
81
+ let buf = BA. sub buf pos length in
82
+ BA. blit t buf
67
83
end
68
84
69
85
module Public = struct
70
86
type t = buffer
71
87
72
- let compare = BA. compare
73
-
74
- external of_bytes :
75
- Context .t -> buffer -> t = " ml_secp256k1_ec_pubkey_parse"
88
+ let length = 64
76
89
77
- external to_bytes :
78
- Context .t -> t -> bool -> buffer = " ml_secp256k1_ec_pubkey_serialize"
79
-
80
- external of_secret :
81
- Context .t -> Secret .t -> t = " ml_secp256k1_ec_pubkey_create"
82
-
83
- let of_bytes ctx buf =
84
- if BA. (length buf <> 33 && length buf <> 65 ) then
85
- invalid_arg " Public.of_bytes: input must be either 33 or 65 bytes long" ;
86
- try Some (of_bytes ctx buf) with _ -> None
90
+ let compare = BA. compare
87
91
88
- let of_bytes_exn ctx buf =
89
- match of_bytes ctx buf with
92
+ external parse :
93
+ Context .t -> buffer -> buffer -> unit = " ml_secp256k1_ec_pubkey_parse"
94
+
95
+ external write :
96
+ Context .t -> buffer -> t -> unit = " ml_secp256k1_ec_pubkey_serialize"
97
+
98
+ external create :
99
+ Context .t -> buffer -> Secret .t -> unit = " ml_secp256k1_ec_pubkey_create"
100
+
101
+ let of_secret ctx seckey =
102
+ let buf = BA. create length in
103
+ create ctx buf seckey ;
104
+ buf
105
+
106
+ let of_bytes ctx ?(pos =0 ) inbuf =
107
+ let pklen = BA. length inbuf in
108
+ if pos < 0 || pos > pklen - 33 then
109
+ invalid_arg " Public.of_bytes: pos < 0 or pos > buflen - 33" ;
110
+ let inbuf = BA. (sub inbuf pos (length inbuf)) in
111
+ if BA. (length inbuf < 33 ) then
112
+ invalid_arg " Public.of_bytes: input must be at least 33 bytes long" ;
113
+ let outbuf = BA. create length in
114
+ try
115
+ parse ctx outbuf inbuf ;
116
+ Some outbuf
117
+ with _ -> None
118
+
119
+ let of_bytes_exn ctx ?pos buf =
120
+ match of_bytes ctx ?pos buf with
90
121
| None -> failwith " Public.of_bytes_exn"
91
122
| Some pk -> pk
92
123
93
124
let to_bytes ?(compress =true ) ctx t =
94
- to_bytes ctx t compress
125
+ let buf = BA. create (if compress then 33 else 65 ) in
126
+ write ctx buf t ;
127
+ buf
128
+
129
+ let write ?(compress =true ) ctx buf ?(pos =0 ) t =
130
+ let buflen = BA. length buf in
131
+ if pos < 0 || (compress && pos > buflen - 33 ) || pos > buflen - 65 then
132
+ invalid_arg " Public.write: pos < 0 or pos > buflen - (33|65)" ;
133
+ let len = if compress then 33 else 65 in
134
+ let buf = BA. sub buf pos len in
135
+ write ctx buf t
95
136
end
96
137
97
138
module Sign = struct
98
139
type t = buffer
99
140
100
141
let compare = BA. compare
101
142
143
+ let length = 64
144
+
102
145
external parse :
103
- Context .t -> buffer -> bool -> t = " ml_secp256k1_ecdsa_signature_parse"
146
+ Context .t -> buffer -> buffer -> bool -> unit = " ml_secp256k1_ecdsa_signature_parse"
104
147
external serialize :
105
- Context .t -> t -> bool -> buffer = " ml_secp256k1_ecdsa_signature_serialize"
106
-
107
- let to_compact ctx t = serialize ctx t true
108
- let to_der ctx t = serialize ctx t false
109
-
110
- let of_compact ctx buf =
111
- try Some (parse ctx buf true ) with _ -> None
112
-
113
- let of_compact_exn ctx buf =
148
+ Context .t -> buffer -> t -> bool -> int = " ml_secp256k1_ecdsa_signature_serialize"
149
+
150
+ let to_compact ctx t =
151
+ let buf = BA. create length in
152
+ let (_:int ) = serialize ctx buf t true in
153
+ buf
154
+
155
+ let to_der ctx t =
156
+ let buf = BA. create 72 in
157
+ let len = serialize ctx buf t false in
158
+ BA. sub buf 0 len
159
+
160
+ let write compact ctx buf ?(pos =0 ) t =
161
+ let buf = BA. (sub buf pos (length buf)) in
162
+ serialize ctx buf t compact
163
+
164
+ let write_compact = write true
165
+ let write_der = write false
166
+
167
+ let of_compact ctx ?(pos =0 ) inbuf =
168
+ let buflen = BA. length inbuf in
169
+ if pos < 0 || pos > buflen - length then
170
+ invalid_arg " Sign.of_compact: pos < 0 or pos > buflen - 64" ;
171
+ let outbuf = BA. create length in
172
+ try
173
+ parse ctx outbuf (BA. sub inbuf pos length) true ;
174
+ Some outbuf
175
+ with _ -> None
176
+
177
+ let of_compact_exn ctx ?pos buf =
114
178
match of_compact ctx buf with
115
179
| None -> failwith " Sign.of_compact_exn"
116
180
| Some signature -> signature
117
181
118
- let of_der ctx buf =
119
- try Some (parse ctx buf false ) with _ -> None
120
-
121
- let of_der_exn ctx buf =
182
+ let of_der ctx ?(pos =0 ) inbuf =
183
+ let buflen = BA. length inbuf in
184
+ if pos < 0 || pos > buflen - length then
185
+ invalid_arg " Sign.of_der: pos < 0 or pos > buflen - 72" ;
186
+ let buf = BA. create length in
187
+ try
188
+ parse ctx buf BA. (sub inbuf pos (length inbuf)) false ;
189
+ Some buf
190
+ with _ -> None
191
+
192
+ let of_der_exn ctx ?pos buf =
122
193
match of_der ctx buf with
123
194
| None -> failwith " Sign.of_der_exn"
124
195
| Some signature -> signature
125
196
126
197
external sign :
127
- Context .t -> Secret .t -> buffer -> t = " ml_secp256k1_ecdsa_sign"
198
+ Context .t -> buffer -> Secret .t -> buffer -> unit = " ml_secp256k1_ecdsa_sign"
128
199
129
200
external verify :
130
201
Context .t -> Public .t -> buffer -> t -> bool = " ml_secp256k1_ecdsa_verify"
131
202
132
- let sign ctx ~seckey ~msg =
133
- if BA. length msg <> 32 then
134
- invalid_arg " Sign.sign: msg must be 32 bytes long" ;
135
- sign ctx seckey msg
136
-
137
- let verify ctx ~pubkey ~msg ~signature =
138
- if BA. length msg <> 32 then
139
- invalid_arg " Sign.verify: msg must be 32 bytes long" ;
140
- verify ctx pubkey msg signature
203
+ let write_sign ctx ~seckey ~outbuf ?(outpos =0 ) ~inbuf ?(inpos =0 ) () =
204
+ let inbuflen = BA. length inbuf in
205
+ if inpos < 0 || inpos > inbuflen - 32 then
206
+ invalid_arg " Sign.sign: inpos < 0 or inpos > msglen - 32" ;
207
+ let outbuflen = BA. length outbuf in
208
+ if outpos < 0 || outpos > outbuflen - length then
209
+ invalid_arg " Sign.write_sign: outpos < 0 or outpos > outbuf - 64" ;
210
+ sign ctx (BA. sub outbuf outpos length) seckey (BA. sub inbuf inpos 32 )
211
+
212
+ let sign ctx ~seckey ?(pos =0 ) inbuf =
213
+ let buflen = BA. length inbuf in
214
+ if pos < 0 || pos > buflen - 32 then
215
+ invalid_arg " Sign.sign: pos < 0 || pos > msglen - 32" ;
216
+ let outbuf = BA. create length in
217
+ sign ctx outbuf seckey (BA. sub inbuf pos 32 ) ;
218
+ outbuf
219
+
220
+ let verify ctx ~pubkey ~signature ?(pos =0 ) msg =
221
+ let msglen = BA. length msg in
222
+ if pos < 0 || pos > msglen - 32 then
223
+ invalid_arg " Sign.verify: msg must be at least 32 bytes long" ;
224
+ verify ctx pubkey (BA. sub msg pos 32 ) signature
141
225
end
142
226
143
227
module RecoverableSign = struct
144
228
type t = buffer
145
229
230
+ let length = 65
231
+
146
232
let compare = BA. compare
147
233
148
234
external parse :
149
- Context .t -> buffer -> int -> t = " ml_secp256k1_ecdsa_recoverable_signature_parse_compact"
150
-
151
- let of_compact ctx buf recid =
152
- try Some (parse ctx buf recid) with _ -> None
153
-
154
- let of_compact_exn ctx buf recid =
155
- match of_compact ctx buf recid with
235
+ Context .t -> buffer -> buffer -> int -> unit = " ml_secp256k1_ecdsa_recoverable_signature_parse_compact"
236
+
237
+ let of_compact ctx ~recid ?(pos =0 ) inbuf =
238
+ let buflen = BA. length inbuf in
239
+ if pos < 0 || pos > buflen - Sign. length then
240
+ invalid_arg " RecoverableSign.of_compact: pos < 0 or pos > buflen - 64" ;
241
+ let buf = BA. create length in
242
+ try
243
+ parse ctx buf (BA. sub inbuf pos Sign. length) recid ;
244
+ Some buf
245
+ with _ -> None
246
+
247
+ let of_compact_exn ctx ~recid ?pos inbuf =
248
+ match of_compact ctx ~recid ?pos inbuf with
156
249
| None -> failwith " RecoverableSign.of_compact_exn"
157
250
| Some signature -> signature
158
251
159
252
external serialize :
160
- Context .t -> t -> (buffer * int ) = " ml_secp256k1_ecdsa_recoverable_signature_serialize_compact"
253
+ Context .t -> buffer -> t -> int = " ml_secp256k1_ecdsa_recoverable_signature_serialize_compact"
254
+
255
+ let to_compact ctx sign =
256
+ let buf = BA. create 64 in
257
+ let recid = serialize ctx buf sign in
258
+ buf, recid
161
259
162
- let to_compact ctx sign = serialize ctx sign
260
+ let write_compact ctx buf ?(pos =0 ) sign =
261
+ let buflen = BA. length buf in
262
+ if pos < 0 || pos > buflen - Sign. length then
263
+ invalid_arg " RecoverableSign.write_compact: pos < 0 or pos > buflen - 64" ;
264
+ serialize ctx (BA. sub buf pos Sign. length) sign
163
265
164
266
external convert :
165
- Context .t -> t -> Sign .t = " ml_secp256k1_ecdsa_recoverable_signature_convert"
267
+ Context .t -> buffer -> t -> unit = " ml_secp256k1_ecdsa_recoverable_signature_convert"
166
268
167
- let convert ctx sign = convert ctx sign
269
+ let convert ctx sign =
270
+ let buf = BA. create Sign. length in
271
+ convert ctx buf sign ;
272
+ buf
168
273
169
274
external sign :
170
- Context .t -> Secret .t -> buffer -> t = " ml_secp256k1_ecdsa_sign_recoverable"
171
-
172
- let sign ctx ~seckey ~msg =
173
- if BA. length msg <> 32 then
174
- invalid_arg " RecoverableSign.sign: msg must be 32 bytes long" ;
175
- sign ctx seckey msg
275
+ Context .t -> buffer -> Secret .t -> buffer -> unit = " ml_secp256k1_ecdsa_sign_recoverable"
276
+
277
+ let write_sign ctx ~seckey ~outbuf ?(outpos =0 ) ~inbuf ?(inpos =0 ) () =
278
+ let inbuf_len = BA. length inbuf in
279
+ if inpos < 0 || inpos > inbuf_len - 32 then
280
+ invalid_arg " RecoverableSign.write_sign: inpos < 0 or inpos > inbuflen - 32" ;
281
+ let outbuf_len = BA. length outbuf in
282
+ if outpos < 0 || outpos > outbuf_len - length then
283
+ invalid_arg " RecoverableSign.write_sign: outpos < 0 or outpos > outbuflen - 65" ;
284
+ sign ctx (BA. sub outbuf outpos length) seckey (BA. sub inbuf inpos 32 )
285
+
286
+ let sign ctx ~seckey ?(pos =0 ) inbuf =
287
+ let inbuflen = BA. length inbuf in
288
+ if pos < 0 || pos > inbuflen - 32 then
289
+ invalid_arg " RecoverableSign.sign: buf must be at least 32 bytes long" ;
290
+ let outbuf = BA. create length in
291
+ sign ctx outbuf seckey (BA. sub inbuf pos 32 ) ;
292
+ outbuf
176
293
177
294
external recover :
178
- Context .t -> t -> buffer -> Public .t = " ml_secp256k1_ecdsa_recover"
179
-
180
- let recover ctx sign ~msg =
181
- if BA. length msg <> 32 then
182
- invalid_arg " RecoverableSign.recover: msg must be 32 bytes long" ;
183
- recover ctx sign msg
184
-
295
+ Context .t -> buffer -> t -> buffer -> unit = " ml_secp256k1_ecdsa_recover"
296
+
297
+ let recover ctx sign ?(pos =0 ) inbuf =
298
+ let inbuflen = BA. length inbuf in
299
+ if pos < 0 || pos > inbuflen - 32 then
300
+ invalid_arg " RecoverableSign.recover: pos < 0 or pos > msglen - 32" ;
301
+ let buf = BA. create Public. length in
302
+ recover ctx buf sign (BA. sub inbuf pos 32 ) ;
303
+ buf
185
304
end
0 commit comments