spark_cryptography/
utils.rs

1// use k256::{Scalar, elliptic_curve::PrimeField};
2// use num_traits::Num;
3
4// use crate::secp256k1::{CURVE_ORDER, CURVE_RADIX};
5
6// /// Converts a BigInt (shamir_secret_sharing::num_bigint::BigInt) to a k256 Scalar.
7// pub(crate) fn int_to_k256_scalar(value: &BigInt) -> Scalar {
8//     // 1) Reduce the entire BigInt modulo the secp256k1 group order.
9//     let curve_order =
10//         BigInt::from_str_radix(CURVE_ORDER, CURVE_RADIX).expect("invalid curve order constant");
11//     let reduced_value = value % &curve_order;
12
13//     // 2) Apply zero-padding if the array is less than 32 bytes.
14//     let mut be_bytes = reduced_value.to_bytes_be().1;
15//     if be_bytes.len() < 32 {
16//         // zero-pad if less than 32 bytes
17//         let mut padded = vec![0u8; 32];
18//         padded[32 - be_bytes.len()..].copy_from_slice(&be_bytes);
19//         be_bytes = padded;
20//     }
21
22//     let mut be_bytes_array = [0u8; 32];
23//     be_bytes_array.copy_from_slice(&be_bytes);
24
25//     // 3) Use from_be_bytes to get the final Scalar,
26//     //    which is in [0, n-1].
27//     Scalar::from_repr_vartime(be_bytes_array.into())
28//         .expect("reduced_value was < n, so this scalar is valid")
29// }
30
31// #[cfg(test)]
32// mod tests {
33//     use num_traits::Zero;
34//     use rand::Rng;
35
36//     use super::*;
37
38//     /// Parses the curve order into a BigInt (shamir_secret_sharing::num_bigint::BigInt).
39//     fn get_curve_order_as_bigint() -> BigInt {
40//         BigInt::from_str_radix(CURVE_ORDER, CURVE_RADIX).expect("invalid curve order constant")
41//     }
42
43//     #[test]
44//     fn test_int_to_scalar_k256_small() {
45//         // zero
46//         let zero_bigint = BigInt::zero();
47//         let zero_scalar = int_to_k256_scalar(&zero_bigint);
48
49//         // convert scalar back to BigInt for checking
50//         let zero_scalar_bigint = BigInt::from_bytes_be(
51//             shamir_secret_sharing::num_bigint::Sign::Plus,
52//             &zero_scalar.to_bytes(),
53//         );
54
55//         // ensure it's indeed zero
56//         assert_eq!(zero_scalar_bigint, BigInt::zero());
57
58//         // small BigInt, e.g. 123
59//         let small = BigInt::from(123u32);
60//         let small_scalar = int_to_k256_scalar(&small);
61//         let small_scalar_bigint = BigInt::from_bytes_be(
62//             shamir_secret_sharing::num_bigint::Sign::Plus,
63//             &small_scalar.to_bytes(),
64//         );
65//         assert_eq!(small, small_scalar_bigint);
66//         // also ensure it's < n
67//         let curve_order = get_curve_order_as_bigint();
68//         assert!(small_scalar_bigint < curve_order);
69//     }
70
71//     #[test]
72//     fn test_int_to_scalar_k256_32_bytes() {
73//         // 32 bytes => let's pick a random 256-bit number
74//         let mut rng = rand::thread_rng();
75//         let mut random_32 = [0u8; 32];
76//         rng.fill(&mut random_32);
77
78//         let bigint_32 =
79//             BigInt::from_bytes_be(shamir_secret_sharing::num_bigint::Sign::Plus, &random_32);
80//         let scalar_32 = int_to_k256_scalar(&bigint_32);
81//         let scalar_32_bigint = BigInt::from_bytes_be(
82//             shamir_secret_sharing::num_bigint::Sign::Plus,
83//             &scalar_32.to_bytes(),
84//         );
85
86//         // Now, scalar_32_bigint should match bigint_32 % n
87//         let curve_order = get_curve_order_as_bigint();
88//         let expected_mod = &bigint_32 % &curve_order;
89//         assert_eq!(scalar_32_bigint, expected_mod);
90//         assert!(scalar_32_bigint < curve_order);
91//     }
92
93//     #[test]
94//     fn test_int_to_scalar_k256_oversized() {
95//         // create a 48-byte random buffer
96//         let mut rng = rand::thread_rng();
97//         let mut random_oversized = vec![0u8; 48];
98//         rng.fill(&mut random_oversized[..]);
99
100//         let bigint_oversized = BigInt::from_bytes_be(
101//             shamir_secret_sharing::num_bigint::Sign::Plus,
102//             &random_oversized,
103//         );
104
105//         let scalar_oversized = int_to_k256_scalar(&bigint_oversized);
106//         let scalar_oversized_bigint = BigInt::from_bytes_be(
107//             shamir_secret_sharing::num_bigint::Sign::Plus,
108//             &scalar_oversized.to_bytes(),
109//         );
110
111//         // The function automatically slices to 32 bytes, then reduces mod n
112//         let curve_order = get_curve_order_as_bigint();
113//         assert!(scalar_oversized_bigint < curve_order, "result must be < n");
114
115//         // Also verify equivalence to forcibly truncated 32 bytes once modded by n
116//         // Basically: let truncated = last 32 bytes of random_oversized => big-int => mod n.
117//         // But since from_be_bytes also does mod reduction, they should match that mod result.
118//         let actual_mod = &bigint_oversized % &curve_order;
119//         assert_eq!(scalar_oversized_bigint, actual_mod);
120//     }
121
122//     #[test]
123//     fn test_int_to_scalar_k256_valid_range() {
124//         let curve_order = get_curve_order_as_bigint();
125//         // Try 10 random inputs
126//         for _ in 0..10 {
127//             let mut rng = rand::thread_rng();
128//             let mut random_64 = vec![0u8; 64];
129//             rng.fill(&mut random_64[..]);
130
131//             let big_val =
132//                 BigInt::from_bytes_be(shamir_secret_sharing::num_bigint::Sign::Plus, &random_64);
133//             let result_scalar = int_to_k256_scalar(&big_val);
134
135//             // check that the result is < n
136//             let result_scalar_bigint = BigInt::from_bytes_be(
137//                 shamir_secret_sharing::num_bigint::Sign::Plus,
138//                 &result_scalar.to_bytes(),
139//             );
140//             assert!(result_scalar_bigint < curve_order);
141//         }
142//     }
143// }