01 рдЬрдирд╡рд░реА 2026
nullprogram.com/blog/2026/01/01/
(рд▓реЗрдЦрдХ рд╡рд░реНрддрдорд╛рди рдореЗрдВ рд╕рдВрдпреБрдХреНрдд рд░рд╛рдЬреНрдп рдЕрдореЗрд░рд┐рдХрд╛ рдореЗрдВ рд░реЛрдЬрдЧрд╛рд░ рдХреЗ рдЕрд╡рд╕рд░реЛрдВ рдХреЗ рд▓рд┐рдП рдЦреБрд▓рд╛ рд╣реИред)
рдХреБрдЫ рдЬрдЯрд┐рд▓рддрд╛ рд╕реНрддрд░ рд╕реЗ рдКрдкрд░ рдХрд╛ рд╕реЙрдлрд╝реНрдЯрд╡реЗрдпрд░ рдПрдХ рд╡рд┐рд╕реНрддрд╛рд░ рднрд╛рд╖рд╛ рдХреЛ рд╕реНрдкреЛрд░реНрдЯ рдХрд░рддрд╛ рд╣реИ, рдЬреЛ рд╕реНрд╡рдпрдВ рдПрдХ рдкреНрд░рдХрд╛рд░ рдХрд╛ рд╕реЙрдлрд╝реНрдЯрд╡реЗрдпрд░ рдкреНрд▓реЗрдЯрдлрд╝реЙрд░реНрдо рдмрди рдЬрд╛рддрд╛ рд╣реИред рд▓реБрдЖ рдЗрд╕ рднреВрдорд┐рдХрд╛ рдХреЛ рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рдирд┐рднрд╛рддрд╛ рд╣реИ, рдФрд░ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рд╡реЗрдм рдкреНрд░реМрджреНрдпреЛрдЧрд┐рдХрд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдП рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рд╣реИред WebAssembly рдЗрд╕реЗ рд╕рд╛рдорд╛рдиреНрдпреАрдХреГрдд рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдХреЛрдИ рднреА Wasm-рд▓рдХреНрд╖реНрдпреАрдХрд░рдг рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛ рдПрдХ Wasm-рд╣реЛрд╕реНрдЯрд┐рдВрдЧ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░ рд╕рдХрддреА рд╣реИред рдЗрд╕рдореЗрдВ рдЯреЗрдХреНрд╕реНрдЯ рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреА рдЖрдкреВрд░реНрддрд┐ рдХрд░рдиреЗ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдЕрдзрд┐рдХ рдШрд░реНрд╖рдг рд╣реИ, рд▓реЗрдХрд┐рди рдПрдХреНрд╕рдЯреЗрдВрд╢рди рд▓реЗрдЦрдХ рдЕрдкрдиреА рдкрд╕рдВрдж рдХреА рднрд╛рд╖рд╛ рдореЗрдВ рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рдПрдХреНрд╕рдЯреЗрдВрд╢рди рднрд╛рд╖рд╛ рдХреЗ рд▓рд┐рдП рдЖрдо рддреМрд░ рдкрд░ рдЙрдкрд▓рдмреНрдз рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдЕрдзрд┐рдХ рдкрд░рд┐рд╖реНрдХреГрдд рд╡рд┐рдХрд╛рд╕ рдЯреВрд▓ – рдбрд┐рдмрдЧрд┐рдВрдЧ, рдкрд░реАрдХреНрд╖рдг рдЗрддреНрдпрд╛рджрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдкрд╛рдЗрдереЙрди рдХреЛ рдкрд╛рд░рдВрдкрд░рд┐рдХ рд░реВрдк рд╕реЗ C рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЗ рдкреАрдЫреЗ рдореВрд▓ рдХреЛрдб рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рд╣рд╛рд▓ рд╣реА рдореЗрдВ рдкрд╛рдЗрдереЙрди рдХреЛ рд╡рд╛рд╕рдо рдХреЗ рд╕рд╛рде рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд рдХрд░рдирд╛ рд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ рд╣реЛ рдЧрдпрд╛ рд╣реИред рдЗрд╕рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рд╣рдо рдкрд╛рдпрдерди рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЗ рдЕрдВрджрд░ рдПрдХ рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░-рд╕реНрд╡рддрдВрддреНрд░ рд╡рд╛рд╕рдо рдмреНрд▓реЙрдм рднреЗрдЬ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рд╣реЛрд╕реНрдЯ рд╕рд┐рд╕реНрдЯрдо рдкрд░ рджреЗрд╢реА рдЯреВрд▓рдЪреЗрди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреЗ рдмрд┐рдирд╛ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЖрдЗрдП рджреЛ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдЙрдкрдпреЛрдЧ рдХреЗ рдорд╛рдорд▓реЛрдВ рдФрд░ рдЙрдирдХреЗ рдиреБрдХрд╕рд╛рдиреЛрдВ рдкрд░ рдЪрд░реНрдЪрд╛ рдХрд░реЗрдВред
рдЖрдо рддреМрд░ рдкрд░ рд╣рдо рдмрд╛рд╣рд░реА рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рддрдХ рдкрд╣реБрдВрдЪрдиреЗ рдХреЗ рд▓рд┐рдП рдкрд╛рдпрдерди рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░реЗрдВрдЧреЗ, рдЬрд┐рд╕реЗ рдкрд╛рдпрдерди рдЕрдкрдиреЗ рдЖрдк рдПрдХреНрд╕реЗрд╕ рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛ рд╣реИред рд╡рд╛рд╕рдо рдПрдХ рд╕реИрдВрдбрдмреЙрдХреНрд╕ рдореЗрдВ рдЪрд▓рддрд╛ рд╣реИ рдЬрд┐рд╕рдХреА рдмрд╛рд╣рд░реА рджреБрдирд┐рдпрд╛ рддрдХ рдХреЛрдИ рдкрд╣реБрдВрдЪ рдирд╣реАрдВ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдпрд╣ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдЙрд╕ рдорд╛рдорд▓реЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧреА рдирд╣реАрдВ рд╣реИред рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдкрд╛рдЗрдереЙрди рдХреЛ рдЕрдзрд┐рдХ рдЧрддрд┐ рднреА рдкреНрд░рджрд╛рди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЬреЛ рд╡рд╛рд╕рдо рдХреЗ рдореБрдЦреНрдп рд╡рд┐рдХреНрд░рдп рдмрд┐рдВрджреБрдУрдВ рдореЗрдВ рд╕реЗ рдПрдХ рд╣реИред рд╣рдо рдПрдХреНрд╕реЗрд╕ рдХреЗ рд▓рд┐рдП рд╡рд╛рд╕реНрдо рдХрд╛ рднреА рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдПрдореНрдмреЗрдб рдХрд░рдиреЗ рдпреЛрдЧреНрдп рдХреНрд╖рдорддрд╛рдПрдБ
рдПрдХ рдЕрд▓рдЧ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛ рдореЗрдВ рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рд╣реИ рдЬрд┐рд╕рдХреЗ рд▓рд┐рдП рдмрд╛рд╣рд░реА рдкрд╣реБрдВрдЪ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред
рдкрд╕рдВрджреАрджрд╛ рдЧреИрд░-WASI Wasm рд░рдирдЯрд╛рдЗрдо рдХреЗ рд▓рд┐рдП рд╡рд▓реЛрдбрд┐рдорд┐рд░ рд╢рд┐рдорд╛рдВрд╕реНрдХреА рдХрд╛ wasm3 рд╣реИред рдпрд╣ рдмрд┐рд▓реНрдХреБрд▓ рдкреБрд░рд╛рдирд╛ рд╕реА рд╣реИ рдФрд░ рдЗрд╕рдореЗрдВ рдПрдВрдмреЗрдб рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рдЕрдиреБрдХреВрд▓ рд╣реИ, рдЬреИрд╕реЗ рдХрд┐, SQLiteред рдкреНрд░рджрд░реНрд╢рди рдордзреНрдпрдо рд╣реИ, рд╣рд╛рд▓рд╛рдБрдХрд┐ wasm3 рдкрд░ рдЪрд▓рдиреЗ рд╡рд╛рд▓рд╛ C рдкреНрд░реЛрдЧреНрд░рд╛рдо рдЕрднреА рднреА рд╕рдордХрдХреНрд╖ рдкрд╛рдпрдерди рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдХрд╛рдлреА рддреЗрдЬрд╝ рд╣реИред рдЗрд╕рдореЗрдВ рдкрд╛рдпрдерди рдмрд╛рдЗрдВрдбрд┐рдВрдЧ, pywasm3 рд╣реИ, рд▓реЗрдХрд┐рди рдЗрд╕реЗ рдХреЗрд╡рд▓ рд╕реЛрд░реНрд╕ рдХреЛрдб рдлреЙрд░реНрдо рдореЗрдВ рд╡рд┐рддрд░рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдпрд╛рдиреА, pywasm3 рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╣реЛрд╕реНрдЯ рдорд╢реАрди рдореЗрдВ C рдЯреВрд▓рдЪреЗрди рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП, рдЬреЛ рдпрд╣рд╛рдВ рдореЗрд░реЗ рдЙрджреНрджреЗрд╢реНрдпреЛрдВ рдХреЛ рд╡рд┐рдлрд▓ рдХрд░рддрд╛ рд╣реИред рдпрджрд┐ рдХреЛрдИ рд╕реА рдЯреВрд▓рдЪреЗрди рд╣реИ, рддреЛ рдореИрдВ рд╡рд╛рд╕реНрдо рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЬрд╛рдиреЗ рдХреЗ рдмрдЬрд╛рдп рдмрд╕ рдЙрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддрд╛ рд╣реВрдВред
рдЗрд╕ рдЖрд▓реЗрдЦ рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХреЗ рдорд╛рдорд▓реЛрдВ рдХреЗ рд▓рд┐рдП, рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛ рд╡рд┐рдХрд▓реНрдк wasmtime-py рд╣реИред рд╡рд┐рддрд░рдг рдореЗрдВ x86-64 рдФрд░ ARM64 рдкрд░ рд╡рд┐рдВрдбреЛрдЬрд╝, рдореИрдХрдУрдПрд╕ рдФрд░ рд▓рд┐рдирдХреНрд╕ рдХреЗ рд▓рд┐рдП рдмрд╛рдпрдиреЗрд░рд┐рдЬрд╝ рд╢рд╛рдорд┐рд▓ рд╣реИрдВ, рдЬреЛ рд▓рдЧрднрдЧ рд╕рднреА рдкрд╛рдпрдерди рдЗрдВрд╕реНрдЯреЙрд▓реЗрд╢рди рдХреЛ рдХрд╡рд░ рдХрд░рддрд╛ рд╣реИред рдореЗрдЬрдмрд╛рдиреЛрдВ рдХреЛ рдкрд╛рдЗрдереЙрди рджреБрднрд╛рд╖рд┐рдпрд╛, рдХрд┐рд╕реА рджреЗрд╢реА рдЯреВрд▓рдЪреЗрди рд╕реЗ рдЕрдзрд┐рдХ рдХреБрдЫ рдирд╣реАрдВ рдЪрд╛рд╣рд┐рдПред рдпрд╣ рд▓рдЧрднрдЧ рдЙрддрдирд╛ рд╣реА рдЕрдЪреНрдЫрд╛ рд╣реИ рдЬрд┐рддрдирд╛ рдХрд┐ рд╡рд╛рд╕рдо рдХреЛ рдкрд╛рдпрдерди рдореЗрдВ рд╣реА рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рд╣реИред рдореЗрд░реЗ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдореЗрдВ рдпрд╣ wasm3 рд╕реЗ 3x-10x рддреЗрдЬрд╝ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдореЗрд░реЗ рдкрд╣рд▓реЗ рдЙрдкрдпреЛрдЧ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ рд╕реНрдерд┐рддрд┐ рдФрд░ рднреА рдмреЗрд╣рддрд░ рд╣реИред рд╕рдорд╕реНрдпрд╛ рдпрд╣ рд╣реИ рдХрд┐ рд╡рд░реНрддрдорд╛рди рдореЗрдВ рдЗрд╕рдХрд╛ рд╡рдЬрди ~18MiB (рд╕реНрдерд╛рдкрд┐рдд) рд╣реИ, рдФрд░ рднрд╡рд┐рд╖реНрдп рдореЗрдВ рд╕рдВрднрд╡рддрдГ рдпрд╣ рдкрд╛рдпрдерди рдЗрдВрдЯрд░рдкреНрд░реЗрдЯрд░ рдХреЛ рд╣реА рдЯрдХреНрдХрд░ рджреЗрдЧрд╛ред рдПрдкреАрдЖрдИ рднреА рдорд╛рд╕рд┐рдХ рдЖрдзрд╛рд░ рдкрд░ рдЯреВрдЯ рдЬрд╛рддреА рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЖрдк рдЕрдкрдЧреНрд░реЗрдб рдЯреНрд░реЗрдбрдорд┐рд▓ рдХреЗ рд▓рд┐рдП рд╕рд╛рдЗрди рдЕрдк рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рдРрд╕рд╛ рди рд╣реЛ рдХрд┐ рдЖрдкрдХрд╛ рдЕрдкрдирд╛ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХреБрдЫ рд╡рд░реНрд╖реЛрдВ рдХреЗ рдмрд╛рдж рдмрд┐рдЯреНрд░реЛрдЯ рдореЗрдВ рдирд╖реНрдЯ рд╣реЛ рдЬрд╛рдПред рдпрд╣ рд▓реЗрдЦ рд╕рдВрд╕реНрдХрд░рдг 40 рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╣реИ.
рдЙрдкрдпреЛрдЧ рдХреЗ рдЙрджрд╛рд╣рд░рдг рдФрд░ рдЧреЛрдЪрд░
рдЖрдзрд┐рдХрд╛рд░рд┐рдХ рдЙрджрд╛рд╣рд░рдг рдХреБрдЫ рднреА рдЧреИрд░-рддреБрдЪреНрдЫ рдпрд╛ рджрд┐рд▓рдЪрд╕реНрдк рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рдЗрд╕рд▓рд┐рдП рдЪреАрдЬреЛрдВ рдХреЛ рд╕рдордЭрдиреЗ рдХреЗ рд▓рд┐рдП рдореБрдЭреЗ рджрд╕реНрддрд╛рд╡реЗрдЬрд╝реАрдХрд░рдг рдХрд╛ рдЕрдзреНрдпрдпрди рдХрд░рдирд╛ рдкрдбрд╝рд╛, рдЬреЛ рдХрдИ рд╕рдВрдХреЗрдд рдирд╣реАрдВ рджреЗрддрд╛ рд╣реИред рдореВрд▓ рд╕реЗрдЯрдЕрдк рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:
import functools
import wasmtime
store = wasmtime.Store()
module = wasmtime.Module.from_file(store.engine, "example.wasm")
instance = wasmtime.Instance(store, module, ())
exports = instance.exports(store)
memory = exports["memory"].get_buffer_ptr(store)
func1 = functools.partial(exports["func1"], store)
func2 = functools.partial(exports["func2"], store)
func3 = functools.partial(exports["func3"], store)
рд╕реНрдЯреЛрд░ рдПрдХ рдЖрд╡рдВрдЯрди рдХреНрд╖реЗрддреНрд░ рд╣реИ рдЬрд╣рд╛рдБ рд╕реЗ рд╣рдо рд╕рднреА рд╡рд╛рд╕ рдСрдмреНрдЬреЗрдХреНрдЯ рдЖрд╡рдВрдЯрд┐рдд рдХрд░рддреЗ рд╣реИрдВред рд╕рдВрдкреВрд░реНрдг рднрдВрдбрд╛рд░ рдХреЛ рддреНрдпрд╛рдЧрдиреЗ рдХреЗ рдЕрд▓рд╛рд╡рд╛ рд╡реНрдпрдХреНрддрд┐рдЧрдд рд╡рд╕реНрддреБрдУрдВ рдХреЛ рдореБрдХреНрдд рдХрд░рдирд╛ рд╕рдВрднрд╡ рдирд╣реАрдВ рд╣реИред рдХрд╛рдлреА рд╕рдордЭрджрд╛рд░, рдИрдорд╛рдирджрд╛рд░реА рд╕реЗред рдХреНрдпрд╛ рд╣реИ? рдирд╣реАрдВ рд╕рдордЭрджрд╛рд░ рдпрд╣ рд╣реИ рдХрд┐ рдореБрдЭреЗ рдХрд┐рддрдиреА рдмрд╛рд░ рдЦреБрдж рдХреЛ рджреЛрд╣рд░рд╛рдирд╛ рдкрдбрд╝рддрд╛ рд╣реИ, рд╕реНрдЯреЛрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрд╕реЗ рд╣рд░ рд╡рд╕реНрддреБ рдореЗрдВ рд╡рд╛рдкрд╕ рдбрд╛рд▓рдирд╛ рдкрдбрд╝рддрд╛ рд╣реИред рдпреЗ рдСрдмреНрдЬреЗрдХреНрдЯ рдмрд┐рд▓реНрдХреБрд▓ рдПрдХ рд╣реА рд╕реНрдЯреЛрд░ рд╕реЗ рдЬреБрдбрд╝реЗ рд╣реИрдВ рдФрд░ рдЗрдиреНрд╣реЗрдВ рдЕрд▓рдЧ-рдЕрд▓рдЧ рд╕реНрдЯреЛрд░ рдХреЗ рд╕рд╛рде рдЗрд╕реНрддреЗрдорд╛рд▓ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдЧрд▓рдд рд╕реНрдЯреЛрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ рдФрд░ рдпрд╣ рдШрдмрд░рд╛ рдЬрд╛рддрд╛ рд╣реИ: рдпрд╣ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЖрдВрддрд░рд┐рдХ рд░реВрдк рд╕реЗ рдирдЬрд╝рд░ рд░рдЦ рд░рд╣рд╛ рд╣реИ! рдореБрдЭреЗ рд╕рдордЭ рдирд╣реАрдВ рдЖрддрд╛ рдХрд┐ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдЗрд╕ рддрд░рд╣ рдХреНрдпреЛрдВ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред рдЗрд╕рд▓рд┐рдП рдЪреАрдЬреЛрдВ рдХреЛ рд╕рд░рд▓ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рдореИрдВ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реВрдВ functools.partial рдмрд╛рдБрдзрдиреЗ рдХреЗ рд▓рд┐рдП store рдкреИрд░рд╛рдореАрдЯрд░ рдФрд░ рдЗрд╕рд▓рд┐рдП рдореБрдЭреЗ рдЕрдкреЗрдХреНрд╖рд┐рдд рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдорд┐рд▓рддрд╛ рд╣реИред
get_buffer_ptr рдСрдмреНрдЬреЗрдХреНрдЯ рдПрдХ рдмрдлрд░ рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдСрдмреНрдЬреЗрдХреНрдЯ рд╣реИ, рдФрд░ рдпрджрд┐ рдЖрдк рдмрд╛рдЗрдЯреНрд╕ рдХреЗ рдЕрд▓рд╛рд╡рд╛ рдХреБрдЫ рднреА рд▓реЗ рдЬрд╛ рд░рд╣реЗ рд╣реИрдВ рддреЛ рд╕рдВрднрд╡рддрдГ рдЖрдк рдореЗрдореЛрд░реА рддрдХ рдкрд╣реБрдВрдЪрдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред рдЗрд╕ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ рд▓рд┐рдП рд╕рд╛рдорд╛рдиреНрдп рдЪреЗрддрд╛рд╡рдирд┐рдпрд╛рдБ рд▓рд╛рдЧреВ рд╣реЛрддреА рд╣реИрдВ: рдпрджрд┐ рдЖрдк рдореЗрдореЛрд░реА рдХрд╛ рдЖрдХрд╛рд░ рдмрджрд▓рддреЗ рд╣реИрдВ рддреЛ рдЖрдк рд╕рдВрднрд╡рддрдГ рдПрдХ рддрд╛рдЬрд╝рд╛ рдмрдлрд╝рд░ рдСрдмреНрдЬреЗрдХреНрдЯ рд▓реЗрдирд╛ рдЪрд╛рд╣реЗрдВрдЧреЗред рдмрд╛рдЗрдЯреНрд╕ рдХреЗ рд▓рд┐рдП (рдЬреИрд╕реЗ рдмрдлрд╝рд░реНрд╕ рдФрд░ рд╕реНрдЯреНрд░рд┐рдВрдЧреНрд╕) рдореИрдВ рдЗрд╕реЗ рдкрд╕рдВрдж рдХрд░рддрд╛ рд╣реВрдБ read рдФрд░ write рддрд░реАрдХреЗ.
рдХреНрдпреЛрдВрдХрд┐ рдорд▓реНрдЯреА-рд╡реИрд▓реНрдпреВ рдЕрднреА рднреА рд╡рд╛рд╕рдо рдкрд╛рд░рд┐рд╕реНрдерд┐рддрд┐рдХреА рддрдВрддреНрд░ рдореЗрдВ рдкреНрд░рд╛рдпреЛрдЧрд┐рдХ рд╕реНрдерд┐рддрд┐ рдореЗрдВ рд╣реИ, рдЖрдк рд╕рдВрднрд╡рддрдГ рд╡рд╛рд╕реНрдо рдХреЗ рд╕рд╛рде рд╕рдВрд░рдЪрдирд╛рдУрдВ рдХреЛ рдкрд╛рд░рд┐рдд рдирд╣реАрдВ рдХрд░реЗрдВрдЧреЗред рд╕реНрдХреЗрд▓рд░ рд╕реЗ рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рдХрд┐рд╕реА рднреА рдЪреАрдЬрд╝ рдХреЗ рд▓рд┐рдП рд╡рд╛рд╕рдо рд░реИрдЦрд┐рдХ рдореЗрдореЛрд░реА рдХреЗ рдЕрдВрджрд░ рдФрд░ рдмрд╛рд╣рд░ рдкреЙрдЗрдВрдЯрд░реНрд╕ рдФрд░ рдбреЗрдЯрд╛ рдХреА рдкреНрд░рддрд┐рд▓рд┐рдкрд┐ рдмрдирд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреАред рдЗрд╕рдореЗрдВ рд╕рд╛рдорд╛рдиреНрдп рдЬрд╛рд▓ рд╢рд╛рдорд┐рд▓ рд╣реИ рдЬреЛ рд▓рдЧрднрдЧ рд╕рднреА рдХреЛ рдкрдХрдбрд╝рддрд╛ рд╣реИ: рд╡рд╛рд╕реНрдо рдЗрдВрдЯрд░рдлреЗрд╕ рдкреЙрдЗрдВрдЯрд░реНрд╕ рдФрд░ рдкреВрд░реНрдгрд╛рдВрдХреЛрдВ рдХреЗ рдмреАрдЪ рдХреЛрдИ рдЕрдВрддрд░ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рдФрд░ рд╡рд╛рд╕реНрдо рд░рдирдЯрд╛рдЗрдо рдЖрдорддреМрд░ рдкрд░ рд╕рднреА рдкреВрд░реНрдгрд╛рдВрдХреЛрдВ рдХреЛ рд╣рд╕реНрддрд╛рдХреНрд╖рд░рд┐рдд рдХреЗ рд░реВрдк рдореЗрдВ рд╡реНрдпрд╛рдЦреНрдпрд╛ рдХрд░рддрд╛ рд╣реИред рдЗрд╕рдХрд╛ рдХреНрдпрд╛ рдорддрд▓рдм рд╣реИ рдЬрдм рддрдХ рдЖрдк рдХрд╛рд░реНрд░рд╡рд╛рдИ рдирд╣реАрдВ рдХрд░рддреЗ, рдЖрдкрдХреЗ рдкреЙрдЗрдВрдЯрд░реНрд╕ рдкрд░ рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ. рдкрддреЗ 0 рд╕реЗ рд╢реБрд░реВ рд╣реЛрддреЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рдпрд╣ рдмреБрд░реА, рдмреБрд░реА рдЦрдмрд░ рд╣реИред
malloc = functools.partial(exports["func1"], store)
hello = b"hello"
pointer = malloc(len(hello))
assert pointer
memory = exports["memory"].write(store, hello, pointer) # WRONG!
рдорд╛рдорд▓реЗ рдХреЛ рдмрджрддрд░ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП, wasmtime-py рдиреЗ рдЕрдкрдирд╛ рдлрд╝реБрдЯрдЧрди рдЬреЛрдбрд╝рд╛: рдж read рдФрд░
write рд╡рд┐рдзрд┐рдпрд╛рдБ рдЕрдВрдд рд╕реЗ рдХрд╛рд░реНрдп рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдирдХрд╛рд░рд╛рддреНрдордХ рд╕реВрдЪрдХрд╛рдВрдХреЛрдВ рдХреЗ рд╕рдВрджрд┐рдЧреНрдз рдкрд╛рдпрдерди рд╕рдореНрдореЗрд▓рди рдХреЛ рдЕрдкрдирд╛рддреА рд╣реИрдВред рдЕрдЧрд░ malloc рдореЗрдореЛрд░реА рдХреЗ рдКрдкрд░реА рдЖрдзреЗ рд╣рд┐рд╕реНрд╕реЗ рдореЗрдВ рдПрдХ рдкреЙрдЗрдВрдЯрд░ рд▓реМрдЯрд╛рддрд╛ рд╣реИ, рдирдХрд╛рд░рд╛рддреНрдордХ рдкреЙрдЗрдВрдЯрд░ рд╕реАрдорд╛ рдЬрд╛рдВрдЪ рдХреЛ рдЕрдВрджрд░ рд╕реЗ рдкрд╛рд░ рдХрд░ рдЬрд╛рдПрдЧрд╛
write рдХреНрдпреЛрдВрдХрд┐ рдирдХрд╛рд░рд╛рддреНрдордХ рд╡реИрдз рд╣реИ, рддреЛ рдЪреБрдкрдЪрд╛рдк рдЧрд▓рдд рдкрддреЗ рдкрд░ рд╕реНрдЯреЛрд░ рдХрд░реЗрдВ! рджреЛрд╣рд╛!
рдореБрдЭреЗ рдЖрд╢реНрдЪрд░реНрдп рд╣реБрдЖ рдХрд┐ рдпрд╣ рддреНрд░реБрдЯрд┐ рдХрд┐рддрдиреА рд╕рд╛рдорд╛рдиреНрдп рд╣реИ, рдЗрд╕рд▓рд┐рдП рдореИрдВрдиреЗ рдСрдирд▓рд╛рдЗрди рдЦреЛрдЬ рдХреАред рдореИрдВ рд╕реИрдВрдбрдмреЙрдХреНрд╕ рд╡рд╛рд▓реЗ рдкреАрдбреАрдПрдл рд░реАрдбрд░ рдореЗрдВ рдЬрдВрдЧрд▓реА рдореЗрдВ рдХреЗрд╡рд▓ рдПрдХ рдЧреИрд░-рддреБрдЪреНрдЫ wasmtime-py рдЙрдкрдпреЛрдЧ рдкрд╛ рд╕рдХрд╛ред рдЬреИрд╕рд╛ рдХрд┐ рдореЗрд░реА рдЕрдкреЗрдХреНрд╖рд╛ рдереА, рдпрд╣ рдирдХрд╛рд░рд╛рддреНрдордХ рд╕реВрдЪрдХ рдЬрд╛рд▓ рдореЗрдВ рдлрдВрд╕ рдЬрд╛рддрд╛ рд╣реИред рдЗрддрдирд╛ рд╣реА рдирд╣реАрдВ, рдпрд╣ рдкрд╛рдпрдерди рдХреА рдореЗрдореЛрд░реА рд╕реНрдкреЗрд╕ рдореЗрдВ рдПрдХ рдмрдлрд░ рдУрд╡рд░рдлрд╝реНрд▓реЛ рд╣реИ:
buf_ptr = malloc(store, len(pdf_data))
mem_data = memory.data_ptr(store)
for i, byte in enumerate(pdf_data):
mem_data[buf_ptr + i] = byte
data_ptr рд╡рд┐рдзрд┐ рдПрдХ рдЧреИрд░-рд╕реАрдорд╛-рдЬрд╛рдБрдЪрд┐рдд рдХрдЪреНрдЪрд╛ рдорд╛рд▓ рд▓реМрдЯрд╛рддреА рд╣реИ ctypes рд╕реВрдЪрдХ, рддреЛ рдпрд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдПрдХ рджреЛрд╣рд░реА рдЧрд▓рддреА рд╣реИред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдЕрдЧрд░ рдЙрд╕реЗ рд╕реИрдВрдбрдмреЙрдХреНрд╕рд┐рдВрдЧ рдХреА рдЬрд░рд╛ рднреА рдкрд░рд╡рд╛рд╣ рд╣реИ рддреЛ рдЙрд╕реЗ рд╡рд╛рд╕рдо рд╕реЗ рдЖрдиреЗ рд╡рд╛рд▓реЗ рд╕рдВрдХреЗрддреЛрдВ рдкрд░ рднрд░реЛрд╕рд╛ рдирд╣реАрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред рджреВрд╕рд░рд╛ рд╕рдВрднрд╛рд╡рд┐рдд рдирдХрд╛рд░рд╛рддреНрдордХ рд╕реВрдЪрдХ рд╣реИ, рдЬреЛ рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ рд╡рд╛рд╕рдо рдореЗрдореЛрд░реА рдХреЗ рдмрд╛рд╣рд░ рдФрд░ рдкрд╛рдпрдерди рдХреА рдореЗрдореЛрд░реА рдореЗрдВ рд▓рд┐рдЦреЗрдЧрд╛, рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рд╕реЗрдЧ-рдлреЙрд▓реНрдЯрд┐рдВрдЧред
рдХрд┐рд╕реА рдХреЛ рдХреНрдпрд╛ рдХрд░рдирд╛ рд╣реИ? рд╡рд╛рд╕рдо рд╕реЗ рдирд┐рдХрд▓рдиреЗ рд╡рд╛рд▓реЗ рдкреНрд░рддреНрдпреЗрдХ рд╕реВрдЪрдХ рдХреЛ рдЫреЛрдЯрд╛ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП
рдорд╛рд╕реНрдХ рдХреЗ рд╕рд╛рде:
pointer = malloc(...) & 0xffffffff # correct for wasm32!
рдпрд╣ рдкрд░рд┐рдгрд╛рдо рдХреЛ рдЕрд╣рд╕реНрддрд╛рдХреНрд╖рд░рд┐рдд рдХреЗ рд░реВрдк рдореЗрдВ рд╡реНрдпрд╛рдЦреНрдпрд╛ рдХрд░рддрд╛ рд╣реИред 64-рдмрд┐рдЯ рд╡рд╛рд╕рдо рдХреЛ 64-рдмрд┐рдЯ рдорд╛рд╕реНрдХ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рд╣рд╛рд▓рд╛рдВрдХрд┐ рд╡реНрдпрд╡рд╣рд╛рд░ рдореЗрдВ рдЖрдкрдХреЛ 64-рдмрд┐рдЯ рд╡рд╛рд╕реНрдо рд╕реЗ рдХрднреА рднреА рд╡реИрдз рдирдХрд╛рд░рд╛рддреНрдордХ рд╕реВрдЪрдХ рдирд╣реАрдВ рдорд┐рд▓реЗрдЧрд╛ред рдпрд╣ рдирд┐рдпрдо рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдкрд░ рднреА рд▓рд╛рдЧреВ рд╣реЛрддрд╛ рд╣реИ, рдЬрд╣рд╛рдВ рдореБрд╣рд╛рд╡рд░рд╛ рд╣реИ:
let pointer = malloc(...) >>> 0
рд╡рд╛рд╕реНрдо рд░рдирдЯрд╛рдЗрдо рдорджрдж рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛ – рдЙрдирдореЗрдВ рдЖрд╡рд╢реНрдпрдХ рдЬрд╛рдирдХрд╛рд░реА рдХрд╛ рдЕрднрд╛рд╡ рд╣реИ – рдФрд░ рдпрд╣ рд╢рд╛рдпрдж рд╡рд╛рд╕рдо рдХреЗ рдбрд┐рдЬрд╛рдЗрди рдореЗрдВ рдПрдХ рдмреБрдирд┐рдпрд╛рджреА рджреЛрд╖ рд╣реИред рдПрдХ рдмрд╛рд░ рдЬрдм рдЖрдкрдХреЛ рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдкрддрд╛ рдЪрд▓ рдЬрд╛рддрд╛ рд╣реИ рддреЛ рдЖрдк рдпрд╣ рдЧрд▓рддреА рд╣рд░ рдЬрдЧрд╣ рд╣реЛрддреЗ рд╣реБрдП рджреЗрдЦрддреЗ рд╣реИрдВред
рдЕрдм рдЬрдм рдЖрдкрдХреЗ рдкрд╛рд╕ рдПрдХ рдЙрдЪрд┐рдд рдкрддрд╛ рд╣реИ, рддреЛ рдЖрдк рдЗрд╕реЗ рдореЗрдореЛрд░реА рдХреЗ рдмрдлрд░ рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рджреГрд╢реНрдп рдкрд░ рд▓рд╛рдЧреВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдпрджрд┐ рдЖрдк NumPy рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣реЗ рд╣реИрдВ рддреЛ рдЗрд╕ рдореЗрдореЛрд░реА рдХреЛ NumPy рдкреНрд░рдХрд╛рд░реЛрдВ рдореЗрдВ рд▓рдкреЗрдЯрдХрд░ рдЗрд╕рдХреЗ рд╕рд╛рде рдЗрдВрдЯрд░реИрдХреНрдЯ рдХрд░рдиреЗ рдХреЗ рдХрдИ рддрд░реАрдХреЗ рд╣реИрдВ, рд╣рд╛рд▓рд╛рдБрдХрд┐ рдХреЗрд╡рд▓ рддрднреА рдЬрдм рдЖрдк рдПрдХ рдЫреЛрдЯреЗ рдПрдВрдбрд┐рдпрди рд╣реЛрд╕реНрдЯ рдкрд░ рд╣реЛрдВред (рдпрджрд┐ рдЖрдк рдПрдХ рдмрдбрд╝реА рдПрдВрдбрд┐рдпрди рдорд╢реАрди рдкрд░ рд╣реИрдВ, рддреЛ рд╡реИрд╕реЗ рднреА рд╡рд╛рд╕реНрдо рдЪрд▓рд╛рдирд╛ рдЫреЛрдбрд╝ рджреЗрдВред) рдореЗрд░реЗ рдорди рдореЗрдВ рдЬреЛ рдкрд╣рд▓рд╛ рдЙрдкрдпреЛрдЧ рдорд╛рдорд▓рд╛ рд╣реИ, рдЙрд╕рдореЗрдВ рдЖрдо рддреМрд░ рдкрд░ рд╕рд╛рджреЗ рдкрд╛рдпрдерди рдорд╛рдиреЛрдВ рдХреЛ рдЕрдВрджрд░ рдФрд░ рдмрд╛рд╣рд░ рдХреЙрдкреА рдХрд░рдирд╛ рд╢рд╛рдорд┐рд▓ рд╣реИред struct рдкреИрдХреЗрдЬ рдпрд╣рд╛рдБ рдХрд╛рдлреА рдЙрдкрдпреЛрдЧреА рд╣реИ:
vec2 = malloc(...) & 0xffffffff
memory = exports["memory"].get_buffer_ptr(store)
struct.pack_into(", memory, vec2, x, y)
рдпрд╣ рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЗ рд╕рдорд╛рди рднреВрдорд┐рдХрд╛ рднрд░рддрд╛ рд╣реИ DataView. рдпрджрд┐ рдЖрдк рдмрд╣реБрдд рд╕рд╛рд░реА рд╕рдВрдЦреНрдпрд╛рдПрдБ рдХреЙрдкреА рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рддреЛ CPython рдХреЗ рд╕рд╛рде рд▓реВрдк рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рдмрдЬрд╛рдп рдПрдХ рдХрд╕реНрдЯрдо рдкреНрд░рд╛рд░реВрдк рд╕реНрдЯреНрд░рд┐рдВрдЧ рдмрдирд╛рдирд╛ рддреЗрдЬрд╝ рд╣реИ:
nums: list[int] = ...
struct.pack_into(f"<{len(nums)}i", memory, buf, *nums)
рд╕рдВрд░рдЪрдирд╛рдУрдВ рдХреЛ рд╡рд╛рдкрд╕ рдХреЙрдкреА рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ struct.unpack_from. рдпрджрд┐ рдЖрдк рддрд╛рд░ рд╣рд┐рд▓рд╛ рд░рд╣реЗ рд╣реИрдВ, рддреЛ рдЖрдкрдХреЛ рдЗрд╕рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА .encode() рдФрд░ .decode() рд╕реЗ рдФрд░ рдореЗрдВ рдХрдирд╡рд░реНрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП
bytesрдЬреЛ рдХрд┐ рдЙрдкрдпреБрдХреНрдд рд╣реИрдВ read рдФрд░ write.
рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд╡рд╛рд╕реНрдо рдХрд╛рд░реНрдпрдХреНрд░рдореЛрдВ рдХреЗ рдЕрднреНрдпрд╛рд╕ рдореЗрдВ рдЖрдк рдореЗрдореЛрд░реА рдХрд╛ рдЕрдиреБрд░реЛрдз рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмрд╛рд╣рд░ рд╕реЗ “рдЕрддрд┐рдерд┐” рдЖрд╡рдВрдЯрдирдХрд░реНрддрд╛ рдХреЗ рд╕рд╛рде рдмрд╛рддрдЪреАрдд рдХрд░рдиреЗ рдЬрд╛ рд░рд╣реЗ рд╣реИрдВ, рдЬрд┐рд╕рдореЗрдВ рдЖрдк рдХрд┐рд╕реА рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд▓рд┐рдП рдЗрдирдкреБрдЯ рдХреЙрдкреА рдХрд░рддреЗ рд╣реИрдВред рдореЗрд░реЗ рдЙрджрд╛рд╣рд░рдгреЛрдВ рдореЗрдВ рдореИрдВрдиреЗ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рд╣реИ malloc рдХреНрдпреЛрдВрдХрд┐ рдЗрд╕рдХреЗ рд▓рд┐рдП рдХрд┐рд╕реА рд╡рд┐рд╕реНрддрд╛рд░ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рд╣рдореЗрд╢рд╛ рдХреА рддрд░рд╣ рдПрдХ рдмрдореНрдк рдПрд▓реЛрдХреЗрдЯрд░ рдЗрд╕реЗ рдмрд╣реБрдд рдмреЗрд╣рддрд░ рддрд░реАрдХреЗ рд╕реЗ рд╣рд▓ рдХрд░рддрд╛ рд╣реИ, рдЦрд╛рд╕рдХрд░ рдЗрд╕рд▓рд┐рдП рдХреНрдпреЛрдВрдХрд┐ рдЗрд╕рдореЗрдВ рд╡рд╛рд╕рдо рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХреЗ рдЕрдВрджрд░ рдкреВрд░реЗ рд╕рд╛рдорд╛рдиреНрдп рдкреНрд░рдпреЛрдЬрди рдПрд▓реЛрдХреЗрдЯрд░ рдХреЛ рднрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реЛрддреА рд╣реИред рдПрдХ рд╡реИрд╢реНрд╡рд┐рдХ рдХреНрд╖реЗрддреНрд░ рд░рдЦреЗрдВ – рдХреЛрдИ рдЕрдиреНрдп рдереНрд░реЗрдб рдЙрд╕ рд╡рд╛рд╕рдо рдЙрджрд╛рд╣рд░рдг рдХреЛ рд╕рд╛рдЭрд╛ рдирд╣реАрдВ рдХрд░реЗрдЧрд╛ – “рд╣реЛрд╕реНрдЯ” рдореЗрдВ рдореЗрдореЛрд░реА рдкреНрд░рдмрдВрдзрди рдХреЗ рд▓рд┐рдП рдХрд┐рд╕реА рднреА рдЪрд┐рдВрддрд╛ рдХреЗ рдмрд┐рдирд╛ рдЖрд╡рд╢реНрдпрдХрддрд╛рдиреБрд╕рд╛рд░ рдЖрд╡рдВрдЯрди рдХрд╛ рдПрдХ рд╕рдореВрд╣ рддреЗрдЬреА рд╕реЗ рдлрд╛рдпрд░ рдХрд░реЗрдВ, рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХреЙрд▓ рдХрд░реЗрдВ, рдЬреЛ рдЙрд╕ рдХреНрд╖реЗрддреНрд░ рд╕реЗ рдкрд░рд┐рдгрд╛рдо рдЖрд╡рдВрдЯрд┐рдд рдХрд░ рд╕рдХрддрд╛ рд╣реИ, рдлрд┐рд░ рдХреНрд╖реЗрддреНрд░ рдХреЛ рд╕рд╛рдл рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд░реАрд╕реЗрдЯ рдХрд░реЗрдВред рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ рдореВрд▓реНрдпреЛрдВ рдХреЛ рдЕрдВрджрд░ рдФрд░ рдмрд╛рд╣рд░ рднреЗрдЬрдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕реНрдЯреИрдХред
WebAssembly рддреЗрдЬрд╝ Python рдЬрд┐рддрдирд╛
рдорд╛рди рд▓реАрдЬрд┐рдП рдХрд┐ рд╣рдордиреЗ рдЕрдкрдиреЗ рдкрд╛рдпрдерди рдкреНрд░реЛрдЧреНрд░рд╛рдо рдореЗрдВ рд╢реБрджреНрдз рдкрд╛рдпрдерди рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рдПрдХ рдХрдореНрдкреНрдпреВрдЯреЗрд╢рдирд▓ рд╣реЙрдЯ рд╕реНрдкреЙрдЯ рджреЗрдЦрд╛ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рдХрд┐рд╕реА рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдХреЛ рдХреЙрд▓ рдирд╣реАрдВ рдХрд░рдирд╛)ред рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдЕрдиреБрдХреВрд▓рд┐рдд рдХрд░рдирд╛ рдмреБрджреНрдзрд┐рдорд╛рдиреА рд╣реЛрдЧреА. рдЕрдкрдиреЗ рдкреНрд░рдпреЛрдЧреЛрдВ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдпрджрд┐ рдореИрдВ рдЙрд╕ рдлрд╝рдВрдХреНрд╢рди рдХреЛ C рдореЗрдВ рдлрд┐рд░ рд╕реЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рдХрд░рддрд╛ рд╣реВрдВ, рдЗрд╕реЗ Wasm рдореЗрдВ рд╕рдВрдХрд▓рд┐рдд рдХрд░рддрд╛ рд╣реВрдВ, рдлрд┐рд░ рдореВрд▓ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд╕реНрдерд╛рди рдкрд░ рдЙрд╕ рдмрд┐рдЯ Wasm рдХреЛ рдЪрд▓рд╛рддрд╛ рд╣реВрдВ, рддреЛ рдореИрдВ рд▓рдЧрднрдЧ 10x рд╕реНрдкреАрдб-рдЕрдк рдХреА рдЙрдореНрдореАрдж рдХрд░ рд╕рдХрддрд╛ рд╣реВрдВред рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░ рд╕реА, рдкрд╛рдпрдерди рдХреА рддреБрд▓рдирд╛ рдореЗрдВ 100 рдЧреБрдирд╛ рдЕрдзрд┐рдХ рддреЗрдЬрд╝ рд╣реИ, рдФрд░ рд╡рд╛рд╕реНрдо рдХреЗ рд╕рд╛рде рдЗрдВрдЯрд░рдлреЗрд╕рд┐рдВрдЧ рдХрд╛ рдУрд╡рд░рд╣реЗрдб – рдЕрдВрджрд░ рдФрд░ рдмрд╛рд╣рд░ рд╕рд╛рдорд╛рди рдХреА рдкреНрд░рддрд┐рд▓рд┐рдкрд┐ рдмрдирд╛рдирд╛, рдЖрджрд┐ – рдЕрдзрд┐рдХ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЗрддрдирд╛ рдЕрдзрд┐рдХ рдирд╣реАрдВ рдХрд┐ рд▓рд╛рднрджрд╛рдпрдХ рди рд╣реЛред рдпрджрд┐ рдореИрдВ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдмрджрд▓ рд╕рдХрддрд╛ рд╣реВрдВ рддреЛ рдЗрд╕рдореЗрдВ рдФрд░ рд╕реБрдзрд╛рд░ рд╣реЛрддрд╛ рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рдХреЙрд▓рд░реНрд╕ рдХреЛ рдмрдлрд░ рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред
wasmtime-py рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж, рдореИрдВ рд╡рд┐рддрд░рдг рдмрд╛рдпрдиреЗрд░рд┐рдЬрд╝ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХреНрд░реЙрд╕-рдХрдВрдкрд╛рдЗрд▓рд░реНрд╕ рдХреЗ рд╕рд╛рде рдкрд░реЗрд╢рд╛рдиреА рдХреЗ рдмрд┐рдирд╛ рдЗрд╕ рдмрджрд▓рд╛рд╡ рдХреЛ рдкреЗрд╢ рдХрд░ рд╕рдХрддрд╛ рд╣реВрдВ, рди рд╣реА рд▓рдХреНрд╖реНрдп рдкрд░ рдЯреВрд▓рдЪреЗрди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдмрд╕ рдПрдХ рднрд╛рд░реА рдкрд╛рдпрдерди рдкреИрдХреЗрдЬред рд╢рд╛рдпрдж рдЗрд╕рдХреЗ рд▓рд╛рдпрдХ рд╣реЛ.
рдореЗрд░рд╛ рдореБрдЦреНрдп рдкреНрд░рд╛рдпреЛрдЧрд┐рдХ рдмреЗрдВрдЪрдорд╛рд░реНрдХ “рдЯреВ рд╕рдо” рд╕рдорд╕реНрдпрд╛ рдХреЗ рдореЗрд░реЗ рд╕рдорд╛рдзрд╛рди рдкрд░ рдПрдХ рднрд┐рдиреНрдирддрд╛ рд╣реИ, рдЬрд┐рд╕реЗ рдореИрдВрдиреЗ рдореВрд▓ рд░реВрдк рд╕реЗ рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЗ рд▓рд┐рдП рд▓рд┐рдЦрд╛ рдерд╛, рдлрд┐рд░ рдЗрд╕реЗ pywasm3 рдФрд░ рдмрд╛рдж рдореЗрдВ wasmtime-py рддрдХ рдмрдврд╝рд╛рдпрд╛ред рдпрд╣ рд╕рд░рд▓ рд╣реИ, рдХрд╛рдлреА рджрд┐рд▓рдЪрд╕реНрдк рд╣реИ, рдФрд░ рдореЗрд░реЗ рдорди рдореЗрдВ рдЬреЛ рд╡рд╛рд╕рдо рдбреНрд░реЙрдк-рдЗрди рд╣реИ, рдЙрд╕рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐ рд╣реИред рдЗрд╕рдХрд╛ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рд╕рдорд╛рди рд╣реИ, рд▓реЗрдХрд┐рди рдЗрд╕реЗ рд╡рд╛рд╕реНрдо рдХреЗ рд╕рд╛рде рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рдХрд░рддрд╛ рд╣реИред
# Original Pythonic interface
def twosum(nums: list[int], target: int) -> tuple[int, int] | None:
...
# Stateful Wasm interface
class TwoSumWasm():
def __init__(self):
store = wasmtime.Store()
module = wasmtime.Module.from_file(store.engine, ...)
instance = wasmtime.Instance(store, module, ())
...
def twosum(self, nums, target):
# ... use wasm instance ...
рдЗрд╕рдореЗрдВ рд╡рд╛рд╕рдо рдЙрджрд╛рд╣рд░рдг рдХреЗ рд╕рд╛рде рдХреБрдЫ рд╕реНрдерд┐рддрд┐ рд╣реИред рдпрджрд┐ рдЖрдк рдЗрд╕реЗ рд╡реИрд╢реНрд╡рд┐рдХ рдмрдирд╛рдХрд░ рдЫрд┐рдкрд╛рддреЗ рд╣реИрдВ рддреЛ рдЖрдкрдХреЛ рдЗрд╕рдХреЗ рдЪрд╛рд░реЛрдВ рдУрд░ рдЕрдкрдиреЗ рдереНрд░реЗрдб рдХреЛ рд╕рд┐рдВрдХреНрд░рдирд╛рдЗрдЬрд╝ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреАред рдПрдХ рдмрд╣реБ-рдереНрд░реЗрдбреЗрдб рдкреНрд░реЛрдЧреНрд░рд╛рдо рдореЗрдВ рд╢рд╛рдпрдж рдпреЗ рдЖрд▓рд╕реА рдврдВрдЧ рд╕реЗ рдирд┐рд░реНрдорд┐рдд рдереНрд░реЗрдб рд▓реЛрдХрд▓ рд╣реЛрдВрдЧреЗред рдореБрдЭреЗ рдЕрднреА рддрдХ рдЗрд╕реЗ рд╣рд▓ рдирд╣реАрдВ рдХрд░рдирд╛ рдкрдбрд╝рд╛ рд╣реИред
рд╣рд╛рд▓рд╛рдБрдХрд┐, wasmtime “рд╕реНрдЯреЛрд░” рдХреА рдХрдордЬреЛрд░реА рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рджрд┐рдЦрддреА рд╣реИ: рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдПрдХ рд╕реНрдЯреЛрд░ рдореЗрдВ рд╕рдВрдХрд▓рди рдФрд░ рдЗрдВрд╕реНрдЯреЗрдВрдЯреЗрд╢рди рдПрдХ рд╕рд╛рде рдХреИрд╕реЗ рдмрдВрдзреЗ рд╣реИрдВ? рдореИрдВ рдПрдХ рдмрд╛рд░ рд╕рдВрдХрд▓рд┐рдд рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛ рдФрд░ рдлрд┐рд░ рддреБрд░рдВрдд рдбрд┐рд╕реНрдкреЛрдЬреЗрдмрд▓ рдЗрдВрд╕реНрдЯреЗрдВрд╕реЗрд╕ рдирд╣реАрдВ рдмрдирд╛ рд╕рдХрддрд╛, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП WASI рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХреЗ рдкреНрд░рддреНрдпреЗрдХ рд░рди рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХред рдкреНрд░рддреНрдпреЗрдХ рдЙрджрд╛рд╣рд░рдг рд╕реНрдерд╛рдпреА рд░реВрдк рд╕реЗ рд╕рдВрдХрд▓рди рднрдВрдбрд╛рд░ рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░рддрд╛ рд╣реИред рд╡реНрдпрд╡рд╣рд╛рд░ рдореЗрдВ рд╣рдореЗрдВ рдкреНрд░рддреНрдпреЗрдХ рдбрд┐рд╕реНрдкреЛрдЬреЗрдмрд▓ рдЗрдВрд╕реНрдЯреЗрдВрд╕ рдХреЗ рд▓рд┐рдП рд╡рд╛рд╕рдо рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХреЛ рд╡реНрдпрд░реНрде рдореЗрдВ рдкреБрди: рд╕рдВрдХрд▓рд┐рдд рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рджрд┐рдЦрд╛рд╡реЗ рдХреЗ рдмрд╛рд╡рдЬреВрдж, рд╕рдВрдХрд▓рди рдФрд░ рдЗрдиреНрд╕реНрдЯреЗрдиреНрд╢рд┐рдпреЗрд╢рди рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдЪрд░рдг рдирд╣реАрдВ рд╣реИрдВ, рдХреНрдпреЛрдВрдХрд┐ рд╡реЗ рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЗ рд╡рд╛рд╕рдо рдПрдкреАрдЖрдИ рдореЗрдВ рд╣реИрдВред wasmtime.Instance рдПрдХ рд╕реНрдЯреЛрд░ рдХреЛ рдЕрдкрдиреЗ рдкрд╣рд▓реЗ рддрд░реНрдХ рдХреЗ рд░реВрдк рдореЗрдВ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддрд╛ рд╣реИ, рд╕реБрдЭрд╛рдирд╛ рдЗрдиреНрд╕реНрдЯреЗрдиреНрд╢рд┐рдпреЗрд╢рди рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрд▓рдЧ рд╕реНрдЯреЛрд░ рдХрд╛ рдЙрдкрдпреЛрдЧред рдЗрд╕рд╕реЗ рдпрд╣ рд╕рдорд╕реНрдпрд╛ рд╣рд▓ рд╣реЛ рдЬрд╛рдПрдЧреА, рд▓реЗрдХрд┐рди рдЬрдм рддрдХ рдпрд╣ рд▓рд┐рдЦрд╛ рдЬрд╛ рд░рд╣рд╛ рд╣реИ рдЕрд╡рд╢реНрдп рдореЙрдбреНрдпреВрд▓ рдХреЛ рд╕рдВрдХрд▓рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рдиреЗ рд╡рд╛рд▓рд╛ рд╡рд╣реА рд╕реНрдЯреЛрд░ рд╣реЛред рдпрд╣ рдХреБрдЫ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдЙрдкрдпреЛрдЧ рдХреЗ рдорд╛рдорд▓реЛрдВ, рд╡рд┐рд╢реЗрд╖рдХрд░ WASI рдХреЗ рд▓рд┐рдП рдПрдХ рдШрд╛рддрдХ рджреЛрд╖ рд╣реИред
рдПрдореНрдмреЗрдбреЗрдб рдХреНрд╖рдорддрд╛рдУрдВ рдХреЗ рд░реВрдк рдореЗрдВ WebAssembly
рд▓реВрдк рд╡реИрд▓реЗрдВрдЯ рдХреА рдореЛрдиреЛрд╕рд╛рдЗрдлрд╝рд░ рдПрдХ рдЕрджреНрднреБрдд рдХреНрд░рд┐рдкреНрдЯреЛрдЧреНрд░рд╛рдлреА рд▓рд╛рдЗрдмреНрд░реЗрд░реА рд╣реИред рджреБрдмрд▓рд╛, рдХреБрд╢рд▓ рдФрд░ рдПрдореНрдмреЗрдбрд┐рдВрдЧ-рдЕрдиреБрдХреВрд▓, рдЗрддрдирд╛ рдХрд┐ рдЗрд╕реЗ рдПрдХреАрдХреГрдд рд░реВрдк рдореЗрдВ рд╡рд┐рддрд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЗрд╕рдХреЗ рд▓рд┐рдП рдХрд┐рд╕реА libc рдпрд╛ рд░рдирдЯрд╛рдЗрдо рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╣рдо рдЗрд╕реЗ рд▓рдЧрднрдЧ рдХрд┐рд╕реА рднреА рдХреНрд▓реИрдВрдЧ рдЯреВрд▓рдЪреЗрди рдХреЗ рд╕рд╛рде рд╕реАрдзреЗ рд╡рд╛рд╕реНрдо рдореЗрдВ рд╕рдВрдХрд▓рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:
$ clang --target=wasm32 -nostdlib -O2 -Wl,--no-entry -Wl,--export-all
-o monocypher.wasm monocypher.c
рдпрд╣ “рд╡рд╛рд╕реНрдо-рдЕрд╡реЗрдпрд░” рдирд╣реАрдВ рд╣реИ рдЗрд╕рд▓рд┐рдП рдореБрдЭреЗ рдЗрд╕рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ --export-all рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЛ рдЙрдЬрд╛рдЧрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП. рдпрд╣ рдкреНрд░рдлреБрд▓реНрд▓рд┐рдд рд╣реИ рдХреНрдпреЛрдВрдХрд┐, рдПрдХрд▓ рдЕрдиреБрд╡рд╛рдж рдЗрдХрд╛рдИ рдХреЗ рд░реВрдк рдореЗрдВ, рдмрд╛рд╣рд░реА рд▓рд┐рдВрдХреЗрдЬ рд╡рд╛рд▓реА рдХреЛрдИ рднреА рдЪреАрдЬрд╝ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рд╣реИред рд╣рд╛рд▓рд╛рдБрдХрд┐ рдпрд╛рдж рд╣реИ рдХрд┐ рдореИрдВрдиреЗ рдЕрддрд┐рдерд┐ рдЖрд╡рдВрдЯрдирдХрд░реНрддрд╛ рдХреЗ рд╕рд╛рде рдмрд╛рддрдЪреАрдд рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреНрдпрд╛ рдХрд╣рд╛ рдерд╛? рдЗрд╕рдХрд╛ рдХреЛрдИ рдЖрд╡рдВрдЯрдирдХрд░реНрддрд╛ рдирд╣реАрдВ рд╣реИ, рди рд╣реА рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рдЗрд╕ рд░реВрдк рдореЗрдВ рдпрд╣ рдЗрддрдирд╛ рдЙрдкрдпреЛрдЧреА рдирд╣реАрдВ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рд╣рдореЗрдВ рдореЗрдореЛрд░реА рдХреЛ рдмрд╛рд╣рд░ рд╕реЗ рдкреНрд░рдмрдВрдзрд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреАред рдХрд░рдиреЗ рдпреЛрдЧреНрдп, рд▓реЗрдХрд┐рди рдПрдХ рд╣реА рдЕрдиреБрд╡рд╛рдж рдЗрдХрд╛рдИ рдкрд░ рдЯрд┐рдХреЗ рд░рд╣рдХрд░, рдХреБрдЫ рдФрд░ рдлрд╝рдВрдХреНрд╢рди рдЬреЛрдбрд╝рдХрд░ рдЗрд╕реЗ рд╕реБрдзрд╛рд░рдирд╛ рдЖрд╕рд╛рди рд╣реИ:
#include "monocypher.c"
extern char __heap_base[];
static char *heap_used;
static char *heap_high;
void *bump_alloc(ptrdiff_t size)
{
// ...
}
void bump_reset()
{
ptrdiff_t len = heap_used - __heap_base;
__builtin_memset(__heap_base, 0, len); // wipe keys, etc.
heap_used = __heap_base;
}
рдореИрдВрдиреЗ рдЪрд░реНрдЪрд╛ рдХреА рд╣реИ __heap_base рдкрд╣рд▓реЗ, рдЬреЛ рдПрдмреАрдЖрдИ рдХрд╛ рд╣рд┐рд╕реНрд╕рд╛ рд╣реИред рд╣рдо рдЗрд╕ “рд╕реНрдЯреИрдХ” рдкрд░ рдХреБрдВрдЬрд┐рдпрд╛рдБ, рдЗрдирдкреБрдЯ рдЖрджрд┐ рджрдмрд╛рдПрдБрдЧреЗ, рдЕрдкрдирд╛ рдХреНрд░рд┐рдкреНрдЯреЛрдЧреНрд░рд╛рдлреА рд░реВрдЯреАрди рдЪрд▓рд╛рдПрдБрдЧреЗ, рдкрд░рд┐рдгрд╛рдо рдХреА рдкреНрд░рддрд┐рд▓рд┐рдкрд┐ рдмрдирд╛рдПрдВрдЧреЗ, рдлрд┐рд░ рдмрдореНрдк рдПрд▓реЛрдХреЗрдЯрд░ рдХреЛ рд░реАрд╕реЗрдЯ рдХрд░реЗрдВрдЧреЗ, рдЬреЛ рд╕рднреА рд╕рдВрд╡реЗрджрдирд╢реАрд▓ рдбреЗрдЯрд╛ рдХреЛ рдорд┐рдЯрд╛ рджреЗрдЧрд╛ред рдЕрдХреНрд╕рд░ memset рдЕрдкрд░реНрдпрд╛рдкреНрдд рд╣реИ – рдЖрдо рддреМрд░ рдкрд░ рдпрд╣ рд╢реВрдиреНрдп-рддрдм-рдореБрдХреНрдд рд╣реИ, рдФрд░ рдХрдВрдкрд╛рдЗрд▓рд░ рдЬреАрд╡рдирдХрд╛рд▓ рдХреЛ рд╕рдорд╛рдкреНрдд рд╣реЛрдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рджреЗрдЦрддреЗ рд╣реИрдВ – рд▓реЗрдХрд┐рди рдпрд╣рд╛рдВ рдХреЛрдИ рдЬреАрд╡рдирдХрд╛рд▓ рд╕рдорд╛рдкреНрдд рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ, рдФрд░ рдЗрд╕ “рдвреЗрд░” рдореЗрдореЛрд░реА рдХреЛ рдмрд╛рд╣рд░реА рд░реВрдк рд╕реЗ рджреЗрдЦрдиреЗ рдпреЛрдЧреНрдп рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬрд╣рд╛рдВ рддрдХ тАЛтАЛтАЛтАЛрдЕрдореВрд░реНрдд рдорд╢реАрди рдмрддрд╛ рд╕рдХрддреА рд╣реИред (рдЕрдиреНрдпрдерд╛ рд╣рдо рд╡рд┐рд╢реНрд╡рд╕рдиреАрдп рд░реВрдк рд╕реЗ рдЕрдкрдиреЗ рдкрд░рд┐рдгрд╛рдореЛрдВ рдХреА рдкреНрд░рддрд┐рд▓рд┐рдкрд┐ рдирд╣реАрдВ рдмрдирд╛ рд╕рдХрддреЗ!)
рдЗрд╕ рдПрдкреАрдЖрдИ рдореЗрдВ рдмрд╣реБрдд рдХреБрдЫ рд╣реИ, рд▓реЗрдХрд┐рди рдореИрдВ рдХреЗрд╡рд▓ AEAD рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЛ рджреЗрдЦрдиреЗ рдЬрд╛ рд░рд╣рд╛ рд╣реВрдВред рд╣рдо рдХреБрдЫ рдбреЗрдЯрд╛ рдХреЛ рдПрдХ рдПрдиреНрдХреНрд░рд┐рдкреНрдЯреЗрдб рдмреЙрдХреНрд╕ рдореЗрдВ “рд▓реЙрдХ” рдХрд░ рджреЗрддреЗ рд╣реИрдВ, рдмрд╛рд╣рд░ рдХреЛрдИ рднреА рдЕрдирдПрдиреНрдХреНрд░рд┐рдкреНрдЯреЗрдб рд▓реЗрдмрд▓ рд▓рд┐рдЦрддреЗ рд╣реИрдВ рдЬреЛ рд╣рдо рдЪрд╛рд╣рддреЗ рд╣реИрдВред рдлрд┐рд░ рдмрд╛рдж рдореЗрдВ рд╣рдо рдмреЙрдХреНрд╕ рдХреЛ рдЕрдирд▓реЙрдХ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЬреЛ рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдХреЗрд╡рд▓ рддрднреА рдЦреБрд▓реЗрдЧрд╛ рдЬрдм рди рддреЛ рдмреЙрдХреНрд╕ рдХреА рд╕рд╛рдордЧреНрд░реА рдФрд░ рди рд╣реА рд▓реЗрдмрд▓ рдХреЗ рд╕рд╛рде рдХреЛрдИ рдЫреЗрдбрд╝рдЫрд╛рдбрд╝ рдХреА рдЧрдИ рд╣реЛред рдпрд╣ рдХреБрдЫ рдареЛрд╕ рдПрдкреАрдЖрдИ рдбрд┐рдЬрд╝рд╛рдЗрди рд╣реИ:
void crypto_aead_lock(uint8_t *cipher_text,
uint8_t mac [16],
const uint8_t key [32],
const uint8_t nonce[24],
const uint8_t *ad, size_t ad_size,
const uint8_t *plain_text, size_t text_size);
int crypto_aead_unlock(uint8_t *plain_text,
const uint8_t mac [16],
const uint8_t key [32],
const uint8_t nonce[24],
const uint8_t *ad, size_t ad_size,
const uint8_t *cipher_text, size_t text_size);
рд╡рд╛рд╕реНрдо рдХреЛ рд╕рдВрдХрд▓рд┐рдд рдХрд░рдХреЗ рд╣рдо рдЗрд╕ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреЛ рдкрд╛рдпрдерди рд╕реЗ рд▓рдЧрднрдЧ рдЙрд╕реА рддрд░рд╣ рдПрдХреНрд╕реЗрд╕ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬреИрд╕реЗ рдпрд╣ рд╢реБрджреНрдз рдкрд╛рдпрдерди рдерд╛, рдФрд░ рдореЛрдиреЛрд╕рд┐рдлрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЕрдиреНрдп рдкреНрд░рдгрд╛рд▓рд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рдмрд╛рддрдЪреАрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
рдЪреВрдБрдХрд┐ рдореЛрдиреЛрд╕рд╛рдЗрдлрд╝рд░ рдЕрдкрдиреЗ рдЖрдк рдмрд╛рд╣рд░реА рджреБрдирд┐рдпрд╛ рдХреЗ рд╕рд╛рде рдЗрдВрдЯрд░реИрдХреНрдЯ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рдпрд╣ рдЙрди рдиреЙрдиреНрд╕ рдФрд░ рдХреБрдВрдЬрд┐рдпреЛрдВ рдХреЛ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдкрдиреЗ рд╕рд┐рд╕реНрдЯрдо рдХреЗ CSPRNG рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЙрд▓ рдХрд░рдиреЗ рд╡рд╛рд▓реЛрдВ рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИ, рдЬреЛ рд╣рдо рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХрд░реЗрдВрдЧреЗред secrets рдЕрдВрддрд░реНрдирд┐рд░реНрдорд┐рдд рдкреИрдХреЗрдЬ:
class Monocypher:
def __init__(self):
...
self._read = functools.partial(memory.read, store)
self._write = functools.partial(memory.write, store)
self.__alloc = functools.partial(exports["bump_alloc"], store)
self._reset = functools.partial(exports["bump_reset"], store)
self._lock = functools.partial(exports["crypto_aead_lock"], store)
self._unlock = functools.partial(exports["crypto_aead_unlock"], store)
self._csprng = secrets.SystemRandom()
def _alloc(self, n):
return self.__alloc(n) & 0xffffffff
def generate_key(self):
return self._csprng.randbytes(32)
def generate_nonce(self):
return self._csprng.randbytes(24)
...
рдПрдХ рдареЛрд╕ рдЖрдзрд╛рд░ рдХреЗ рд╕рд╛рде, рдЬреЛ рдХреБрдЫ рднреА рд╣реЛрддрд╛ рд╣реИ рд╡рд╣ рдЖрд╕рд╛рдиреА рд╕реЗ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред рдП finally
рдЧрд╛рд░рдВрдЯреА рд░рд╣рд╕реНрдп рд╣рдореЗрд╢рд╛ рд╡рд╛рд╕ рдореЗрдореЛрд░реА рд╕реЗ рд╣рдЯрд╛ рджрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ, рдФрд░ рдмрд╛рдХреА рдХреЗрд╡рд▓ рдмрд╛рдЗрдЯреНрд╕ рдХреА рдкреНрд░рддрд┐рд▓рд┐рдкрд┐ рдмрдирд╛рдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╣реИ:
def aead_lock(self, text, key, ad = b""):
assert len(key) == 32
try:
macptr = self._alloc(16)
keyptr = self._alloc(32)
nonceptr = self._alloc(24)
adptr = self._alloc(len(ad))
textptr = self._alloc(len(text))
self._write(key, keyptr)
nonce = self.generate_nonce()
self._write(nonce, nonceptr)
self._write(ad, adptr)
self._write(text, textptr)
self._lock(
textptr,
macptr,
keyptr,
nonceptr,
adptr, len(ad),
textptr, len(text),
)
return (
self._read(macptr, macptr+16),
nonce,
self._read(textptr, textptr+len(text)),
)
finally:
self._reset()
рдФрд░ aead_unlock рдореВрд▓ рд░реВрдк рд╕реЗ рд░рд┐рд╡рд░реНрд╕ рдореЗрдВ рд╕рдорд╛рди рд╣реИ, рд▓реЗрдХрд┐рди рдпрджрд┐ рдмреЙрдХреНрд╕ рдЕрдирд▓реЙрдХ рдХрд░рдиреЗ рдореЗрдВ рд╡рд┐рдлрд▓ рд░рд╣рддрд╛ рд╣реИ, рддреЛ рд╕рдВрднрд╡рддрдГ рдЫреЗрдбрд╝рдЫрд╛рдбрд╝ рдХреЗ рдХрд╛рд░рдг рдлреЗрдВрдХ рджреЗрддрд╛ рд╣реИ:
def aead_unlock(self, text, mac, key, nonce, ad = b""):
assert len(mac) == 16
assert len(key) == 32
assert len(nonce) == 24
try:
macptr = self._alloc(16)
keyptr = self._alloc(32)
nonceptr = self._alloc(24)
adptr = self._alloc(len(ad))
textptr = self._alloc(len(text))
self._write(mac, macptr)
self._write(key, keyptr)
self._write(nonce, nonceptr)
self._write(ad, adptr)
self._write(text, textptr)
if self._unlock(
textptr,
macptr,
keyptr,
nonceptr,
adptr, len(ad),
textptr, len(text),
):
raise ValueError("AEAD mismatch")
return self._read(textptr, textptr+len(text))
finally:
self._reset()
рдЙрдкрдпреЛрдЧ:
mc = Monocypher()
key = mc.generate_key()
message = "Hello, world!"
mac, nonce, encrypted = mc.aead_lock(message.encode(), key)
рд╕рдВрдЪрд╛рд░рд┐рдд mac, nonceрдФрд░ encrypted рджреВрд╕рд░реЗ рдкрдХреНрд╖ рдХреЗ рд▓рд┐рдП (рдпрд╛ рдЖрдкрдХреЗ рднрд╡рд┐рд╖реНрдп рдХреЗ рд▓рд┐рдП), рдЬрд┐рд╕рдХреЗ рдкрд╛рд╕ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд╣реИ key:
decrypted = mc.aead_unlock(encrypted, mac, key, nonce)
рдЦреЛрдЬреЗрдВ рдореЗрд░реЗ рд╕реНрдХреНрд░реИрдЪ рднрдВрдбрд╛рд░ рдореЗрдВ рд╕рдВрдкреВрд░реНрдг рд╕реНрд░реЛрдд.
рд╣рд╛рд▓рд╛рдБрдХрд┐ рдореБрдЭреЗ wasmtime-py рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреБрдЫ рдЖрдкрддреНрддрд┐рдпрд╛рдВ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдпрд╣ рдореБрдЭреЗ рд░реЛрдорд╛рдВрдЪрд┐рдд рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рд╕рдм рдХрд┐рддрдиреА рдЕрдЪреНрдЫреА рддрд░рд╣ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред рдкрд┐рдЫрд▓реЗ рдХреБрдЫ рд╕рдордп рд╕реЗ рдпрд╣ рдореЗрд░рд╛ рд╣рдереМрдбрд╝рд╛ рдХреАрд▓ рдХреА рддрд▓рд╛рд╢ рдореЗрдВ рд╣реИред
<a href