-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathChallInstParser.py
executable file
·146 lines (118 loc) · 4.69 KB
/
ChallInstParser.py
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
142
143
144
145
146
#!/usr/bin/python
# Parses RLWE challenge/instance files:
# takes the path to a .challenge file first, and an optional second path to a
# corresponding .instance file. Prints the contents of the .challenge file
# and the .instance file, if a path is provided.
# See the code for examples of how to access message contents.
#
# You will need the "protobuf" python package to run this code, which you can
# install with "easy_install protobuf"
# You can find more detailed information about parsing messages in python here:
# https://developers.google.com/protocol-buffers/docs/reference/python-generated
import sys
import Challenges_pb2
import math
def parse_challenge(challenge_path):
if challenge_path is None:
return
challenge = None
with open(challenge_path) as f:
challenge = Challenges_pb2.Challenge()
challenge.ParseFromString(f.read())
return challenge
def parse_instance(challenge, instance_path):
if challenge is None or instance_path is None:
return
instance = None
with open(instance_path) as f:
paramType = challenge.WhichOneof("params")
if paramType == "cparams":
instance = Challenges_pb2.InstanceCont()
elif paramType == "dparams":
instance = Challenges_pb2.InstanceDisc()
elif paramType == "rparams":
instance = Challenges_pb2.InstanceRLWR()
else:
return
instance.ParseFromString(f.read())
return instance
def parse_secret(secret_path):
if secret_path is None:
return
secret = None
with open(secret_path) as f:
secret = Challenges_pb2.Secret()
secret.ParseFromString(f.read())
return secret
def reverseBits(num, bitSize):
# convert number into binary representation
# output will be like bin(10) = '0b10101'
binary = bin(num)
# skip first two characters of binary
# representation string and reverse
# remaining string and then append zeros
# after it. binary[-1:1:-1] --> start
# from last character and reverse it until
# second last character from left
reverse = binary[-1:1:-1]
reverse = reverse + (bitSize - len(reverse)) * '0'
# converts reversed binary string into integer
# print int(reverse,2)
return int(reverse, 2)
def adjust_index(x):
res = [0 for _ in range(len(x))]
bitSize = int(math.log(len(x), 2))
for i in range(len(x)):
res[reverseBits(i, bitSize)] = x[i]
return res
def get_challenge(challenge_path, instance_path, secret_path):
challenge = parse_challenge(challenge_path)
if challenge is None:
print "Could not parse the challenge parameters."
sys.exit(-1)
print challenge # print all contents
# examples of how to access message contents
# number of instances in the challenge
#print challenge.numInstances
# shows which type of parameter the message contains
#print challenge.WhichOneof("params")
# cyclotomic index of a challenge
#print {'cparams': challenge.cparams.m,
# # number of samples in each instance
# 'dparams': challenge.dparams.numSamples,
# # input modulus of the RLWR challenge
# 'rparams': challenge.rparams.q}[challenge.WhichOneof("params")]
secret = parse_secret(secret_path)
if secret is None:
print "Could not parse secret."
sys.exit(-1)
else:
s = adjust_index(secret.s.xs[0:])
#print secret # print all contents
# it's easy to access any member of the parsed message
#print secret.s.xs[0] # first decoding basis coefficient of the secret
A = []
B = []
instance = parse_instance(challenge, instance_path)
if instance is None:
print "Could not parse instance."
sys.exit(-1)
# print instance # print all contents
# it is easy to access any member of the parsed message
# each instance has many samples (print something from the first sample)
# each sample is a pair (a,b=a*s+e) (print something in the ring element 'a')
# each ring element is represented as a list of coefficients with resepct to
# the decoding basis. (print the first coefficient)
# print instance.samples[0].a.xs[0]
# print "See source code in ChallInstParser.py for examples of how to access specific message members."
for i in range(challenge.dparams.numSamples):
a = adjust_index(instance.samples[i].a.xs[0:])
b = adjust_index(instance.samples[i].b.xs[0:])
A.append(a)
B.append(b)
challID = challenge.challengeID
n = challenge.dparams.m / 2
q = challenge.dparams.q
svar = challenge.dparams.svar
numSample = challenge.dparams.numSamples
return [challID,A, B, s, n, q, svar, numSample]