-rwxr-xr-x 4449 lib25519-20240321/use-s2n-bignum raw
#!/usr/bin/env python3 prefix = 'https://raw.githubusercontent.com/awslabs/s2n-bignum/acbb18e6343f12a7944de72c1ec0991739600f8c' todo = ( ('x86/curve25519','curve25519_x25519base' ,'crypto_nG/montgomery25519/amd64-s2nbignum-adx','amd64 bmi2 adx'), ('x86/curve25519','curve25519_x25519base_alt' ,'crypto_nG/montgomery25519/amd64-s2nbignum' ,'amd64'), ('x86/curve25519','curve25519_x25519' ,'crypto_nP/montgomery25519/amd64-s2nbignum-adx','amd64 bmi2 adx'), ('x86/curve25519','curve25519_x25519_alt' ,'crypto_nP/montgomery25519/amd64-s2nbignum' ,'amd64'), ('arm/curve25519','curve25519_x25519base_byte' ,'crypto_nG/montgomery25519/arm64-s2nbignum' ,'arm64'), ('arm/curve25519','curve25519_x25519base_byte_alt','crypto_nG/montgomery25519/arm64-s2nbignum-alt','arm64'), ('arm/curve25519','curve25519_x25519_byte' ,'crypto_nP/montgomery25519/arm64-s2nbignum' ,'arm64'), ('arm/curve25519','curve25519_x25519_byte_alt' ,'crypto_nP/montgomery25519/arm64-s2nbignum-alt','arm64'), ) import os import re import urllib.request def preprocess(asm): # expand #define x(y) and remove semicolons macros = {} processed = [] def expand(processed,line): m = re.match(rb'\s*([a-zA-Z0-9_]*)\((.*)\)$',line) if m is None: processed += [line] return fun = m.group(1) args = m.group(2) processed += [b'// expanding %b(%b):' % (fun,args)] assert fun in macros assert macros[fun][0].count(b',') == args.count(b',') tr = {param:arg for param,arg in zip(macros[fun][0].split(b','),args.split(b','))} for result in macros[fun][1]: for param in tr: result = re.sub(param,tr[param],result) expand(processed,result) inmacro = False for line in asm: if inmacro: insn = line while insn.endswith(b'\\') or insn.endswith(b' ') or insn.endswith(b';'): insn = insn[:-1] macro_out += [insn] if not line.endswith(b'\\'): macros[macro] = macro_args,macro_out inmacro = False else: m = re.match(rb'#define (.*)\((.*)\) *\\$',line) if m is not None: inmacro = True macro = m.group(1) macro_args = m.group(2) macro_out = [] else: expand(processed,line) return processed for dir,source,target,architectures in todo: print(f'{prefix}/{dir}/{source}.S') with urllib.request.urlopen(f'{prefix}/{dir}/{source}.S') as http: asm = http.read() asm = asm.splitlines() asm2 = [] for line in asm: if line == b'#include "_internal_s2n_bignum.h"': continue if line.startswith(b'S2N_BN_SYMBOL') and line.endswith(b':'): parenfun = line[len(b'S2N_BN_SYMBOL'):-1] asm2 += [b'.globl CRYPTO_SHARED_NAMESPACE'+parenfun] asm2 += [b'.globl _CRYPTO_SHARED_NAMESPACE'+parenfun] asm2 += [b'CRYPTO_SHARED_NAMESPACE'+parenfun+b':'] asm2 += [b'_CRYPTO_SHARED_NAMESPACE'+parenfun+b':'] continue if line.startswith(b' S2N'): continue if line.startswith(b'// .section .rodata'): asm2 = [b'#include "crypto_asm_rodata.h"']+asm2 line = b'ASM_RODATA' asm2 += [line] asm = b'\n'.join(preprocess(asm2))+b'\n' if '_byte' in source: fun = source else: fun = source.replace('x25519','x25519_byte') fun = fun.replace('x25519_bytebase','x25519base_byte') os.makedirs(target,exist_ok=True) with open(f'{target}/architectures','w') as f: f.write(architectures+'\n') with open(f'{target}/{source}.S','wb') as f: f.write(b'// generated by use-s2n-bignum script\n') f.write(b'// starting from s2n-bignum\n') f.write(b'\n') f.write(asm) nG = target.startswith('crypto_nG') with open(f'{target}/wrapper.c','w') as f: f.write('#include <stdint.h>\n') if nG: f.write('#include "crypto_nG.h"\n\n') else: f.write('#include "crypto_nP.h"\n\n') f.write(f'#define wrapped CRYPTO_SHARED_NAMESPACE({fun})\n\n') if nG: f.write('extern void wrapped(uint8_t *,const uint8_t *);\n\n') else: f.write('extern void wrapped(uint8_t *,const uint8_t *,const uint8_t *);\n\n') if nG: f.write('void crypto_nG(unsigned char *nG,const unsigned char *n)\n') else: f.write('void crypto_nP(unsigned char *q,const unsigned char *n,const unsigned char *p)\n') f.write('{\n') if nG: f.write(' wrapped(nG,n);\n') else: f.write(' wrapped(q,n,p);\n') f.write('}\n')