File: libxeddsa_emscripten.py

package info (click to toggle)
python-xeddsa 1.1.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 224 kB
  • sloc: python: 472; ansic: 15; makefile: 13
file content (171 lines) | stat: -rw-r--r-- 5,864 bytes parent folder | download
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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
# pylint: skip-file

from browser import window  # type: ignore[import-not-found]
import re
from typing import Any, Optional, cast


__all__ = [
    "cdata",
    "lib",
    "ffi"
]


class cdata:
    def __init__(self, array: Any) -> None:
        self.__array = array

    @property
    def array(self) -> Any:
        return self.__array

    def __bytes__(self) -> bytes:
        return bytes(window.Array["from"](self.__array))


class lib:
    @staticmethod
    def ed25519_priv_sign(sig: cdata, priv: cdata, msg: cdata, msg_size: int, nonce: cdata) -> None:
        sig_ptr = window.Module._malloc(sig.array.length)

        window.ed25519_priv_sign(sig_ptr, priv.array, msg.array, msg_size, nonce.array)

        sig.array.set(window.HEAPU8.subarray(sig_ptr, sig_ptr + sig.array.length))
        window.Module._free(sig_ptr)

    @staticmethod
    def ed25519_seed_sign(sig: cdata, seed: cdata, msg: cdata, msg_size: int) -> None:
        sig_ptr = window.Module._malloc(sig.array.length)

        window.ed25519_seed_sign(sig_ptr, seed.array, msg.array, msg_size)

        sig.array.set(window.HEAPU8.subarray(sig_ptr, sig_ptr + sig.array.length))
        window.Module._free(sig_ptr)

    @staticmethod
    def ed25519_verify(sig: cdata, ed25519_pub: cdata, msg: cdata, msg_size: int) -> int:
        return cast(int, window.ed25519_verify(sig.array, ed25519_pub.array, msg.array, msg_size))

    @staticmethod
    def curve25519_pub_to_ed25519_pub(ed25519_pub: cdata, curve25519_pub: cdata, set_sign_bit: bool) -> None:
        ed25519_pub_ptr = window.Module._malloc(ed25519_pub.array.length)

        window.curve25519_pub_to_ed25519_pub(ed25519_pub_ptr, curve25519_pub.array, set_sign_bit)

        ed25519_pub.array.set(window.HEAPU8.subarray(
            ed25519_pub_ptr,
            ed25519_pub_ptr + ed25519_pub.array.length
        ))
        window.Module._free(ed25519_pub_ptr)

    @staticmethod
    def ed25519_pub_to_curve25519_pub(curve25519_pub: cdata, ed25519_pub: cdata) -> int:
        curve25519_pub_ptr = window.Module._malloc(curve25519_pub.array.length)

        result = cast(int, window.ed25519_pub_to_curve25519_pub(curve25519_pub_ptr, ed25519_pub.array))

        curve25519_pub.array.set(window.HEAPU8.subarray(
            curve25519_pub_ptr,
            curve25519_pub_ptr + curve25519_pub.array.length
        ))
        window.Module._free(curve25519_pub_ptr)

        return result

    @staticmethod
    def priv_to_curve25519_pub(curve25519_pub: cdata, priv: cdata) -> None:
        curve25519_pub_ptr = window.Module._malloc(curve25519_pub.array.length)

        window.priv_to_curve25519_pub(curve25519_pub_ptr, priv.array)

        curve25519_pub.array.set(window.HEAPU8.subarray(
            curve25519_pub_ptr,
            curve25519_pub_ptr + curve25519_pub.array.length
        ))
        window.Module._free(curve25519_pub_ptr)

    @staticmethod
    def priv_to_ed25519_pub(ed25519_pub: cdata, priv: cdata) -> None:
        ed25519_pub_ptr = window.Module._malloc(ed25519_pub.array.length)

        window.priv_to_ed25519_pub(ed25519_pub_ptr, priv.array)

        ed25519_pub.array.set(window.HEAPU8.subarray(
            ed25519_pub_ptr,
            ed25519_pub_ptr + ed25519_pub.array.length
        ))
        window.Module._free(ed25519_pub_ptr)

    @staticmethod
    def seed_to_ed25519_pub(ed25519_pub: cdata, seed: cdata) -> None:
        ed25519_pub_ptr = window.Module._malloc(ed25519_pub.array.length)

        window.seed_to_ed25519_pub(ed25519_pub_ptr, seed.array)

        ed25519_pub.array.set(window.HEAPU8.subarray(
            ed25519_pub_ptr,
            ed25519_pub_ptr + ed25519_pub.array.length
        ))
        window.Module._free(ed25519_pub_ptr)

    @staticmethod
    def priv_force_sign(priv_out: cdata, priv_in: cdata, set_sign_bit: bool) -> None:
        priv_out_ptr = window.Module._malloc(priv_out.array.length)

        window.priv_force_sign(priv_out_ptr, priv_in.array, set_sign_bit)

        priv_out.array.set(window.HEAPU8.subarray(
            priv_out_ptr,
            priv_out_ptr + priv_out.array.length
        ))
        window.Module._free(priv_out_ptr)

    @staticmethod
    def seed_to_priv(priv: cdata, seed: cdata) -> None:
        priv_ptr = window.Module._malloc(priv.array.length)

        window.seed_to_priv(priv_ptr, seed.array)

        priv.array.set(window.HEAPU8.subarray(priv_ptr, priv_ptr + priv.array.length))
        window.Module._free(priv_ptr)

    @staticmethod
    def x25519(shared_secret: cdata, priv: cdata, curve25519_pub: cdata) -> int:
        shared_secret_ptr = window.Module._malloc(shared_secret.array.length)

        result = cast(int, window.x25519(shared_secret_ptr, priv.array, curve25519_pub.array))

        shared_secret.array.set(window.HEAPU8.subarray(
            shared_secret_ptr,
            shared_secret_ptr + shared_secret.array.length
        ))
        window.Module._free(shared_secret_ptr)

        return result

    @staticmethod
    def xeddsa_init() -> int:
        return cast(int, window.xeddsa_init())

    XEDDSA_VERSION_MAJOR: int = window.XEDDSA_VERSION_MAJOR
    XEDDSA_VERSION_MINOR: int = window.XEDDSA_VERSION_MINOR
    XEDDSA_VERSION_REVISION: int = window.XEDDSA_VERSION_REVISION


class ffi:
    @staticmethod
    def new(type_definition: str, data: Optional[bytes] = None) -> cdata:
        match = re.match(r"uint8_t\[(\d+)?\]", type_definition)
        if match is None:
            raise ValueError("Only uint8_t arrays are supported for now.")

        array_size = match.group(1)
        if array_size is None and data is None:
            raise ValueError("Data must be supplied if an array of unknown size is requested.")

        return cdata(
            window.Uint8Array.new(array_size)
            if data is None
            else window.Uint8Array["from"](list(data))
        )