primitive.go 13.4 KB
Newer Older
Nadim Kobeissi's avatar
Nadim Kobeissi committed
1 2
/* SPDX-FileCopyrightText: © 2019-2020 Nadim Kobeissi <nadim@symbolic.software>
 * SPDX-License-Identifier: GPL-3.0-only */
Nadim Kobeissi's avatar
Nadim Kobeissi committed
3 4
// 5e88e17b2b330ef227c81153d720b176

5
package vplogic
Nadim Kobeissi's avatar
Nadim Kobeissi committed
6

7 8 9 10
import (
	"fmt"
)

Nadim Kobeissi's avatar
Nadim Kobeissi committed
11
var primitiveCoreSpecs = []PrimitiveCoreSpec{
12
	{
Nadim Kobeissi's avatar
Nadim Kobeissi committed
13
		Name:    "ASSERT",
Nadim Kobeissi's avatar
Nadim Kobeissi committed
14
		Arity:   []int{2},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
15 16 17 18
		Output:  1,
		HasRule: true,
		CoreRule: func(p Primitive) (bool, []Value) {
			v := []Value{{Kind: "primitive", Primitive: p}}
Nadim Kobeissi's avatar
Nadim Kobeissi committed
19
			if valueEquivalentValues(p.Arguments[0], p.Arguments[1], true) {
20
				return true, v
21 22 23
			}
			return false, v
		},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
24 25 26
		Check:      true,
		Injectable: false,
		Explosive:  false,
27 28
	},
	{
Nadim Kobeissi's avatar
Nadim Kobeissi committed
29
		Name:    "CONCAT",
Nadim Kobeissi's avatar
Nadim Kobeissi committed
30
		Arity:   []int{2, 3, 4, 5},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
31 32 33 34
		Output:  1,
		HasRule: false,
		CoreRule: func(p Primitive) (bool, []Value) {
			v := []Value{{Kind: "primitive", Primitive: p}}
35 36
			return false, v
		},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
37 38 39
		Check:      false,
		Injectable: true,
		Explosive:  true,
40 41
	},
	{
Nadim Kobeissi's avatar
Nadim Kobeissi committed
42
		Name:    "SPLIT",
Nadim Kobeissi's avatar
Nadim Kobeissi committed
43
		Arity:   []int{1},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
44 45 46 47 48
		Output:  -1,
		HasRule: true,
		CoreRule: func(p Primitive) (bool, []Value) {
			v := []Value{{Kind: "primitive", Primitive: p}}
			switch p.Arguments[0].Kind {
49 50 51
			case "constant":
				return false, v
			case "primitive":
Nadim Kobeissi's avatar
Nadim Kobeissi committed
52 53
				pp := p.Arguments[0].Primitive
				switch pp.Name {
54
				case "CONCAT":
Nadim Kobeissi's avatar
Nadim Kobeissi committed
55
					return true, pp.Arguments
56 57 58 59 60 61 62
				}
				return false, v
			case "equation":
				return false, v
			}
			return false, v
		},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
63 64 65
		Check:      true,
		Injectable: false,
		Explosive:  false,
66 67
	},
}
Nadim Kobeissi's avatar
Nadim Kobeissi committed
68

