blob: b560b3736aa80677d9c94df73b5e9ee0f926df09 [file] [log] [blame]
#!/usr/bin/env python3
# Copyright lowRISC contributors.
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0
import argparse
import json
import math
import sys
import hjson
def parse_hex_int(hex_str):
# int() throws an error message for empty string
if hex_str == '':
return 0
return int(hex_str, 16)
def parse_test(raw_data, n, e, t):
test = {'n': n, 'e': e}
test['msg'] = parse_hex_int(t['msg'])
# Message is expressed in hex notation, so the length in bytes is
# the number of characters / 2
test['msg_len'] = math.ceil(len(t['msg']) / 2)
test['signature'] = parse_hex_int(t['sig'])
notes = []
if t['comment']:
notes.append(t['comment'])
# Add notes from flags, if any
notes.extend([raw_data['notes'][flag] for flag in t['flags']])
# cases for expected result
if t['result'] == 'valid':
test['valid'] = True
elif t['result'] == 'invalid':
test['valid'] = False
elif t['result'] == 'acceptable':
# err on the side of caution and reject "acceptable" signatures
test['valid'] = False
notes.append('signature marked as acceptable by wycheproof')
else:
raise RuntimeError('Unexpected result type {}'.format(test['result']))
test['comment'] = 'wycheproof test with tcId={:d}, notes={}'.format(
t["tcId"], ', '.join(notes))
return test
def parse_test_group(raw_data, group):
tests = []
n = parse_hex_int(group['n'])
e = parse_hex_int(group['e'])
for t in group['tests']:
tests.append(parse_test(raw_data, n, e, t))
return tests
def parse_test_vectors(raw_data):
if raw_data['algorithm'] != 'RSASSA-PKCS1-v1_5':
raise RuntimeError('Unexpected algorithm: {}, expected {}'.format(
raw_data['algorithm'], 'RSASSA-PKCS1-v1_5'))
tests = []
for group in raw_data['testGroups']:
if group['sha'] != 'SHA-256':
raise RuntimeError(
'Unexpected hash function: {}, expected {}'.format(
group['sha'], 'SHA-256'))
tests.extend(parse_test_group(raw_data, group))
return tests
def main():
parser = argparse.ArgumentParser()
parser.add_argument('src',
metavar='FILE',
type=argparse.FileType('r'),
help='Read test vectors from this JSON file.')
parser.add_argument('dst',
metavar='FILE',
type=argparse.FileType('w'),
help='Write output to this file.')
args = parser.parse_args()
testvecs = parse_test_vectors(json.load(args.src))
args.src.close()
hjson.dump(testvecs, args.dst)
args.dst.close()
return 0
if __name__ == '__main__':
sys.exit(main())