arcis-compiler 0.9.1

A framework for writing secure multi-party computation (MPC) circuits to be executed on the Arcium network.
Documentation
use crate::{
    traits::ToMontgomery,
    utils::{
        crypto::key::{X25519PrivateKey, X25519PublicKey},
        curve_point::Curve,
        elliptic_curve::F25519,
    },
};
use std::ops::Mul;

pub fn get_shared_secret<
    Base: F25519,
    S: Clone + Copy + Mul<C, Output = C>,
    C: Curve + ToMontgomery<Output = Base>,
>(
    private_key: X25519PrivateKey<S>,
    public_key: X25519PublicKey<C>,
) -> Base {
    (private_key.inner() * public_key.inner())
        .to_montgomery(private_key.is_expected_non_zero && public_key.is_expected_non_identity)
        .0
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::{
        traits::FromLeBytes,
        utils::{
            curve_point::CurvePoint,
            field::{BaseField, ScalarField},
        },
    };

    #[test]
    fn test_get_shared_secret() {
        // each triple consists of the little-endian byte representation of
        // - Alice's random private key (generated in ts with x25519.utils.randomSecretKey())
        // - Bob's random private key (generated in ts with x25519.utils.randomSecretKey())
        // - the shared secret (obtained via x25519.getSharedSecret(privateKeyA, publicKeyB))
        let test_data: [([u8; 32], [u8; 32], [u8; 32]); 5] = [
            (
                [
                    79, 199, 145, 114, 162, 100, 170, 63, 44, 63, 54, 126, 103, 170, 132, 78, 148,
                    119, 210, 52, 131, 103, 4, 118, 29, 247, 127, 235, 193, 80, 210, 170,
                ],
                [
                    158, 160, 64, 24, 61, 192, 235, 182, 154, 139, 164, 90, 18, 208, 56, 146, 139,
                    75, 93, 101, 137, 165, 192, 12, 17, 86, 200, 18, 198, 178, 240, 167,
                ],
                [
                    162, 54, 163, 41, 149, 202, 42, 90, 142, 151, 173, 221, 246, 59, 221, 212, 50,
                    131, 100, 215, 62, 152, 161, 156, 24, 145, 41, 94, 78, 213, 220, 5,
                ],
            ),
            (
                [
                    161, 37, 23, 231, 148, 32, 153, 52, 146, 96, 11, 87, 160, 246, 147, 250, 244,
                    93, 196, 71, 62, 156, 59, 25, 96, 172, 17, 20, 7, 25, 166, 7,
                ],
                [
                    195, 183, 31, 207, 125, 170, 40, 206, 229, 207, 71, 59, 62, 240, 50, 205, 234,
                    18, 46, 226, 48, 55, 17, 227, 4, 215, 230, 111, 84, 161, 168, 115,
                ],
                [
                    214, 213, 217, 33, 199, 22, 131, 58, 154, 123, 82, 200, 8, 121, 251, 107, 70,
                    40, 208, 37, 148, 147, 197, 157, 131, 214, 64, 169, 234, 121, 169, 3,
                ],
            ),
            (
                [
                    129, 29, 5, 16, 28, 94, 151, 184, 110, 29, 118, 134, 178, 157, 161, 188, 124,
                    82, 213, 3, 203, 251, 72, 58, 97, 105, 87, 153, 151, 100, 43, 28,
                ],
                [
                    9, 232, 103, 151, 165, 10, 146, 245, 133, 34, 10, 25, 43, 223, 233, 194, 174,
                    27, 81, 163, 92, 19, 131, 90, 139, 108, 23, 71, 242, 211, 44, 130,
                ],
                [
                    229, 25, 35, 30, 24, 145, 19, 180, 90, 119, 70, 40, 135, 172, 71, 169, 114,
                    138, 238, 35, 198, 28, 38, 211, 57, 33, 199, 35, 162, 80, 112, 16,
                ],
            ),
            (
                [
                    95, 213, 217, 35, 191, 161, 68, 159, 122, 218, 224, 170, 149, 48, 44, 218, 208,
                    194, 229, 113, 170, 212, 65, 63, 237, 199, 29, 47, 23, 74, 244, 104,
                ],
                [
                    84, 21, 79, 162, 217, 201, 124, 72, 81, 246, 61, 169, 53, 183, 59, 165, 7, 117,
                    80, 168, 83, 193, 69, 45, 188, 64, 231, 1, 253, 241, 97, 252,
                ],
                [
                    40, 190, 233, 251, 24, 75, 162, 200, 74, 159, 236, 45, 194, 89, 130, 176, 29,
                    68, 44, 124, 165, 14, 178, 6, 248, 219, 202, 227, 211, 49, 93, 32,
                ],
            ),
            (
                [
                    63, 110, 198, 241, 56, 96, 91, 151, 113, 158, 157, 78, 49, 204, 44, 176, 214,
                    124, 177, 199, 92, 1, 218, 184, 198, 53, 21, 32, 41, 44, 239, 131,
                ],
                [
                    127, 198, 190, 15, 200, 200, 249, 10, 169, 254, 175, 102, 156, 106, 91, 116,
                    122, 84, 130, 63, 112, 25, 254, 7, 192, 80, 132, 209, 106, 114, 174, 101,
                ],
                [
                    193, 45, 60, 220, 218, 245, 111, 88, 221, 57, 147, 206, 251, 168, 114, 149, 25,
                    46, 98, 199, 202, 220, 1, 236, 69, 88, 145, 90, 113, 19, 47, 122,
                ],
            ),
        ];

        test_data
            .into_iter()
            .for_each(|(private_key_a_bytes, private_key_b_bytes, expected)| {
                let private_key_a =
                    X25519PrivateKey::<ScalarField>::from_le_bytes(private_key_a_bytes);
                let public_key_a =
                    X25519PublicKey::<CurvePoint>::new_from_private_key(private_key_a);
                let private_key_b =
                    X25519PrivateKey::<ScalarField>::from_le_bytes(private_key_b_bytes);
                let public_key_b =
                    X25519PublicKey::<CurvePoint>::new_from_private_key(private_key_b);
                let shared_secret_a = get_shared_secret(private_key_a, public_key_b);
                let shared_secret_b = get_shared_secret(private_key_b, public_key_a);
                let expected = BaseField::from_le_bytes(expected);
                assert_eq!(shared_secret_a, expected);
                assert_eq!(shared_secret_b, expected);
            });
    }
}