diff --git a/tools/build_mocks b/tools/build_mocks index f0c5ddf5c2..4c064a2e85 100755 --- a/tools/build_mocks +++ b/tools/build_mocks @@ -6,6 +6,7 @@ COMMENT_PREFIX = '/// ' current_method = None current_package = None + def split_to_parts(line, mod_desc=None): global current_method global current_package @@ -23,6 +24,7 @@ def split_to_parts(line, mod_desc=None): yield (current_package, line) + def store_to_file(dest, parts): while True: try: @@ -42,6 +44,7 @@ def store_to_file(dest, parts): f.write(line) f.close() + def build_module(mod_file, dest): if not (mod_file.endswith('.h') or mod_file.endswith('.c')): return @@ -51,15 +54,17 @@ def build_module(mod_file, dest): if not l.startswith(COMMENT_PREFIX): continue - l = l[len(COMMENT_PREFIX):]#.strip() + l = l[len(COMMENT_PREFIX):] # .strip() store_to_file(dest, split_to_parts(l, mod_desc)) + def build_directory(dir, dest): print("Building mocks for", dir, "to", dest) for pkg in os.listdir(dir): for mod in os.listdir(os.path.join(dir, pkg)): build_module(os.path.join(dir, pkg, mod), dest) + def clear_directory(top_dir): print("Clearing up directory", top_dir) for root, dirs, files in os.walk(top_dir, topdown=False): diff --git a/tools/build_vendorheader b/tools/build_vendorheader index 1eddb7435c..3d80e02e99 100755 --- a/tools/build_vendorheader +++ b/tools/build_vendorheader @@ -4,17 +4,21 @@ import struct import binascii # encode vendor name, add length byte and padding to multiple of 4 + + def encode_vendor(vname): vbin = vname.encode('utf-8') vbin = struct.pack('>1,m)**2 % m - if e & 1: t = (t*b) % m - return t +def H(m): + return hashlib.sha512(m).digest() + + +def expmod(b, e, m): + if e < 0: + raise Exception("negative exponent") + if e == 0: + return 1 + t = expmod(b, e >> 1, m)**2 % m + if e & 1: + t = (t * b) % m + return t + def inv(x): - return expmod(x,q-2,q) + return expmod(x, q - 2, q) d = -121665 * inv(121666) -I = expmod(2,(q-1)>>2,q) +I = expmod(2, (q - 1) >> 2, q) + def xrecover(y): - xx = (y*y-1) * inv(d*y*y+1) - x = expmod(xx,(q+3)>>3,q) - if (x*x - xx) % q != 0: x = (x*I) % q - if x % 2 != 0: x = q-x - return x + xx = (y * y - 1) * inv(d * y * y + 1) + x = expmod(xx, (q + 3) >> 3, q) + if (x * x - xx) % q != 0: + x = (x * I) % q + if x % 2 != 0: + x = q - x + return x By = 4 * inv(5) Bx = xrecover(By) -B = [Bx % q,By % q] +B = [Bx % q, By % q] -def edwards(P,Q): - x1 = P[0] - y1 = P[1] - x2 = Q[0] - y2 = Q[1] - x3 = (x1*y2+x2*y1) * inv(1+d*x1*x2*y1*y2) - y3 = (y1*y2+x1*x2) * inv(1-d*x1*x2*y1*y2) - return [x3 % q,y3 % q] -def scalarmult(P,e): - if e == 0: return [0,1] - Q = scalarmult(P,e>>1) - Q = edwards(Q,Q) - if e & 1: Q = edwards(Q,P) - return Q +def edwards(P, Q): + x1 = P[0] + y1 = P[1] + x2 = Q[0] + y2 = Q[1] + x3 = (x1 * y2 + x2 * y1) * inv(1 + d * x1 * x2 * y1 * y2) + y3 = (y1 * y2 + x1 * x2) * inv(1 - d * x1 * x2 * y1 * y2) + return [x3 % q, y3 % q] + + +def scalarmult(P, e): + if e == 0: + return [0, 1] + Q = scalarmult(P, e >> 1) + Q = edwards(Q, Q) + if e & 1: + Q = edwards(Q, P) + return Q + def encodeint(y): - bits = [(y >> i) & 1 for i in range(b)] - return bytes([sum([bits[i * 8 + j] << j for j in range(8)]) for i in range(b>>3)]) + bits = [(y >> i) & 1 for i in range(b)] + return bytes([sum([bits[i * 8 + j] << j for j in range(8)]) for i in range(b >> 3)]) + def encodepoint(P): - x = P[0] - y = P[1] - bits = [(y >> i) & 1 for i in range(b - 1)] + [x & 1] - return bytes([sum([bits[i * 8 + j] << j for j in range(8)]) for i in range(b>>3)]) + x = P[0] + y = P[1] + bits = [(y >> i) & 1 for i in range(b - 1)] + [x & 1] + return bytes([sum([bits[i * 8 + j] << j for j in range(8)]) for i in range(b >> 3)]) + + +def bit(h, i): + return (h[i >> 3] >> (i & 7)) & 1 -def bit(h,i): - return (h[i>>3] >> (i&7)) & 1 def publickey(sk): - h = H(sk) - a = 2**(b-2) + sum(2**i * bit(h,i) for i in range(3,b-2)) - A = scalarmult(B,a) - return encodepoint(A) + h = H(sk) + a = 2**(b - 2) + sum(2**i * bit(h, i) for i in range(3, b - 2)) + A = scalarmult(B, a) + return encodepoint(A) + def Hint(m): - h = H(m) - return sum(2**i * bit(h,i) for i in range(2*b)) + h = H(m) + return sum(2**i * bit(h, i) for i in range(2 * b)) + + +def signature(m, sk, pk): + h = H(sk) + a = 2**(b - 2) + sum(2**i * bit(h, i) for i in range(3, b - 2)) + r = Hint(bytes([h[i] for i in range(b >> 3, b >> 2)]) + m) + R = scalarmult(B, r) + S = (r + Hint(encodepoint(R) + pk + m) * a) % l + return encodepoint(R) + encodeint(S) -def signature(m,sk,pk): - h = H(sk) - a = 2**(b-2) + sum(2**i * bit(h,i) for i in range(3,b-2)) - r = Hint(bytes([h[i] for i in range(b>>3,b>>2)]) + m) - R = scalarmult(B,r) - S = (r + Hint(encodepoint(R) + pk + m) * a) % l - return encodepoint(R) + encodeint(S) def isoncurve(P): - x = P[0] - y = P[1] - return (-x*x + y*y - 1 - d*x*x*y*y) % q == 0 + x = P[0] + y = P[1] + return (-x * x + y * y - 1 - d * x * x * y * y) % q == 0 + def decodeint(s): - return sum(2**i * bit(s,i) for i in range(0,b)) + return sum(2**i * bit(s, i) for i in range(0, b)) + def decodepoint(s): - y = sum(2**i * bit(s,i) for i in range(0,b-1)) - x = xrecover(y) - if x & 1 != bit(s,b-1): x = q-x - P = [x,y] - if not isoncurve(P): raise Exception("decoding point that is not on curve") - return P + y = sum(2**i * bit(s, i) for i in range(0, b - 1)) + x = xrecover(y) + if x & 1 != bit(s, b - 1): + x = q - x + P = [x, y] + if not isoncurve(P): + raise Exception("decoding point that is not on curve") + return P -def checkvalid(s,m,pk): - if len(s) != b>>2: raise Exception("signature length is wrong") - if len(pk) != b>>3: raise Exception("public-key length is wrong") - R = decodepoint(s[0:b>>3]) - A = decodepoint(pk) - S = decodeint(s[b>>3:b>>2]) - h = Hint(encodepoint(R) + pk + m) - if scalarmult(B,S) != edwards(R,scalarmult(A,h)): - raise Exception("signature does not pass verification") + +def checkvalid(s, m, pk): + if len(s) != b >> 2: + raise Exception("signature length is wrong") + if len(pk) != b >> 3: + raise Exception("public-key length is wrong") + R = decodepoint(s[0:b >> 3]) + A = decodepoint(pk) + S = decodeint(s[b >> 3:b >> 2]) + h = Hint(encodepoint(R) + pk + m) + if scalarmult(B, S) != edwards(R, scalarmult(A, h)): + raise Exception("signature does not pass verification") diff --git a/tools/keytool b/tools/keytool index 7eff01c3e2..9099549409 100755 --- a/tools/keytool +++ b/tools/keytool @@ -4,9 +4,11 @@ import binascii import ed25519raw import pyblake2 + def hex(by): return str(binascii.hexlify(by), 'ascii') + def combine_keys(pks): combine = None for pk in pks: @@ -17,6 +19,7 @@ def combine_keys(pks): combine = ed25519raw.edwards(combine, P) return ed25519raw.encodepoint(combine) + def combine_sig(R, sigs): s = 0 for si in sigs: @@ -25,12 +28,14 @@ def combine_sig(R, sigs): sig = R + ed25519raw.encodeint(s) return sig + def binom(n, k): b = 1 - for i in range(1, k+1): + for i in range(1, k + 1): b = b * (n - k + i) // i return b + def compute_mask(combination, m, n): result = 0 signer = 0 @@ -47,6 +52,7 @@ def compute_mask(combination, m, n): signer = signer + 1 return result + def createPubkey(): print('Enter randomness: ', end='') seckey = ed25519raw.H(input().encode('utf-8'))[0:32] @@ -54,38 +60,41 @@ def createPubkey(): print('Secret Key: %s' % hex(seckey)) print('Public Key: %s' % hex(pubkey)) -def combinePubkeys(m,n): - if binom(n,m) > 100: + +def combinePubkeys(m, n): + if binom(n, m) > 100: raise Exception("Too many keys") pks = [] for i in range(0, n): - print('Enter pubkey %d: ' %i, end='') + print('Enter pubkey %d: ' % i, end='') pk = binascii.unhexlify(input()) # remove 00 prefix if present if len(pk) == 33: pk = pk[1:] pks.append(ed25519raw.decodepoint(pk)) - for i in range(0, binom(n,m)): + for i in range(0, binom(n, m)): mask = compute_mask(i, m, n) sum = None for j in range(0, n): - if mask & (1<>3,b>>2)]) + data + + a = 2**(b - 2) + sum(2**i * ed25519raw.bit(h, i) for i in range(3, b - 2)) + r = ed25519raw.Hint(bytes([h[i] for i in range(b >> 3, b >> 2)]) + data + binascii.unhexlify("%08x" % ctr)) - R = ed25519raw.scalarmult(ed25519raw.B,r) + R = ed25519raw.scalarmult(ed25519raw.B, r) return (r, ed25519raw.encodepoint(R)) + def phase1(data): digest = pyblake2.blake2s(data).digest() print('Digest: %s' % hex(digest)) @@ -96,6 +105,7 @@ def phase1(data): (_, R) = get_nonce(seckey, digest, ctr) print('Local commit: %s' % hex(R)) + def combinePhase1(m): commits = [] for i in range(0, m): @@ -103,6 +113,7 @@ def combinePhase1(m): commits.append(binascii.unhexlify(input())) print('Global commit: %s' % hex(combine_keys(commits))) + def phase2(data): digest = pyblake2.blake2s(data).digest() print('Digest: %s' % hex(digest)) @@ -118,11 +129,12 @@ def phase2(data): (r, Ri) = get_nonce(seckey, digest, ctr) h = ed25519raw.H(seckey) b = ed25519raw.b - a = 2**(b-2) + sum(2**i * ed25519raw.bit(h,i) for i in range(3,b-2)) + a = 2**(b - 2) + sum(2**i * ed25519raw.bit(h, i) for i in range(3, b - 2)) S = (r + ed25519raw.Hint(R + pk + digest) * a) % ed25519raw.l print('Local commit: %s' % hex(Ri)) print('Local sig: %s' % hex(ed25519raw.encodeint(S))) + def combinePhase2(m): sigs = [] print('Enter global commit: ', end='') @@ -133,6 +145,7 @@ def combinePhase2(m): sig = combine_sig(R, sigs) print('Combined sig: %s' % hex(sig)) + def checkSignature(data): digest = pyblake2.blake2s(data).digest() print('Digest: %s' % hex(digest)) @@ -143,6 +156,7 @@ def checkSignature(data): ed25519raw.checkvalid(sig, digest, pubkey) print('Valid Signature!') + def usage(): print('Usage: keyctl phase options') print('Phases:') @@ -154,6 +168,7 @@ def usage(): print(' keyctl combine_ph2 m: combine signatures') print(' keyctl check_sig file.bin: check signature') + def main(): if len(sys.argv) < 2: usage() @@ -164,7 +179,7 @@ def main(): elif func == 'combine_pub': m = int(sys.argv[2]) n = int(sys.argv[3]) - combinePubkeys(m,n) + combinePubkeys(m, n) elif func == 'ph1': filename = sys.argv[2] data = open(filename, 'rb').read() @@ -186,10 +201,11 @@ def main(): else: usage() + def test(): data = sys.argv[1].encode('utf-8') N = 5 - keyset = [1,3,4] + keyset = [1, 3, 4] digest = pyblake2.blake2s(data).digest() print('Digest: %s' % hex(digest)) @@ -199,8 +215,8 @@ def test(): commits = [] sigs = [] for i in range(0, N): - print('----- Key %d ------' % (i+1)) - seckey = ed25519raw.H(("key%d"%(i+1)).encode('utf-8'))[0:32] + print('----- Key %d ------' % (i + 1)) + seckey = ed25519raw.H(("key%d" % (i + 1)).encode('utf-8'))[0:32] pubkey = ed25519raw.publickey(seckey) print('Secret Key: %s' % hex(seckey)) print('Public Key: %s' % hex(pubkey)) @@ -216,26 +232,27 @@ def test(): globalPk = combine_keys([pks[i] for i in keyset]) globalR = combine_keys([commits[i] for i in keyset]) print('-----------------') - print('Global pubkey: %s' %hex(globalPk)) - print('Global commit: %s' %hex(globalR)) + print('Global pubkey: %s' % hex(globalPk)) + print('Global commit: %s' % hex(globalR)) print('-----------------') - for i in range(0,5): + for i in range(0, 5): seckey = sks[i] pubkey = pks[i] r = nonces[i] R = commits[i] h = ed25519raw.H(seckey) b = ed25519raw.b - a = 2**(b-2) + sum(2**i * ed25519raw.bit(h,i) for i in range(3,b-2)) + a = 2**(b - 2) + sum(2**i * ed25519raw.bit(h, i) + for i in range(3, b - 2)) S = (r + ed25519raw.Hint(globalR + globalPk + digest) * a) % ed25519raw.l - print('Local sig %d: %s' % (i+1, hex(ed25519raw.encodeint(S)))) + print('Local sig %d: %s' % (i + 1, hex(ed25519raw.encodeint(S)))) commits.append(R) sigs.append(ed25519raw.encodeint(S)) print('-----------------') - sig = combine_sig(globalR, [sigs[i] for i in [1,3,4]]) - print('Global sig: %s' %hex(sig)) + sig = combine_sig(globalR, [sigs[i] for i in [1, 3, 4]]) + print('Global sig: %s' % hex(sig)) ed25519raw.checkvalid(sig, digest, globalPk) print('Valid Signature!') diff --git a/tools/toi2png b/tools/toi2png index 98078d4549..b682885e79 100755 --- a/tools/toi2png +++ b/tools/toi2png @@ -9,7 +9,7 @@ def process_rgb(w, h, data): pix = bytearray(w * h * 3) for i in range(w * h): c = (data[i * 2] << 8) + data[i * 2 + 1] - pix[i * 3 ] = (c & 0xF800) >> 8 + pix[i * 3 + 0] = (c & 0xF800) >> 8 pix[i * 3 + 1] = (c & 0x07C0) >> 3 pix[i * 3 + 2] = (c & 0x001F) << 3 return bytes(pix) @@ -18,7 +18,7 @@ def process_rgb(w, h, data): def process_grayscale(w, h, data): pix = bytearray(w * h) for i in range(w * h // 2): - pix[i * 2 ] = data[i] & 0xF0 + pix[i * 2 + 0] = data[i] & 0xF0 pix[i * 2 + 1] = (data[i] & 0x0F) << 4 return bytes(pix) @@ -51,10 +51,10 @@ def process_image(ifn): return 4 data = zlib.decompress(data, -10) - if ifn.endswith('.toif'): if len(data) != w * h * 2: - print('Uncompressed data length mismatch (%d vs %d)' % (len(data), w * h * 2)) + print('Uncompressed data length mismatch (%d vs %d)' % + (len(data), w * h * 2)) return 5 pix = process_rgb(w, h, data) img = Image.frombuffer('RGB', (w, h), pix, 'raw', 'RGB', 0, 1) @@ -63,7 +63,8 @@ def process_image(ifn): if ifn.endswith('.toig'): if len(data) != w * h // 2: - print('Uncompressed data length mismatch (%d vs %d)' % (len(data), w * h // 2)) + print('Uncompressed data length mismatch (%d vs %d)' % + (len(data), w * h // 2)) return 6 pix = process_grayscale(w, h, data) img = Image.frombuffer('L', (w, h), pix, 'raw', 'L', 0, 1) diff --git a/tools/ttf2c b/tools/ttf2c index e49b57d041..ff6c41bc0e 100755 --- a/tools/ttf2c +++ b/tools/ttf2c @@ -6,6 +6,7 @@ MAX_GLYPH = ord('~') # metrics explanation: https://www.freetype.org/freetype2/docs/glyphs/metrics.png + def process_face(name, style, size): print('Processing ... %s %s %s' % (name, style, size)) face = freetype.Face('/usr/share/fonts/truetype/%s-%s.ttf' % (name, style)) @@ -24,20 +25,20 @@ def process_face(name, style, size): face.load_char(c, freetype.FT_LOAD_RENDER | freetype.FT_LOAD_TARGET_NORMAL) bitmap = face.glyph.bitmap metrics = face.glyph.metrics - assert(metrics.width // 64 == bitmap.width) - assert(metrics.height // 64 == bitmap.rows) - assert(metrics.horiAdvance % 64 == 0) - assert(metrics.horiBearingX % 64 == 0) - assert(metrics.horiBearingY % 64 == 0) - assert(bitmap.width == bitmap.pitch) - assert(len(bitmap.buffer) == bitmap.pitch * bitmap.rows) + assert metrics.width // 64 == bitmap.width + assert metrics.height // 64 == bitmap.rows + assert metrics.horiAdvance % 64 == 0 + assert metrics.horiBearingX % 64 == 0 + assert metrics.horiBearingY % 64 == 0 + assert bitmap.width == bitmap.pitch + assert len(bitmap.buffer) == bitmap.pitch * bitmap.rows print('Loaded glyph "%c" ... %d x %d @ %d grays (%d bytes)' % (c, bitmap.width, bitmap.rows, bitmap.num_grays, len(bitmap.buffer))) f.write('/* %c */ static const uint8_t Font_%s_%s_%d_glyph_%d[] = { %d, %d, %d, %d, %d' % (c, name, style, size, i, bitmap.width, bitmap.rows, metrics.horiAdvance // 64, metrics.horiBearingX // 64, metrics.horiBearingY // 64)) buf = list(bitmap.buffer) if len(buf) > 0: if len(buf) % 2 > 0: buf.append(0) - buf = [ ( (a & 0xF0) | (b >> 4) ) for a, b in [buf[i:i + 2] for i in range(0, len(buf), 2)] ] + buf = [((a & 0xF0) | (b >> 4)) for a, b in [buf[i:i + 2] for i in range(0, len(buf), 2)]] f.write(', ' + ', '.join(['%d' % x for x in buf])) f.write(' };\n') f.write('\nconst uint8_t * const Font_%s_%s_%d[%d + 1 - %d] = {\n' % (name, style, size, MAX_GLYPH, MIN_GLYPH))