testnumbat_wasm_node/api/
crypto_api_node.rs

1use crate::AndesApiImpl;
2use testnumbat_wasm::{
3    api::CryptoApi,
4    types::{BoxedBytes, MessageHashType, H256},
5    Box,
6};
7
8extern "C" {
9
10    fn sha256(dataOffset: *const u8, length: i32, resultOffset: *mut u8) -> i32;
11
12    fn keccak256(dataOffset: *const u8, length: i32, resultOffset: *mut u8) -> i32;
13
14    fn ripemd160(dataOffset: *const u8, length: i32, resultOffset: *mut u8) -> i32;
15
16    fn verifyBLS(
17        keyOffset: *const u8,
18        messageOffset: *const u8,
19        messageLength: i32,
20        sigOffset: *const u8,
21    ) -> i32;
22
23    fn verifyEd25519(
24        keyOffset: *const u8,
25        messageOffset: *const u8,
26        messageLength: i32,
27        sigOffset: *const u8,
28    ) -> i32;
29
30    fn verifySecp256k1(
31        keyOffset: *const u8,
32        keyLength: i32,
33        messageOffset: *const u8,
34        messageLength: i32,
35        sigOffset: *const u8,
36    ) -> i32;
37
38    fn verifyCustomSecp256k1(
39        keyOffset: *const u8,
40        keyLength: i32,
41        messageOffset: *const u8,
42        messageLength: i32,
43        sigOffset: *const u8,
44        hashType: i32,
45    ) -> i32;
46
47    fn encodeSecp256k1DerSignature(
48        rOffset: *const u8,
49        rLength: i32,
50        sOffset: *const u8,
51        sLength: i32,
52        sigOffset: *const u8,
53    ) -> i32;
54
55}
56
57impl CryptoApi for AndesApiImpl {
58    fn sha256(&self, data: &[u8]) -> H256 {
59        unsafe {
60            let mut res = H256::zero();
61            sha256(data.as_ptr(), data.len() as i32, res.as_mut_ptr());
62            res
63        }
64    }
65
66    fn keccak256(&self, data: &[u8]) -> H256 {
67        unsafe {
68            let mut res = H256::zero();
69            keccak256(data.as_ptr(), data.len() as i32, res.as_mut_ptr());
70            res
71        }
72    }
73
74    fn ripemd160(&self, data: &[u8]) -> Box<[u8; 20]> {
75        unsafe {
76            let mut res = [0u8; 20];
77            ripemd160(data.as_ptr(), data.len() as i32, res.as_mut_ptr());
78            Box::new(res)
79        }
80    }
81
82    // the verify functions return 0 if valid signature, -1 if invalid
83
84    fn verify_bls(&self, key: &[u8], message: &[u8], signature: &[u8]) -> bool {
85        unsafe {
86            verifyBLS(
87                key.as_ptr(),
88                message.as_ptr(),
89                message.len() as i32,
90                signature.as_ptr(),
91            ) == 0
92        }
93    }
94
95    fn verify_ed25519(&self, key: &[u8], message: &[u8], signature: &[u8]) -> bool {
96        unsafe {
97            verifyEd25519(
98                key.as_ptr(),
99                message.as_ptr(),
100                message.len() as i32,
101                signature.as_ptr(),
102            ) == 0
103        }
104    }
105
106    fn verify_secp256k1(&self, key: &[u8], message: &[u8], signature: &[u8]) -> bool {
107        unsafe {
108            verifySecp256k1(
109                key.as_ptr(),
110                key.len() as i32,
111                message.as_ptr(),
112                message.len() as i32,
113                signature.as_ptr(),
114            ) == 0
115        }
116    }
117
118    fn verify_custom_secp256k1(
119        &self,
120        key: &[u8],
121        message: &[u8],
122        signature: &[u8],
123        hash_type: MessageHashType,
124    ) -> bool {
125        unsafe {
126            verifyCustomSecp256k1(
127                key.as_ptr(),
128                key.len() as i32,
129                message.as_ptr(),
130                message.len() as i32,
131                signature.as_ptr(),
132                hash_type.as_u8() as i32,
133            ) == 0
134        }
135    }
136
137    fn encode_secp256k1_der_signature(&self, r: &[u8], s: &[u8]) -> BoxedBytes {
138        unsafe {
139            // 3 for "magic" numbers in the signature + 3 for lengths: total_sig_length, r_length, s_length
140            let mut sig_length = 6 + r.len() + s.len();
141            let mask = 0x80;
142
143            // 1 additional zero-byte is added for r and s if they could be misinterpreted as a negative number
144            if r[0] & mask != 0 {
145                sig_length += 1;
146            }
147            if s[0] & mask != 0 {
148                sig_length += 1;
149            }
150
151            let mut sig_output = BoxedBytes::allocate(sig_length);
152
153            encodeSecp256k1DerSignature(
154                r.as_ptr(),
155                r.len() as i32,
156                s.as_ptr(),
157                s.len() as i32,
158                sig_output.as_mut_ptr(),
159            );
160
161            sig_output
162        }
163    }
164}