fluentbase_types/crypto_api.rs
1use crate::{
2 BLS12381_FP_SIZE, BLS12381_G1_COMPRESSED_SIZE, BLS12381_G1_RAW_AFFINE_SIZE, BN254_FP_SIZE,
3 BN254_G1_RAW_AFFINE_SIZE, ED25519_POINT_COMPRESSED_SIZE, ED25519_POINT_DECOMPRESSED_SIZE,
4 SECP256K1_G1_COMPRESSED_SIZE, SECP256K1_G1_RAW_AFFINE_SIZE, SECP256R1_G1_COMPRESSED_SIZE,
5 SECP256R1_G1_RAW_AFFINE_SIZE,
6};
7
8/// A low-level API for cryptographic primitives used across the runtime.
9#[rustfmt::skip]
10pub trait CryptoAPI {
11 /// In-place `Keccak-f[1600]` permutation over 25 lanes of 64-bit.
12 ///
13 /// Input/Output: `state` is the 5x5x64-bit state flattened to 25 u64 words (little-endian lanes).
14 fn keccak256_permute(state: &mut [u64; 25]);
15
16 /// Expand/prepare the SHA-256 message schedule in-place.
17 ///
18 /// Input/Output: `w` holds 64 32-bit words; indices 16..63 are filled using the σ0/σ1 recurrences.
19 fn sha256_extend(w: &mut [u32; 64]);
20
21 /// One SHA-256 compression round.
22 ///
23 /// Inputs: `state` is the current 8-word state; `w` is the 64-word message schedule.
24 /// Output: `state` is updated in-place with the standard SHA-256 round function.
25 fn sha256_compress(state: &mut [u32; 8], w: &[u32; 64]);
26
27 /// Decompress an Ed25519 point from compressed y and a sign bit.
28 ///
29 /// Inputs: `y` is 32-byte compressed y-coordinate; `sign` selects the x parity.
30 /// Output: 64-byte raw affine point encoded as x||y (little-endian per coordinate).
31 fn ed25519_decompress(y: [u8; ED25519_POINT_COMPRESSED_SIZE], sign: u32) -> [u8; ED25519_POINT_DECOMPRESSED_SIZE];
32
33 /// Add two Ed25519 points in raw affine form.
34 ///
35 /// Inputs: `p`, `q` are 64-byte x||y encodings.
36 /// Output: 64-byte x||y result in the prime-order subgroup.
37 fn ed25519_add(p: [u8; ED25519_POINT_DECOMPRESSED_SIZE], q: [u8; ED25519_POINT_DECOMPRESSED_SIZE]) -> [u8; ED25519_POINT_DECOMPRESSED_SIZE];
38
39 /// BN254 base field (Fp) addition: (x + y) mod p.
40 /// Inputs/Output: 32-byte little-endian field elements.
41 fn tower_fp1_bn254_add(x: [u8; BN254_FP_SIZE], y: [u8; BN254_FP_SIZE]) -> [u8; BN254_FP_SIZE];
42
43 /// BN254 base field (Fp) subtraction: (x - y) mod p.
44 /// Inputs/Output: 32-byte little-endian field elements.
45 fn tower_fp1_bn254_sub(x: [u8; BN254_FP_SIZE], y: [u8; BN254_FP_SIZE]) -> [u8; BN254_FP_SIZE];
46
47 /// BN254 base field (Fp) multiplication: (x * y) mod p.
48 /// Inputs/Output: 32-byte little-endian field elements.
49 fn tower_fp1_bn254_mul(x: [u8; BN254_FP_SIZE], y: [u8; BN254_FP_SIZE]) -> [u8; BN254_FP_SIZE];
50
51 /// BLS12-381 base field (Fp) addition: (x + y) mod p.
52 /// Inputs/Output: 48-byte little-endian field elements.
53 fn tower_fp1_bls12381_add(x: [u8; BLS12381_FP_SIZE], y: [u8; BLS12381_FP_SIZE]) -> [u8; BLS12381_FP_SIZE];
54
55 /// BLS12-381 base field (Fp) subtraction: (x - y) mod p.
56 /// Inputs/Output: 48-byte little-endian field elements.
57 fn tower_fp1_bls12381_sub(x: [u8; BLS12381_FP_SIZE], y: [u8; BLS12381_FP_SIZE]) -> [u8; BLS12381_FP_SIZE];
58
59 /// BLS12-381 base field (Fp) multiplication: (x * y) mod p.
60 /// Inputs/Output: 48-byte little-endian field elements.
61 fn tower_fp1_bls12381_mul(x: [u8; BLS12381_FP_SIZE], y: [u8; BLS12381_FP_SIZE]) -> [u8; BLS12381_FP_SIZE];
62
63 /// BN254 quadratic extension field (Fp2) addition.
64 ///
65 /// Each Fp2 element is (c0, c1) over BN254 Fp, each limb 32-byte little-endian.
66 /// Returns (sum_c0, sum_c1).
67 fn tower_fp2_bn254_add(a_c0: [u8; BN254_FP_SIZE], a_c1: [u8; BN254_FP_SIZE], b_c0: [u8; BN254_FP_SIZE], b_c1: [u8; BN254_FP_SIZE]) -> ([u8; BN254_FP_SIZE], [u8; BN254_FP_SIZE]);
68
69 /// BN254 quadratic extension field (Fp2) subtraction.
70 /// Returns (diff_c0, diff_c1).
71 fn tower_fp2_bn254_sub(a_c0: [u8; BN254_FP_SIZE], a_c1: [u8; BN254_FP_SIZE], b_c0: [u8; BN254_FP_SIZE], b_c1: [u8; BN254_FP_SIZE]) -> ([u8; BN254_FP_SIZE], [u8; BN254_FP_SIZE]);
72
73 /// BN254 quadratic extension field (Fp2) multiplication.
74 /// Returns (prod_c0, prod_c1) reduced modulo p.
75 fn tower_fp2_bn254_mul(a_c0: [u8; BN254_FP_SIZE], a_c1: [u8; BN254_FP_SIZE], b_c0: [u8; BN254_FP_SIZE], b_c1: [u8; BN254_FP_SIZE]) -> ([u8; BN254_FP_SIZE], [u8; BN254_FP_SIZE]);
76
77 /// BLS12-381 quadratic extension field (Fp2) addition.
78 /// Each limb is 48-byte little-endian; returns (sum_c0, sum_c1).
79 fn tower_fp2_bls12381_add(a_c0: [u8; BLS12381_FP_SIZE], a_c1: [u8; BLS12381_FP_SIZE], b_c0: [u8; BLS12381_FP_SIZE], b_c1: [u8; BLS12381_FP_SIZE]) -> ([u8; BLS12381_FP_SIZE], [u8; BLS12381_FP_SIZE]);
80
81 /// BLS12-381 quadratic extension field (Fp2) subtraction.
82 /// Returns (diff_c0, diff_c1).
83 fn tower_fp2_bls12381_sub(a_c0: [u8; BLS12381_FP_SIZE], a_c1: [u8; BLS12381_FP_SIZE], b_c0: [u8; BLS12381_FP_SIZE], b_c1: [u8; BLS12381_FP_SIZE]) -> ([u8; BLS12381_FP_SIZE], [u8; BLS12381_FP_SIZE]);
84
85 /// BLS12-381 quadratic extension field (Fp2) multiplication.
86 /// Returns (prod_c0, prod_c1) reduced modulo p.
87 fn tower_fp2_bls12381_mul(a_c0: [u8; BLS12381_FP_SIZE], a_c1: [u8; BLS12381_FP_SIZE], b_c0: [u8; BLS12381_FP_SIZE], b_c1: [u8; BLS12381_FP_SIZE]) -> ([u8; BLS12381_FP_SIZE], [u8; BLS12381_FP_SIZE]);
88
89 /// Add two secp256k1 G1 points (affine x||y, 64 bytes total).
90 /// Returns the affine sum encoded as x||y (little-endian coordinates).
91 fn secp256k1_add(p: [u8; SECP256K1_G1_RAW_AFFINE_SIZE], q: [u8; SECP256K1_G1_RAW_AFFINE_SIZE]) -> [u8; SECP256K1_G1_RAW_AFFINE_SIZE];
92
93 /// Decompress a secp256k1 point from x and sign bit.
94 /// Inputs: `x` is 32-byte x (big-endian); `sign` selects the y root.
95 /// Output: 64-byte x||y (big-endian per coordinate).
96 fn secp256k1_decompress(x: [u8; SECP256K1_G1_COMPRESSED_SIZE], sign: u32) -> [u8; SECP256K1_G1_RAW_AFFINE_SIZE];
97
98 /// Point doubling on secp256k1.
99 /// Input: affine x||y; Output: affine x||y.
100 fn secp256k1_double(p: [u8; SECP256K1_G1_RAW_AFFINE_SIZE]) -> [u8; SECP256K1_G1_RAW_AFFINE_SIZE];
101
102 /// Add two secp256r1 (P-256) G1 points (affine x||y, 64 bytes total).
103 /// Returns the affine sum encoded as x||y (little-endian coordinates).
104 fn secp256r1_add(p: [u8; SECP256R1_G1_RAW_AFFINE_SIZE], q: [u8; SECP256R1_G1_RAW_AFFINE_SIZE]) -> [u8; SECP256R1_G1_RAW_AFFINE_SIZE];
105
106 /// Decompress a secp256r1 point from x and sign bit.
107 /// Inputs: `x` is 32-byte x (big-endian); `sign` selects the y root.
108 /// Output: 64-byte x||y (big-endian per coordinate).
109 fn secp256r1_decompress(x: [u8; SECP256R1_G1_COMPRESSED_SIZE], sign: u32) -> [u8; SECP256R1_G1_RAW_AFFINE_SIZE];
110
111 /// Point doubling on secp256r1.
112 /// Input: affine x||y; Output: affine x||y.
113 fn secp256r1_double(p: [u8; SECP256R1_G1_RAW_AFFINE_SIZE]) -> [u8; SECP256R1_G1_RAW_AFFINE_SIZE];
114
115 /// Add two BLS12-381 G1 points (affine x||y, 96 bytes total).
116 /// Returns the affine sum encoded as x||y (little-endian coordinates).
117 fn bls12381_add(p: [u8; BLS12381_G1_RAW_AFFINE_SIZE], q: [u8; BLS12381_G1_RAW_AFFINE_SIZE]) -> [u8; BLS12381_G1_RAW_AFFINE_SIZE];
118
119 /// Decompress a BLS12-381 G1 point from x and sign bit.
120 /// Inputs: `x` is Fp-sized x (big-endian); `sign` selects the y root.
121 /// Output: affine x||y encoding.
122 fn bls12381_decompress(x: [u8; BLS12381_G1_COMPRESSED_SIZE], sign: u32) -> [u8; BLS12381_G1_RAW_AFFINE_SIZE];
123
124 /// Point doubling on BLS12-381 G1.
125 /// Input: affine x||y; Output: affine x||y.
126 fn bls12381_double(p: [u8; BLS12381_G1_RAW_AFFINE_SIZE]) -> [u8; BLS12381_G1_RAW_AFFINE_SIZE];
127
128 /// Add two BN254 G1 points (affine x||y, 64 bytes total).
129 /// Returns the affine sum encoded as x||y.
130 fn bn254_add(p: [u8; BN254_G1_RAW_AFFINE_SIZE], q: [u8; BN254_G1_RAW_AFFINE_SIZE]) -> [u8; BN254_G1_RAW_AFFINE_SIZE];
131
132 /// Point doubling on BN254 G1.
133 /// Input: affine x||y; Output: affine x||y.
134 fn bn254_double(p: [u8; BN254_G1_RAW_AFFINE_SIZE]) -> [u8; BN254_G1_RAW_AFFINE_SIZE];
135
136 /// Compute (x * y) mod m for 256-bit integers.
137 /// Inputs: `x`, `y`, `m` are 32-byte little-endian;
138 /// Output: 32-byte little-endian result in [0, m).
139 fn uint256_mul_mod(x: &[u8; 32], y: &[u8; 32], m: &[u8; 32]) -> [u8; 32];
140
141 /// Multiply a 256-bit integer by a 2048-bit integer.
142 ///
143 /// Inputs: `a` is 32-byte little-endian; `b` is 256-byte little-endian.
144 /// Output: (lo, hi) where `lo` is the least-significant 2048-bit limb (256 bytes),
145 /// and `hi` is the top 256-bit carry (32 bytes), both little-endian.
146 fn uint256_x2048_mul(a: &[u8; 32], b: &[u8; 256]) -> ([u8; 256], [u8; 32]);
147}