Nadim Kobeissi's avatar
Nadim Kobeissi committed
69
var primitiveSpecs = []PrimitiveSpec{
70
	{
Nadim Kobeissi's avatar
Nadim Kobeissi committed
71
		Name:   "PW_HASH",
Nadim Kobeissi's avatar
Nadim Kobeissi committed
72
		Arity:  []int{1, 2, 3, 4, 5},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
73 74 75
		Output: 1,
		Decompose: DecomposeRule{
			HasRule: false,
76
		},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
77 78
		Recompose: RecomposeRule{
			HasRule: false,
79
		},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
80 81
		Rewrite: RewriteRule{
			HasRule: false,
82
		},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
83 84
		Rebuild: RebuildRule{
			HasRule: false,
85
		},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
86 87 88
		Check:           false,
		Injectable:      true,
		Explosive:       false,
89
		PasswordHashing: []int{0, 1, 2, 3, 4},
90
	},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
91
	{
Nadim Kobeissi's avatar
Nadim Kobeissi committed
92
		Name:   "HASH",
Nadim Kobeissi's avatar
Nadim Kobeissi committed
93
		Arity:  []int{1, 2, 3, 4, 5},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
94 95 96
		Output: 1,
		Decompose: DecomposeRule{
			HasRule: false,
Nadim Kobeissi's avatar
Nadim Kobeissi committed
97
		},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
98 99
		Recompose: RecomposeRule{
			HasRule: false,
100
		},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
101 102
		Rewrite: RewriteRule{
			HasRule: false,
Nadim Kobeissi's avatar
Nadim Kobeissi committed
103
		},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
104 105
		Rebuild: RebuildRule{
			HasRule: false,
106
		},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
107 108 109
		Check:           false,
		Injectable:      true,
		Explosive:       true,
110
		PasswordHashing: []int{},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
111 112
	},
	{
Nadim Kobeissi's avatar
Nadim Kobeissi committed
113
		Name:   "HKDF",
Nadim Kobeissi's avatar
Nadim Kobeissi committed
114
		Arity:  []int{3},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
115 116 117
		Output: -1,
		Decompose: DecomposeRule{
			HasRule: false,
Nadim Kobeissi's avatar
Nadim Kobeissi committed
118
		},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
119 120
		Recompose: RecomposeRule{
			HasRule: false,
121
		},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
122 123
		Rewrite: RewriteRule{
			HasRule: false,
Nadim Kobeissi's avatar
Nadim Kobeissi committed
124
		},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
125 126
		Rebuild: RebuildRule{
			HasRule: false,
127
		},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
128 129 130
		Check:           false,
		Injectable:      true,
		Explosive:       true,
131
		PasswordHashing: []int{},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
132 133
	},
	{
Nadim Kobeissi's avatar
Nadim Kobeissi committed
134
		Name:   "AEAD_ENC",
Nadim Kobeissi's avatar
Nadim Kobeissi committed
135
		Arity:  []int{3},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
136 137 138 139 140
		Output: 1,
		Decompose: DecomposeRule{
			HasRule: true,
			Given:   []int{0},
			Reveal:  1,
141
			Filter: func(p Primitive, x Value, i int) (Value, bool) {
142 143
				return x, true
			},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
144
		},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
145 146
		Recompose: RecomposeRule{
			HasRule: false,
147
		},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
148 149
		Rewrite: RewriteRule{
			HasRule: false,
Nadim Kobeissi's avatar
Nadim Kobeissi committed
150
		},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
151 152
		Rebuild: RebuildRule{
			HasRule: false,
153
		},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
154 155 156
		Check:           false,
		Injectable:      true,
		Explosive:       false,
157
		PasswordHashing: []int{1},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
158 159
	},
	{
Nadim Kobeissi's avatar
Nadim Kobeissi committed
160
		Name:   "AEAD_DEC",
Nadim Kobeissi's avatar
Nadim Kobeissi committed
161
		Arity:  []int{3},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
162 163 164 165 166
		Output: 1,
		Decompose: DecomposeRule{
			HasRule: true,
			Given:   []int{0},
			Reveal:  1,
167
			Filter: func(p Primitive, x Value, i int) (Value, bool) {
168 169
				return x, true
			},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
170
		},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
171 172
		Recompose: RecomposeRule{
			HasRule: false,
173
		},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
174 175 176 177
		Rewrite: RewriteRule{
			HasRule: true,
			Name:    "AEAD_ENC",
			From:    1,
178 179 180
			To: func(p Primitive) Value {
				return p.Arguments[1]
			},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
181
			Matching: map[int][]int{
182 183 184
				0: {0},
				2: {2},
			},
185
			Filter: func(p Primitive, x Value, i int) (Value, bool) {
Nadim Kobeissi's avatar
Nadim Kobeissi committed
186 187 188 189 190 191 192 193 194
				switch i {
				case 0:
					return x, true
				case 2:
					return x, true
				}
				return x, false
			},
		},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
195 196
		Rebuild: RebuildRule{
			HasRule: false,
197
		},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
198 199 200
		Check:           true,
		Injectable:      false,
		Explosive:       false,
201
		PasswordHashing: []int{},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
202 203
	},
	{
Nadim Kobeissi's avatar
Nadim Kobeissi committed
204
		Name:   "ENC",
Nadim Kobeissi's avatar
Nadim Kobeissi committed
205
		Arity:  []int{2},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
206 207 208 209 210
		Output: 1,
		Decompose: DecomposeRule{
			HasRule: true,
			Given:   []int{0},
			Reveal:  1,
211
			Filter: func(p Primitive, x Value, i int) (Value, bool) {
212 213
				return x, true
			},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
214
		},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
215 216
		Recompose: RecomposeRule{
			HasRule: false,
217
		},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
218 219
		Rewrite: RewriteRule{
			HasRule: false,
Nadim Kobeissi's avatar
Nadim Kobeissi committed
220
		},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
221 222
		Rebuild: RebuildRule{
			HasRule: false,
223
		},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
224 225 226
		Check:           false,
		Injectable:      true,
		Explosive:       false,
227
		PasswordHashing: []int{1},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
228 229
	},
	{
Nadim Kobeissi's avatar
Nadim Kobeissi committed
230
		Name:   "DEC",
Nadim Kobeissi's avatar
Nadim Kobeissi committed
231
		Arity:  []int{2},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
232 233 234 235 236
		Output: 1,
		Decompose: DecomposeRule{
			HasRule: true,
			Given:   []int{0},
			Reveal:  1,
237
			Filter: func(p Primitive, x Value, i int) (Value, bool) {
238 239
				return x, true
			},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
240
		},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
241 242
		Recompose: RecomposeRule{
			HasRule: false,
243
		},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
244 245 246 247
		Rewrite: RewriteRule{
			HasRule: true,
			Name:    "ENC",
			From:    1,
248 249 250
			To: func(p Primitive) Value {
				return p.Arguments[1]
			},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
251
			Matching: map[int][]int{
252 253
				0: {0},
			},
254
			Filter: func(p Primitive, x Value, i int) (Value, bool) {
Nadim Kobeissi's avatar
Nadim Kobeissi committed
255 256 257 258 259 260 261
				switch i {
				case 0:
					return x, true
				}
				return x, false
			},
		},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
262 263
		Rebuild: RebuildRule{
			HasRule: false,
264
		},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
265 266 267
		Check:           false,
		Injectable:      false,
		Explosive:       false,
268
		PasswordHashing: []int{},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
269 270
	},
	{
Nadim Kobeissi's avatar
Nadim Kobeissi committed
271
		Name:   "MAC",
Nadim Kobeissi's avatar
Nadim Kobeissi committed
272
		Arity:  []int{2},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
273 274 275
		Output: 1,
		Decompose: DecomposeRule{
			HasRule: false,
Nadim Kobeissi's avatar
Nadim Kobeissi committed
276
		},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
277 278
		Recompose: RecomposeRule{
			HasRule: false,
279
		},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
280 281
		Rewrite: RewriteRule{
			HasRule: false,
Nadim Kobeissi's avatar
Nadim Kobeissi committed
282
		},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
283 284
		Rebuild: RebuildRule{
			HasRule: false,
285
		},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
286 287 288
		Check:           false,
		Injectable:      true,
		Explosive:       false,
289
		PasswordHashing: []int{1},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
290 291
	},
	{
Nadim Kobeissi's avatar
Nadim Kobeissi committed
292
		Name:   "SIGN",
Nadim Kobeissi's avatar
Nadim Kobeissi committed
293
		Arity:  []int{2},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
294 295 296
		Output: 1,
		Decompose: DecomposeRule{
			HasRule: false,
Nadim Kobeissi's avatar
Nadim Kobeissi committed
297
		},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
298 299
		Recompose: RecomposeRule{
			HasRule: false,
300
		},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
301 302
		Rewrite: RewriteRule{
			HasRule: false,
Nadim Kobeissi's avatar
Nadim Kobeissi committed
303
		},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
304 305
		Rebuild: RebuildRule{
			HasRule: false,
306
		},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
307 308 309
		Check:           false,
		Injectable:      true,
		Explosive:       false,
310
		PasswordHashing: []int{1},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
311 312
	},
	{
Nadim Kobeissi's avatar
Nadim Kobeissi committed
313
		Name:   "SIGNVERIF",
Nadim Kobeissi's avatar
Nadim Kobeissi committed
314
		Arity:  []int{3},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
315 316 317 318 319 320 321 322 323 324 325
		Output: 1,
		Decompose: DecomposeRule{
			HasRule: false,
		},
		Recompose: RecomposeRule{
			HasRule: false,
		},
		Rewrite: RewriteRule{
			HasRule: true,
			Name:    "SIGN",
			From:    2,
326
			To: func(p Primitive) Value {
Nadim Kobeissi's avatar
Nadim Kobeissi committed
327
				return valueN
328
			},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
329
			Matching: map[int][]int{
330 331 332
				0: {0},
				1: {1},
			},
333
			Filter: func(p Primitive, x Value, i int) (Value, bool) {
Nadim Kobeissi's avatar
Nadim Kobeissi committed
334 335
				switch i {
				case 0:
Nadim Kobeissi's avatar
Nadim Kobeissi committed
336
					switch x.Kind {
Nadim Kobeissi's avatar
Nadim Kobeissi committed
337 338 339 340 341
					case "constant":
						return x, false
					case "primitive":
						return x, false
					case "equation":
Nadim Kobeissi's avatar
Nadim Kobeissi committed
342
						switch len(x.Equation.Values) {
343
						case 2:
Nadim Kobeissi's avatar
Nadim Kobeissi committed
344
							return x.Equation.Values[1], true
345 346
						default:
							return x, false
Nadim Kobeissi's avatar
Nadim Kobeissi committed
347 348 349 350 351 352 353 354
						}
					}
				case 1:
					return x, true
				}
				return x, false
			},
		},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
355 356
		Rebuild: RebuildRule{
			HasRule: false,
357
		},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
358 359 360
		Check:           true,
		Injectable:      false,
		Explosive:       false,
361
		PasswordHashing: []int{},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
362
	},
363
	{
Nadim Kobeissi's avatar
Nadim Kobeissi committed
364
		Name:   "PKE_ENC",
Nadim Kobeissi's avatar
Nadim Kobeissi committed
365
		Arity:  []int{2},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
366 367 368 369 370
		Output: 1,
		Decompose: DecomposeRule{
			HasRule: true,
			Given:   []int{0},
			Reveal:  1,
371
			Filter: func(p Primitive, x Value, i int) (Value, bool) {
372 373
				switch i {
				case 0:
Nadim Kobeissi's avatar
Nadim Kobeissi committed
374
					switch x.Kind {
375 376 377 378 379
					case "constant":
						return x, false
					case "primitive":
						return x, false
					case "equation":
Nadim Kobeissi's avatar
Nadim Kobeissi committed
380 381
						if len(x.Equation.Values) == 2 {
							return x.Equation.Values[1], true
382 383 384 385 386 387 388 389 390
						}
						return x, false
					}
				case 1:
					return x, true
				}
				return x, false
			},
		},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
391 392
		Recompose: RecomposeRule{
			HasRule: false,
393
		},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
394 395
		Rewrite: RewriteRule{
			HasRule: false,
396
		},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
397 398
		Rebuild: RebuildRule{
			HasRule: false,
399
		},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
400 401 402
		Check:           false,
		Injectable:      true,
		Explosive:       false,
403
		PasswordHashing: []int{1},
404 405
	},
	{
Nadim Kobeissi's avatar
Nadim Kobeissi committed
406
		Name:   "PKE_DEC",
Nadim Kobeissi's avatar
Nadim Kobeissi committed
407
		Arity:  []int{2},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
408 409 410 411 412
		Output: 1,
		Decompose: DecomposeRule{
			HasRule: true,
			Given:   []int{0},
			Reveal:  1,
413
			Filter: func(p Primitive, x Value, i int) (Value, bool) {
414 415 416
				return x, true
			},
		},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
417 418
		Recompose: RecomposeRule{
			HasRule: false,
419
		},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
420 421 422 423
		Rewrite: RewriteRule{
			HasRule: true,
			Name:    "PKE_ENC",
			From:    1,
424 425 426
			To: func(p Primitive) Value {
				return p.Arguments[1]
			},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
427
			Matching: map[int][]int{
428 429
				0: {0},
			},
430
			Filter: func(p Primitive, x Value, i int) (Value, bool) {
431 432
				switch i {
				case 0:
Nadim Kobeissi's avatar
Nadim Kobeissi committed
433
					switch x.Kind {
434
					case "constant", "primitive":
Nadim Kobeissi's avatar
Nadim Kobeissi committed
435 436 437
						return Value{
							Kind: "equation",
							Equation: Equation{
Nadim Kobeissi's avatar
Nadim Kobeissi committed
438
								Values: []Value{valueG, x},
439 440 441 442 443 444 445 446 447
							},
						}, true
					case "equation":
						return x, false
					}
				}
				return x, false
			},
		},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
448 449
		Rebuild: RebuildRule{
			HasRule: false,
450
		},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
451 452 453
		Check:           false,
		Injectable:      false,
		Explosive:       false,
454
		PasswordHashing: []int{},
455 456
	},
	{
Nadim Kobeissi's avatar
Nadim Kobeissi committed
457
		Name:   "SHAMIR_SPLIT",
Nadim Kobeissi's avatar
Nadim Kobeissi committed
458
		Arity:  []int{1},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
459 460 461 462 463 464 465
		Output: 3,
		Decompose: DecomposeRule{
			HasRule: false,
		},
		Recompose: RecomposeRule{
			HasRule: true,
			Given: [][]int{
Nadim Kobeissi's avatar
Nadim Kobeissi committed
466 467 468
				{0, 1},
				{0, 2},
				{1, 2},
469
			},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
470
			Reveal: 0,
471
			Filter: func(p Primitive, x Value, i int) (Value, bool) {
472 473 474
				return x, true
			},
		},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
475 476
		Rewrite: RewriteRule{
			HasRule: false,
477
		},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
478 479
		Rebuild: RebuildRule{
			HasRule: false,
480
		},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
481 482 483
		Check:           false,
		Injectable:      false,
		Explosive:       false,
484
		PasswordHashing: []int{},
485 486
	},
	{
Nadim Kobeissi's avatar
Nadim Kobeissi committed
487
		Name:   "SHAMIR_JOIN",
Nadim Kobeissi's avatar
Nadim Kobeissi committed
488
		Arity:  []int{2},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
489 490 491 492 493 494 495 496 497 498 499 500 501 502
		Output: 1,
		Decompose: DecomposeRule{
			HasRule: false,
		},
		Recompose: RecomposeRule{
			HasRule: false,
		},
		Rewrite: RewriteRule{
			HasRule: false,
		},
		Rebuild: RebuildRule{
			HasRule: true,
			Name:    "SHAMIR_SPLIT",
			Given: [][]int{
Nadim Kobeissi's avatar
Nadim Kobeissi committed
503 504 505 506 507 508
				{0, 1},
				{1, 0},
				{0, 2},
				{2, 0},
				{1, 2},
				{2, 1},
509
			},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
510
			Reveal: 0,
511
			Filter: func(p Primitive, x Value, i int) (Value, bool) {
512 513 514
				return x, true
			},
		},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
515 516 517
		Check:           false,
		Injectable:      false,
		Explosive:       false,
518
		PasswordHashing: []int{},
519
	},
520
	{
Nadim Kobeissi's avatar
Nadim Kobeissi committed
521
		Name:   "RINGSIGN",
Nadim Kobeissi's avatar
Nadim Kobeissi committed
522
		Arity:  []int{4},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
523 524 525
		Output: 1,
		Decompose: DecomposeRule{
			HasRule: false,
526
		},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
527 528
		Recompose: RecomposeRule{
			HasRule: false,
529
		},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
530 531
		Rewrite: RewriteRule{
			HasRule: false,
532
		},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
533 534
		Rebuild: RebuildRule{
			HasRule: false,
535
		},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
536 537 538
		Check:           false,
		Injectable:      true,
		Explosive:       false,
539
		PasswordHashing: []int{3},
540 541
	},
	{
Nadim Kobeissi's avatar
Nadim Kobeissi committed
542
		Name:   "RINGSIGNVERIF",
Nadim Kobeissi's avatar
Nadim Kobeissi committed
543
		Arity:  []int{5},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
544 545 546 547 548 549 550 551 552 553 554
		Output: 1,
		Decompose: DecomposeRule{
			HasRule: false,
		},
		Recompose: RecomposeRule{
			HasRule: false,
		},
		Rewrite: RewriteRule{
			HasRule: true,
			Name:    "RINGSIGN",
			From:    4,
555
			To: func(p Primitive) Value {
Nadim Kobeissi's avatar
Nadim Kobeissi committed
556
				return valueN
557
			},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
558
			Matching: map[int][]int{
559 560 561 562 563
				0: {0, 1, 2},
				1: {0, 1, 2},
				2: {0, 1, 2},
				3: {3},
			},
564
			Filter: func(p Primitive, x Value, i int) (Value, bool) {
565 566
				switch i {
				case 0:
Nadim Kobeissi's avatar
Nadim Kobeissi committed
567
					switch x.Kind {
568 569 570 571 572
					case "constant":
						return x, false
					case "primitive":
						return x, false
					case "equation":
Nadim Kobeissi's avatar
Nadim Kobeissi committed
573
						switch len(x.Equation.Values) {
574
						case 2:
Nadim Kobeissi's avatar
Nadim Kobeissi committed
575
							return x.Equation.Values[1], true
576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591
						default:
							return x, false
						}
					}
				case 1:
					return x, true
				case 2:
					return x, true
				case 3:
					return x, true
				case 4:
					return x, true
				}
				return x, false
			},
		},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
592 593
		Rebuild: RebuildRule{
			HasRule: false,
594
		},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
595 596 597
		Check:           true,
		Injectable:      false,
		Explosive:       false,
598
		PasswordHashing: []int{},
599
	},
600 601
	{
		Name:   "BLIND",
Nadim Kobeissi's avatar
Nadim Kobeissi committed
602
		Arity:  []int{2},
603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623
		Output: 1,
		Decompose: DecomposeRule{
			HasRule: true,
			Given:   []int{0},
			Reveal:  1,
			Filter: func(p Primitive, x Value, i int) (Value, bool) {
				return x, true
			},
		},
		Recompose: RecomposeRule{
			HasRule: false,
		},
		Rewrite: RewriteRule{
			HasRule: false,
		},
		Rebuild: RebuildRule{
			HasRule: false,
		},
		Check:           false,
		Injectable:      true,
		Explosive:       false,
624
		PasswordHashing: []int{1},
625 626 627
	},
	{
		Name:   "UNBLIND",
Nadim Kobeissi's avatar
Nadim Kobeissi committed
628
		Arity:  []int{3},
629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681
		Output: 1,
		Decompose: DecomposeRule{
			HasRule: false,
		},
		Recompose: RecomposeRule{
			HasRule: false,
		},
		Rewrite: RewriteRule{
			HasRule: true,
			Name:    "SIGN",
			From:    2,
			To: func(p Primitive) Value {
				return Value{
					Kind: "primitive",
					Primitive: Primitive{
						Name: "SIGN",
						Arguments: []Value{
							p.Arguments[0],
							p.Arguments[1].Primitive.Arguments[1],
						},
						Output: 0,
						Check:  false,
					},
				}
			},
			Matching: map[int][]int{
				0: {1},
			},
			Filter: func(p Primitive, x Value, i int) (Value, bool) {
				switch i {
				case 1:
					blindPrim := Value{
						Kind: "primitive",
						Primitive: Primitive{
							Name: "BLIND",
							Arguments: []Value{
								p.Arguments[0], p.Arguments[1],
							},
							Output: 0,
							Check:  false,
						},
					}
					return blindPrim, true
				}
				return x, false
			},
		},
		Rebuild: RebuildRule{
			HasRule: false,
		},
		Check:           false,
		Injectable:      true,
		Explosive:       false,
682
		PasswordHashing: []int{},
683
	},
Nadim Kobeissi's avatar
Nadim Kobeissi committed
684 685
}

