[Feature] Add Aleo generator access to programs.
Motivation
This PR adds access to the Aleo generator G to program functions and finalize via a new operand, aleo::GENERATOR.
This will allow us to perform g_scalar_multiply in programs, which enables various capabilities like address derivation.
Example Usage:
The following program tests view key to address derivation in function and finalize. You can index the generator by passing in a u32 index value (aleo::GENERATOR[0u32]). Or read the full generator object as a [group; 251u32] by using aleo::GENERATOR directly.
function foo:
input r0 as scalar.public;
input r1 as address.public;
mul aleo::GENERATOR[0u32] r0 into r2;
cast r2 into r3 as address;
assert.eq r1 r3;
async foo r0 r1 into r4;
output r4 as {program_id}/foo.future;
finalize foo:
input r0 as scalar.public;
input r1 as address.public;
mul aleo::GENERATOR[0u32] r0 into r2;
cast r2 into r3 as address;
assert.eq r1 r3;
Note: This requires ConsensusVersion::V13, so I am keeping this PR as draft until there is a formal ConsensusVersion::V13 with updated block heights merged into staging.
I recently ran into this issue (precisely when writing a test that involves doing sth similar to key derivation inside an Aleo-instructions program). My current fix has been to get CurrentNetwork::g_powers()[0] in Rust and format! it into the Aleo-instruction-program's string.
I find it confusing that there's a point referred to as a "generator" in the documentation and obtainable through the literal group::GEN which is different from the generator G = CurrentNetwork::g_powers()[0] used throughout the protocol (e. g. via vk * G = address). To be clear, every non-zero point of the group those two points live in is also a generator. Does this other point group::GEN have any particular role in the protocol? (if not, why was it added as special literal? Perhaps G = CurrentNetwork::g_powers()[0] was generated by multiplying the fixed, untrusted group::GEN by a random scalar?).
In any case, some better naming may be useful in distinguishing it from the actual, more protocol-relevant generator CurrentNetwork::g_powers()[0] to prevent errors of the flavour of vk * group::GEN == address. Also, perhaps the referenced paragraph of the Aleo Instructions documentation could clarify the distinction, although that update might make more sense once this PR is merged and Aleo programmers really have that interface to CurrentNetwork::g_powers()[0].