/
main_N.circom.template
73 lines (64 loc) · 2.55 KB
/
main_N.circom.template
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
pragma circom 2.0.0;
include "aes.circom";
include "bitify.circom";
include "key_shares.circom";
template Main(maxBlocksToReveal) {
var keyLength = 16;
var hashLength = 32;
var nonceLength = 12;
var ciphertextlen = maxBlocksToReveal*16;
signal input ciphertext[ciphertextlen];
signal input client_key_share[keyLength];
signal input client_key_share_commitment[hashLength];
signal input notary_key_share[keyLength];
signal input nonce[nonceLength];
signal input starting_aes_block;
signal input bytes_to_reveal[ciphertextlen];
signal output plaintext[ciphertextlen];
component aes = aes(ciphertextlen, keyLength*8);
component Num2BitsCiphertext[ciphertextlen];
for (var i = 0; i < ciphertextlen; i++) {
Num2BitsCiphertext[i] = Num2Bits(8);
Num2BitsCiphertext[i].in <== ciphertext[i];
for (var j = 0; j < 8; j++) {
aes.ciphertext[i][j] <== Num2BitsCiphertext[i].out[7 - j];
}
}
component keyCommitment = CheckKeySharesCommitment();
for (var i = 0; i < keyLength; i++) {
keyCommitment.client_key_share[i] <== client_key_share[i];
keyCommitment.notary_key_share[i] <== notary_key_share[i];
}
for (var i = 0; i < hashLength; i++) {
keyCommitment.hash[i] <== client_key_share_commitment[i];
}
for (var i = 0; i < keyLength; i++) {
for (var j = 0; j < 8; j++) {
aes.key[8*i + j] <== keyCommitment.out[i][7 - j];
}
}
for (var i = 0; i < 12; i++) {
aes.nonce[i] <== nonce[i];
}
aes.starting_aes_block <== starting_aes_block;
// Converting back to bytes and revealing only those bytes as noted in bytes_to_reveal
signal totalPlaintext[ciphertextlen];
component Bits2Num[ciphertextlen];
component SelectPlaintextToReveal[ciphertextlen];
for (var i = 0; i < ciphertextlen; i++) {
Bits2Num[i] = Bits2Num(8);
for (var k = 0; k < 8; k++) {
Bits2Num[i].in[7 - k] <== aes.plaintext[i][k];
}
totalPlaintext[i] <== Bits2Num[i].out;
SelectPlaintextToReveal[i] = select2();
SelectPlaintextToReveal[i].values[1] <== 0;
SelectPlaintextToReveal[i].values[0] <== totalPlaintext[i];
SelectPlaintextToReveal[i].bits[0] <== bytes_to_reveal[i];
plaintext[i] <== SelectPlaintextToReveal[i].out;
log(plaintext[i]);
}
}
// NOTE: a requirement for succesful proof creation/validation is that all output variables are set (and potentially tested)
// NOTE: according to DECO nonce/IV is public (see appendix B.2)
component main {public [ ciphertext, client_key_share, client_key_share_commitment, nonce, starting_aes_block, bytes_to_reveal ]} = Main(NUMBER_OF_AES_BLOCKS_HERE);