arithmetic-eval 0.3.0

Simple interpreter for arithmetic expressions.
Documentation
//! El-Gamal encryption on a prime-order cyclic group.

dbg(GEN, ORDER);

gen = || {
    sk = rand_scalar();
    #{ sk, pk: GEN ^ sk }
};

encrypt = |message, pk| {
    r = rand_scalar();
    shared_secret = pk ^ r;
    #{ R: GEN ^ r, B: message * shared_secret }
};

decrypt = |{ R, B }, sk| {
    shared_secret = R ^ sk;
    B / shared_secret
};

// Test!
{ sk, pk } = gen();

5.while(|i| i != 0, |i| {
    message = GEN ^ rand_scalar();
    dbg(message);
    encrypted = message.encrypt(pk);
    dbg(encrypted);
    assert_eq(encrypted.decrypt(sk), message);

    i - 1
});

// Advanced testing making use of partial homomorhicity of encryption.
ONE = GEN ^ 0;
encrypt_and_combine = |messages, pk| {
    messages.map(|msg| msg.encrypt(pk)).fold(
        #{ R: ONE, B: ONE },
        |enc_x, enc_y| enc_x * enc_y,
    )
};

messages = (1, 2, 3, 4, 5).map(|_| GEN ^ rand_scalar());
assert_eq(
    encrypt_and_combine(messages, pk).decrypt(sk),
    messages.fold(ONE, |acc, msg| acc * msg)
);