686 687 688 689 690 691 692 693
func primitiveIsCorePrim(name string) bool {
	switch name {
	case "ASSERT", "CONCAT", "SPLIT":
		return true
	}
	return false
}

Nadim Kobeissi's avatar
Nadim Kobeissi committed
694
func primitiveCoreGet(name string) (PrimitiveCoreSpec, error) {
695
	for _, v := range primitiveCoreSpecs {
Nadim Kobeissi's avatar
Nadim Kobeissi committed
696
		if v.Name == name {
697 698 699 700
			return v, nil
		}
	}
	err := fmt.Errorf("unknown primitive (%s)", name)
Nadim Kobeissi's avatar
Nadim Kobeissi committed
701
	return PrimitiveCoreSpec{}, err
702 703
}

Nadim Kobeissi's avatar
Nadim Kobeissi committed
704
func primitiveGet(name string) (PrimitiveSpec, error) {
Nadim Kobeissi's avatar
Nadim Kobeissi committed
705
	for _, v := range primitiveSpecs {
Nadim Kobeissi's avatar
Nadim Kobeissi committed
706
		if v.Name == name {
707
			return v, nil
Nadim Kobeissi's avatar
Nadim Kobeissi committed
708 709
		}
	}
710
	err := fmt.Errorf("unknown primitive (%s)", name)
Nadim Kobeissi's avatar
Nadim Kobeissi committed
711
	return PrimitiveSpec{}, err
Nadim Kobeissi's avatar
Nadim Kobeissi committed
712
}
Nadim Kobeissi's avatar
Nadim Kobeissi committed
713 714 715 716 717 718 719 720 721 722 723 724 725 726 727

func primitiveGetArity(p Primitive) ([]int, error) {
	if primitiveIsCorePrim(p.Name) {
		prim, err := primitiveCoreGet(p.Name)
		if err != nil {
			return []int{}, err
		}
		return prim.Arity, nil
	}
	prim, err := primitiveGet(p.Name)
	if err != nil {
		return []int{}, err
	}
	return prim.Arity, nil
}