1use crate::{syscall_handler::syscall_process_exit_code, RuntimeContext};
2use fluentbase_types::{ExitCode, ED25519_POINT_DECOMPRESSED_SIZE};
3use rwasm::{StoreTr, TrapCode, Value};
4use sp1_curves::{edwards::ed25519::Ed25519, AffinePoint};
5
6pub fn syscall_edwards_add_handler(
7 ctx: &mut impl StoreTr<RuntimeContext>,
8 params: &[Value],
9 _result: &mut [Value],
10) -> Result<(), TrapCode> {
11 let p_ptr = params[0].i32().unwrap() as u32;
12 let mut p_bytes = [0u8; ED25519_POINT_DECOMPRESSED_SIZE];
13 ctx.memory_read(p_ptr as usize, &mut p_bytes)?;
14 let q_ptr = params[1].i32().unwrap() as u32;
15 let mut q_bytes = [0u8; ED25519_POINT_DECOMPRESSED_SIZE];
16 ctx.memory_read(q_ptr as usize, &mut q_bytes)?;
17 let res = syscall_edwards_add_impl(p_bytes, q_bytes)
18 .map_err(|e| syscall_process_exit_code(ctx, e))?;
19 ctx.memory_write(q_ptr as usize, &res)?;
20 Ok(())
21}
22
23#[cfg(target_endian = "big")]
24compile_error!("syscall_ed25519_add_impl is not implemented for big-endian targets");
25
26pub fn syscall_edwards_add_impl(
27 p_bytes: [u8; ED25519_POINT_DECOMPRESSED_SIZE],
28 q_bytes: [u8; ED25519_POINT_DECOMPRESSED_SIZE],
29) -> Result<[u8; ED25519_POINT_DECOMPRESSED_SIZE], ExitCode> {
30 let p_words: [u32; ED25519_POINT_DECOMPRESSED_SIZE / 4] = bytemuck::cast(p_bytes);
31 let q_words: [u32; ED25519_POINT_DECOMPRESSED_SIZE / 4] = bytemuck::cast(q_bytes);
32 let p_affine = AffinePoint::<Ed25519>::from_words_le(&p_words);
33 let q_affine = AffinePoint::<Ed25519>::from_words_le(&q_words);
34 let result_affine = p_affine + q_affine;
35 let r_words: [u32; ED25519_POINT_DECOMPRESSED_SIZE / 4] =
36 result_affine.to_words_le().try_into().unwrap();
37 let r_bytes: [u8; ED25519_POINT_DECOMPRESSED_SIZE] = bytemuck::cast(r_words);
38 Ok(r_bytes)
39}
40
41#[cfg(test)]
42mod tests {
43 use super::*;
44
45 #[test]
47 fn test_ed25519_add_sp1() {
48 let a: [u8; 64] = [
51 195, 166, 157, 207, 218, 220, 175, 197, 111, 177, 123, 23, 73, 72, 114, 103, 28, 246,
52 66, 207, 66, 146, 187, 234, 136, 238, 133, 145, 47, 196, 216, 199, 79, 31, 224, 30,
53 179, 122, 51, 84, 116, 12, 4, 189, 198, 198, 190, 22, 71, 201, 143, 249, 92, 56, 147,
54 133, 92, 187, 130, 33, 152, 19, 171, 73,
55 ];
56
57 let b: [u8; 64] = [
60 197, 189, 200, 77, 201, 212, 57, 105, 191, 133, 123, 170, 167, 50, 114, 38, 37, 102,
61 188, 29, 215, 227, 157, 142, 252, 31, 129, 67, 24, 255, 114, 136, 115, 94, 94, 55, 43,
62 200, 117, 224, 139, 251, 238, 45, 80, 154, 70, 213, 219, 78, 201, 108, 73, 203, 72, 45,
63 167, 131, 199, 47, 82, 134, 53, 62,
64 ];
65
66 let r = syscall_edwards_add_impl(a, b).unwrap();
67
68 let c: [u8; 64] = [
71 49, 144, 129, 197, 86, 163, 62, 48, 222, 208, 213, 200, 219, 90, 163, 54, 211, 248,
72 178, 224, 238, 167, 235, 219, 251, 247, 189, 239, 194, 16, 16, 80, 19, 106, 20, 198,
73 72, 56, 103, 111, 68, 201, 29, 107, 75, 208, 193, 232, 181, 186, 175, 22, 213, 187,
74 253, 125, 44, 80, 222, 209, 159, 125, 202, 37,
75 ];
76
77 assert_eq!(r, c);
78 }
79}