mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-11-27 02:24:15 +03:00
More examples
This commit is contained in:
parent
e1a148a93e
commit
d7813923d2
@ -416,7 +416,6 @@ impl ParserContext<'_> {
|
||||
/// and function definition.
|
||||
fn parse_function(&mut self) -> Result<(Identifier, Function)> {
|
||||
// TODO: Handle dangling annotations.
|
||||
// TODO: Handle duplicate annotations.
|
||||
// Parse annotations, if they exist.
|
||||
let mut annotations = Vec::new();
|
||||
while self.look_ahead(0, |t| &t.token) == &Token::At {
|
||||
|
@ -1,10 +1,13 @@
|
||||
// This function takes as input a field `a` and calls several core functions.
|
||||
// Core functions are built-in to the Leo language and call handwritten, optimized circuits in the AVM.
|
||||
// To call a core function, use the correct capitalized identifier followed by two colons
|
||||
// and then the function name. Example: `Pedersen64::hash()`.
|
||||
transition main(a: field) -> field {
|
||||
let b: field = BHP256::hash(a);
|
||||
let c: field = Poseidon2::hash(b);
|
||||
let d: field = BHP256::commit(c, 1scalar);
|
||||
return d;
|
||||
program core.aleo {
|
||||
// This function takes as input a field `a` and calls several core functions.
|
||||
// Core functions are built-in to the Leo language and call handwritten, optimized circuits in the AVM.
|
||||
// To call a core function, use the correct capitalized identifier followed by two colons
|
||||
// and then the function name. Example: `Pedersen64::hash()`.
|
||||
transition main(a: field) -> field {
|
||||
let b: field = BHP256::hash(a);
|
||||
let c: field = Poseidon2::hash(b);
|
||||
let d: field = BHP256::commit(c, 1scalar);
|
||||
return d;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,13 +1,16 @@
|
||||
// This function takes a group coordinate as input `a` and performs several operations which should output the `0group`.
|
||||
// Note that the operations can be called as associated functions on the `a` variable.
|
||||
program groups.aleo {
|
||||
// This function takes a group coordinate as input `a` and performs several operations which should output the `0group`.
|
||||
// Note that the operations can be called as associated functions on the `a` variable.
|
||||
|
||||
transition main(a: group) -> group {
|
||||
// unary
|
||||
let e: group = a.double(); // 2a
|
||||
let g: group = e.neg(); // -2a
|
||||
transition main(a: group) -> group {
|
||||
// unary
|
||||
let e: group = a.double(); // 2a
|
||||
let g: group = e.neg(); // -2a
|
||||
|
||||
// binary
|
||||
let j: group = (a * 2scalar).add(g);
|
||||
// binary
|
||||
let j: group = (a * 2scalar).add(g);
|
||||
|
||||
return j;
|
||||
return j;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,52 +1,54 @@
|
||||
// The 'ntzdebruijn' main function.
|
||||
// From Hacker's Delight 2nd ed. figure 5-26
|
||||
transition main(public x: u32) -> u8 {
|
||||
if x == 0u32 {return 32u8;}
|
||||
// 0x04D7651F = 81224991
|
||||
x = (x & 0u32.sub_wrapped(x)).mul_wrapped(81224991u32);
|
||||
let i: u32 = x >> 27u8;
|
||||
return deBruijnTableLookup(i);
|
||||
}
|
||||
|
||||
// { 0, 1, 2,24, 3,19, 6,25, 22, 4,20,10,16, 7,12,26,
|
||||
// 31,23,18, 5,21, 9,15,11, 30,17, 8,14,29,13,28,27};
|
||||
|
||||
function deBruijnTableLookup(i: u32) -> u8 {
|
||||
|
||||
if i == 0u32 {return 0u8;} else
|
||||
if i == 1u32 {return 1u8;} else
|
||||
if i == 2u32 {return 2u8;} else
|
||||
if i == 3u32 {return 24u8;} else
|
||||
if i == 4u32 {return 3u8;} else
|
||||
if i == 5u32 {return 19u8;} else
|
||||
if i == 6u32 {return 6u8;} else
|
||||
if i == 7u32 {return 25u8;} else
|
||||
|
||||
if i == 8u32 {return 22u8;} else
|
||||
if i == 9u32 {return 4u8;} else
|
||||
if i == 10u32 {return 20u8;} else
|
||||
if i == 11u32 {return 10u8;} else
|
||||
if i == 12u32 {return 16u8;} else
|
||||
if i == 13u32 {return 7u8;} else
|
||||
if i == 14u32 {return 12u8;} else
|
||||
if i == 15u32 {return 26u8;} else
|
||||
|
||||
if i == 16u32 {return 31u8;} else
|
||||
if i == 17u32 {return 23u8;} else
|
||||
if i == 18u32 {return 18u8;} else
|
||||
if i == 19u32 {return 5u8;} else
|
||||
if i == 20u32 {return 21u8;} else
|
||||
if i == 21u32 {return 9u8;} else
|
||||
if i == 22u32 {return 15u8;} else
|
||||
if i == 23u32 {return 11u8;} else
|
||||
|
||||
if i == 24u32 {return 30u8;} else
|
||||
if i == 25u32 {return 17u8;} else
|
||||
if i == 26u32 {return 8u8;} else
|
||||
if i == 27u32 {return 14u8;} else
|
||||
if i == 28u32 {return 29u8;} else
|
||||
if i == 29u32 {return 13u8;} else
|
||||
if i == 30u32 {return 28u8;} else
|
||||
if i == 31u32 {return 27u8;} else
|
||||
{return 0u8;} // unused
|
||||
program ntzdebrujin.aleo {
|
||||
// The 'ntzdebruijn' main function.
|
||||
// From Hacker's Delight 2nd ed. figure 5-26
|
||||
transition main(public x: u32) -> u8 {
|
||||
if x == 0u32 {return 32u8;}
|
||||
// 0x04D7651F = 81224991
|
||||
x = (x & 0u32.sub_wrapped(x)).mul_wrapped(81224991u32);
|
||||
let i: u32 = x >> 27u8;
|
||||
return deBruijnTableLookup(i);
|
||||
}
|
||||
|
||||
// { 0, 1, 2,24, 3,19, 6,25, 22, 4,20,10,16, 7,12,26,
|
||||
// 31,23,18, 5,21, 9,15,11, 30,17, 8,14,29,13,28,27};
|
||||
|
||||
function deBruijnTableLookup(i: u32) -> u8 {
|
||||
|
||||
if i == 0u32 {return 0u8;} else
|
||||
if i == 1u32 {return 1u8;} else
|
||||
if i == 2u32 {return 2u8;} else
|
||||
if i == 3u32 {return 24u8;} else
|
||||
if i == 4u32 {return 3u8;} else
|
||||
if i == 5u32 {return 19u8;} else
|
||||
if i == 6u32 {return 6u8;} else
|
||||
if i == 7u32 {return 25u8;} else
|
||||
|
||||
if i == 8u32 {return 22u8;} else
|
||||
if i == 9u32 {return 4u8;} else
|
||||
if i == 10u32 {return 20u8;} else
|
||||
if i == 11u32 {return 10u8;} else
|
||||
if i == 12u32 {return 16u8;} else
|
||||
if i == 13u32 {return 7u8;} else
|
||||
if i == 14u32 {return 12u8;} else
|
||||
if i == 15u32 {return 26u8;} else
|
||||
|
||||
if i == 16u32 {return 31u8;} else
|
||||
if i == 17u32 {return 23u8;} else
|
||||
if i == 18u32 {return 18u8;} else
|
||||
if i == 19u32 {return 5u8;} else
|
||||
if i == 20u32 {return 21u8;} else
|
||||
if i == 21u32 {return 9u8;} else
|
||||
if i == 22u32 {return 15u8;} else
|
||||
if i == 23u32 {return 11u8;} else
|
||||
|
||||
if i == 24u32 {return 30u8;} else
|
||||
if i == 25u32 {return 17u8;} else
|
||||
if i == 26u32 {return 8u8;} else
|
||||
if i == 27u32 {return 14u8;} else
|
||||
if i == 28u32 {return 29u8;} else
|
||||
if i == 29u32 {return 13u8;} else
|
||||
if i == 30u32 {return 28u8;} else
|
||||
if i == 31u32 {return 27u8;} else
|
||||
{return 0u8;} // unused
|
||||
}
|
||||
}
|
||||
|
@ -1,17 +1,19 @@
|
||||
// The 'ntzgaudet' main function.
|
||||
// From Hacker's Delight 2nd ed. figure 5-24
|
||||
transition main(public x: u32) -> u8 {
|
||||
let y: u32 = x & 0u32.sub_wrapped(x); // Isolate rightmost 1-bit
|
||||
let bz: u8 = (y != 0u32) ? 0u8 : 1u8;
|
||||
// 0x0000FFFF = 65535
|
||||
let b4: u8 = (y & 65535u32 != 0u32) ? 0u8 : 16u8;
|
||||
// 0x00FF00FF = 16711935
|
||||
let b3: u8 = (y & 16711935u32 != 0u32) ? 0u8 : 8u8;
|
||||
// 0x0F0F0F0F = 252645135
|
||||
let b2: u8 = (y & 252645135u32 != 0u32) ? 0u8 : 4u8;
|
||||
// 0x33333333 = 858993459
|
||||
let b1: u8 = (y & 858993459u32 != 0u32) ? 0u8 : 2u8;
|
||||
// 0x55555555 = 1431655765
|
||||
let b0: u8 = (y & 1431655765u32 != 0u32) ? 0u8 : 1u8;
|
||||
return bz + b4 + b3 + b2 + b1 + b0;
|
||||
program ntzgaudet.aleo {
|
||||
// The 'ntzgaudet' main function.
|
||||
// From Hacker's Delight 2nd ed. figure 5-24
|
||||
transition main(public x: u32) -> u8 {
|
||||
let y: u32 = x & 0u32.sub_wrapped(x); // Isolate rightmost 1-bit
|
||||
let bz: u8 = (y != 0u32) ? 0u8 : 1u8;
|
||||
// 0x0000FFFF = 65535
|
||||
let b4: u8 = (y & 65535u32 != 0u32) ? 0u8 : 16u8;
|
||||
// 0x00FF00FF = 16711935
|
||||
let b3: u8 = (y & 16711935u32 != 0u32) ? 0u8 : 8u8;
|
||||
// 0x0F0F0F0F = 252645135
|
||||
let b2: u8 = (y & 252645135u32 != 0u32) ? 0u8 : 4u8;
|
||||
// 0x33333333 = 858993459
|
||||
let b1: u8 = (y & 858993459u32 != 0u32) ? 0u8 : 2u8;
|
||||
// 0x55555555 = 1431655765
|
||||
let b0: u8 = (y & 1431655765u32 != 0u32) ? 0u8 : 1u8;
|
||||
return bz + b4 + b3 + b2 + b1 + b0;
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +1,15 @@
|
||||
// The 'ntzloops' main function.
|
||||
// From Hacker's Delight 2nd ed. figure 5-23
|
||||
transition main(public x: u32) -> u8 {
|
||||
x = !x & x.sub_wrapped(1u32);
|
||||
let n: u8 = 0u8;
|
||||
for i:u8 in 0u8..32u8 {
|
||||
if x != 0u32 {
|
||||
n += 1u8;
|
||||
x = x >> 1u8;
|
||||
program ntzloops.aleo {
|
||||
// The 'ntzloops' main function.
|
||||
// From Hacker's Delight 2nd ed. figure 5-23
|
||||
transition main(public x: u32) -> u8 {
|
||||
x = !x & x.sub_wrapped(1u32);
|
||||
let n: u8 = 0u8;
|
||||
for i:u8 in 0u8..32u8 {
|
||||
if x != 0u32 {
|
||||
n += 1u8;
|
||||
x = x >> 1u8;
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
@ -1,15 +1,17 @@
|
||||
// The 'ntzmasks' main function.
|
||||
// From Hacker's Delight 2nd ed. figure 5-20
|
||||
transition main(public x: u32) -> u8 {
|
||||
if (x == 0u32) {return 32u8;}
|
||||
let n: u8 = 1u8;
|
||||
// x >>= 16u8 wasn't working, and I don't want to use
|
||||
// to u32 as a shift operand, so I do x = x >> 16u8
|
||||
if ((x & 65535u32) == 0u32) {n += 16u8; x = x >> 16u8;}
|
||||
if ((x & 255u32) == 0u32) {n += 8u8; x = x >> 8u8;}
|
||||
if ((x & 15u32) == 0u32) {n += 4u8; x = x >> 4u8;}
|
||||
if ((x & 3u32) == 0u32) {n += 2u8; x = x >> 2u8;}
|
||||
// can't do `return n - (x & 1u32);` because no typecasts, so:
|
||||
if ((x & 1u32) == 1u32) {n -= 1u8;}
|
||||
return n;
|
||||
program ntzmasks.aleo {
|
||||
// The 'ntzmasks' main function.
|
||||
// From Hacker's Delight 2nd ed. figure 5-20
|
||||
transition main(public x: u32) -> u8 {
|
||||
if (x == 0u32) {return 32u8;}
|
||||
let n: u8 = 1u8;
|
||||
// x >>= 16u8 wasn't working, and I don't want to use
|
||||
// to u32 as a shift operand, so I do x = x >> 16u8
|
||||
if ((x & 65535u32) == 0u32) {n += 16u8; x = x >> 16u8;}
|
||||
if ((x & 255u32) == 0u32) {n += 8u8; x = x >> 8u8;}
|
||||
if ((x & 15u32) == 0u32) {n += 4u8; x = x >> 4u8;}
|
||||
if ((x & 3u32) == 0u32) {n += 2u8; x = x >> 2u8;}
|
||||
// can't do `return n - (x & 1u32);` because no typecasts, so:
|
||||
if ((x & 1u32) == 1u32) {n -= 1u8;}
|
||||
return n;
|
||||
}
|
||||
}
|
||||
|
@ -1,58 +1,60 @@
|
||||
// The 'ntzreisers' main function.
|
||||
// From Hacker's Delight 2nd ed. figure 5-27
|
||||
transition main(public x: u32) -> u8 {
|
||||
x = (x & 0u32.sub_wrapped(x)).rem_wrapped(37u32);
|
||||
return reisersTableLookup(x);
|
||||
}
|
||||
|
||||
// There are 37 entries here
|
||||
// {32, 0, 1, 26, 2, 23, 27,
|
||||
// u, 3, 16, 24, 30, 28, 11, u, 13, 4,
|
||||
// 7, 17, u, 25, 22, 31, 15, 29, 10, 12,
|
||||
// 6, u, 21, 14, 9, 5, 20, 8, 19, 18};
|
||||
|
||||
function reisersTableLookup(i: u32) -> u8 {
|
||||
|
||||
if i == 0u32 {return 32u8;} else
|
||||
if i == 1u32 {return 0u8;} else
|
||||
if i == 2u32 {return 1u8;} else
|
||||
if i == 3u32 {return 26u8;} else
|
||||
if i == 4u32 {return 2u8;} else
|
||||
if i == 5u32 {return 23u8;} else
|
||||
if i == 6u32 {return 27u8;} else
|
||||
|
||||
if i == 7u32 {return 0u8;} else // unused
|
||||
if i == 8u32 {return 3u8;} else
|
||||
if i == 9u32 {return 16u8;} else
|
||||
if i == 10u32 {return 24u8;} else
|
||||
if i == 11u32 {return 30u8;} else
|
||||
if i == 12u32 {return 28u8;} else
|
||||
if i == 13u32 {return 11u8;} else
|
||||
if i == 14u32 {return 0u8;} else // unused
|
||||
if i == 15u32 {return 13u8;} else
|
||||
if i == 16u32 {return 4u8;} else
|
||||
|
||||
if i == 17u32 {return 7u8;} else
|
||||
if i == 18u32 {return 17u8;} else
|
||||
if i == 19u32 {return 0u8;} else // unused
|
||||
if i == 20u32 {return 25u8;} else
|
||||
if i == 21u32 {return 22u8;} else
|
||||
if i == 22u32 {return 31u8;} else
|
||||
if i == 23u32 {return 15u8;} else
|
||||
if i == 24u32 {return 29u8;} else
|
||||
if i == 25u32 {return 10u8;} else
|
||||
if i == 26u32 {return 12u8;} else
|
||||
|
||||
if i == 27u32 {return 6u8;} else
|
||||
if i == 28u32 {return 0u8;} else // unused
|
||||
if i == 29u32 {return 21u8;} else
|
||||
if i == 30u32 {return 14u8;} else
|
||||
if i == 31u32 {return 9u8;} else
|
||||
if i == 32u32 {return 5u8;} else
|
||||
if i == 33u32 {return 20u8;} else
|
||||
if i == 34u32 {return 8u8;} else
|
||||
if i == 35u32 {return 19u8;} else
|
||||
if i == 36u32 {return 18u8;} else
|
||||
|
||||
{return 0u8;} // unused
|
||||
program ntzreisers.aleo {
|
||||
// The 'ntzreisers' main function.
|
||||
// From Hacker's Delight 2nd ed. figure 5-27
|
||||
transition main(public x: u32) -> u8 {
|
||||
x = (x & 0u32.sub_wrapped(x)).rem_wrapped(37u32);
|
||||
return reisersTableLookup(x);
|
||||
}
|
||||
|
||||
// There are 37 entries here
|
||||
// {32, 0, 1, 26, 2, 23, 27,
|
||||
// u, 3, 16, 24, 30, 28, 11, u, 13, 4,
|
||||
// 7, 17, u, 25, 22, 31, 15, 29, 10, 12,
|
||||
// 6, u, 21, 14, 9, 5, 20, 8, 19, 18};
|
||||
|
||||
function reisersTableLookup(i: u32) -> u8 {
|
||||
|
||||
if i == 0u32 {return 32u8;} else
|
||||
if i == 1u32 {return 0u8;} else
|
||||
if i == 2u32 {return 1u8;} else
|
||||
if i == 3u32 {return 26u8;} else
|
||||
if i == 4u32 {return 2u8;} else
|
||||
if i == 5u32 {return 23u8;} else
|
||||
if i == 6u32 {return 27u8;} else
|
||||
|
||||
if i == 7u32 {return 0u8;} else // unused
|
||||
if i == 8u32 {return 3u8;} else
|
||||
if i == 9u32 {return 16u8;} else
|
||||
if i == 10u32 {return 24u8;} else
|
||||
if i == 11u32 {return 30u8;} else
|
||||
if i == 12u32 {return 28u8;} else
|
||||
if i == 13u32 {return 11u8;} else
|
||||
if i == 14u32 {return 0u8;} else // unused
|
||||
if i == 15u32 {return 13u8;} else
|
||||
if i == 16u32 {return 4u8;} else
|
||||
|
||||
if i == 17u32 {return 7u8;} else
|
||||
if i == 18u32 {return 17u8;} else
|
||||
if i == 19u32 {return 0u8;} else // unused
|
||||
if i == 20u32 {return 25u8;} else
|
||||
if i == 21u32 {return 22u8;} else
|
||||
if i == 22u32 {return 31u8;} else
|
||||
if i == 23u32 {return 15u8;} else
|
||||
if i == 24u32 {return 29u8;} else
|
||||
if i == 25u32 {return 10u8;} else
|
||||
if i == 26u32 {return 12u8;} else
|
||||
|
||||
if i == 27u32 {return 6u8;} else
|
||||
if i == 28u32 {return 0u8;} else // unused
|
||||
if i == 29u32 {return 21u8;} else
|
||||
if i == 30u32 {return 14u8;} else
|
||||
if i == 31u32 {return 9u8;} else
|
||||
if i == 32u32 {return 5u8;} else
|
||||
if i == 33u32 {return 20u8;} else
|
||||
if i == 34u32 {return 8u8;} else
|
||||
if i == 35u32 {return 19u8;} else
|
||||
if i == 36u32 {return 18u8;} else
|
||||
|
||||
{return 0u8;} // unused
|
||||
}
|
||||
}
|
||||
|
@ -1,90 +1,92 @@
|
||||
// The 'nztseals' main function.
|
||||
// From Hacker's Delight 2nd ed. figure 5-25
|
||||
transition main(public x: u32) -> u8 {
|
||||
// 0x0450FBAF = 72416175
|
||||
x = (x & 0u32.sub_wrapped(x)).mul_wrapped(72416175u32);
|
||||
return sealsTableLookup(x >> 26u8);
|
||||
}
|
||||
|
||||
// Right now we do not have any structure that allows
|
||||
// computable indexing, so simulate that with a function.
|
||||
// {32, 0, 1,12, 2, 6, u,13, 3, u, 7, u, u, u, u,14,
|
||||
// 10, 4, u, u, 8, u, u,25, u, u, u, u, u,21,27,15,
|
||||
// 31,11, 5, u, u, u, u, u, 9, u, u,24, u, u,20,26,
|
||||
// 30, u, u, u, u,23, u,19, 29, u,22,18,28,17,16, u};
|
||||
|
||||
function sealsTableLookup(i: u32) -> u8 {
|
||||
|
||||
if i == 0u32 {return 32u8;} else
|
||||
if i == 1u32 {return 0u8;} else
|
||||
if i == 2u32 {return 1u8;} else
|
||||
if i == 3u32 {return 12u8;} else
|
||||
if i == 4u32 {return 2u8;} else
|
||||
if i == 5u32 {return 6u8;} else
|
||||
if i == 6u32 {return 0u8;} else // unused
|
||||
if i == 7u32 {return 13u8;} else
|
||||
|
||||
if i == 8u32 {return 3u8;} else
|
||||
if i == 9u32 {return 0u8;} else // unused
|
||||
if i == 10u32 {return 7u8;} else
|
||||
if i == 11u32 {return 0u8;} else // unused
|
||||
if i == 12u32 {return 0u8;} else // unused
|
||||
if i == 13u32 {return 0u8;} else // unused
|
||||
if i == 14u32 {return 0u8;} else // unused
|
||||
if i == 15u32 {return 14u8;} else
|
||||
|
||||
if i == 16u32 {return 10u8;} else
|
||||
if i == 17u32 {return 4u8;} else
|
||||
if i == 18u32 {return 0u8;} else // unused
|
||||
if i == 19u32 {return 0u8;} else // unused
|
||||
if i == 20u32 {return 8u8;} else
|
||||
if i == 21u32 {return 0u8;} else // unused
|
||||
if i == 22u32 {return 0u8;} else // unused
|
||||
if i == 23u32 {return 25u8;} else
|
||||
|
||||
if i == 24u32 {return 0u8;} else // unused
|
||||
if i == 25u32 {return 0u8;} else // unused
|
||||
if i == 26u32 {return 0u8;} else // unused
|
||||
if i == 27u32 {return 0u8;} else // unused
|
||||
if i == 28u32 {return 0u8;} else // unused
|
||||
if i == 29u32 {return 21u8;} else
|
||||
if i == 30u32 {return 27u8;} else
|
||||
if i == 31u32 {return 15u8;} else
|
||||
|
||||
if i == 32u32 {return 31u8;} else
|
||||
if i == 33u32 {return 11u8;} else
|
||||
if i == 34u32 {return 5u8;} else
|
||||
if i == 35u32 {return 0u8;} else // unused
|
||||
if i == 36u32 {return 0u8;} else // unused
|
||||
if i == 37u32 {return 0u8;} else // unused
|
||||
if i == 38u32 {return 0u8;} else // unused
|
||||
if i == 39u32 {return 0u8;} else // unused
|
||||
|
||||
if i == 40u32 {return 9u8;} else
|
||||
if i == 41u32 {return 0u8;} else // unused
|
||||
if i == 42u32 {return 0u8;} else // unused
|
||||
if i == 43u32 {return 24u8;} else
|
||||
if i == 44u32 {return 0u8;} else // unused
|
||||
if i == 45u32 {return 0u8;} else // unused
|
||||
if i == 46u32 {return 20u8;} else
|
||||
if i == 47u32 {return 26u8;} else
|
||||
|
||||
if i == 48u32 {return 30u8;} else
|
||||
if i == 49u32 {return 0u8;} else // unused
|
||||
if i == 50u32 {return 0u8;} else // unused
|
||||
if i == 51u32 {return 0u8;} else // unused
|
||||
if i == 52u32 {return 0u8;} else // unused
|
||||
if i == 53u32 {return 23u8;} else
|
||||
if i == 54u32 {return 0u8;} else // unused
|
||||
if i == 55u32 {return 19u8;} else
|
||||
|
||||
if i == 56u32 {return 29u8;} else
|
||||
if i == 57u32 {return 0u8;} else // unused
|
||||
if i == 58u32 {return 22u8;} else
|
||||
if i == 59u32 {return 18u8;} else
|
||||
if i == 60u32 {return 28u8;} else
|
||||
if i == 61u32 {return 17u8;} else
|
||||
if i == 62u32 {return 16u8;} else
|
||||
if i == 63u32 {return 0u8;} else // unused
|
||||
{return 0u8;} // unused
|
||||
program ntzseals.aleo {
|
||||
// The 'nztseals' main function.
|
||||
// From Hacker's Delight 2nd ed. figure 5-25
|
||||
transition main(public x: u32) -> u8 {
|
||||
// 0x0450FBAF = 72416175
|
||||
x = (x & 0u32.sub_wrapped(x)).mul_wrapped(72416175u32);
|
||||
return sealsTableLookup(x >> 26u8);
|
||||
}
|
||||
|
||||
// Right now we do not have any structure that allows
|
||||
// computable indexing, so simulate that with a function.
|
||||
// {32, 0, 1,12, 2, 6, u,13, 3, u, 7, u, u, u, u,14,
|
||||
// 10, 4, u, u, 8, u, u,25, u, u, u, u, u,21,27,15,
|
||||
// 31,11, 5, u, u, u, u, u, 9, u, u,24, u, u,20,26,
|
||||
// 30, u, u, u, u,23, u,19, 29, u,22,18,28,17,16, u};
|
||||
|
||||
function sealsTableLookup(i: u32) -> u8 {
|
||||
|
||||
if i == 0u32 {return 32u8;} else
|
||||
if i == 1u32 {return 0u8;} else
|
||||
if i == 2u32 {return 1u8;} else
|
||||
if i == 3u32 {return 12u8;} else
|
||||
if i == 4u32 {return 2u8;} else
|
||||
if i == 5u32 {return 6u8;} else
|
||||
if i == 6u32 {return 0u8;} else // unused
|
||||
if i == 7u32 {return 13u8;} else
|
||||
|
||||
if i == 8u32 {return 3u8;} else
|
||||
if i == 9u32 {return 0u8;} else // unused
|
||||
if i == 10u32 {return 7u8;} else
|
||||
if i == 11u32 {return 0u8;} else // unused
|
||||
if i == 12u32 {return 0u8;} else // unused
|
||||
if i == 13u32 {return 0u8;} else // unused
|
||||
if i == 14u32 {return 0u8;} else // unused
|
||||
if i == 15u32 {return 14u8;} else
|
||||
|
||||
if i == 16u32 {return 10u8;} else
|
||||
if i == 17u32 {return 4u8;} else
|
||||
if i == 18u32 {return 0u8;} else // unused
|
||||
if i == 19u32 {return 0u8;} else // unused
|
||||
if i == 20u32 {return 8u8;} else
|
||||
if i == 21u32 {return 0u8;} else // unused
|
||||
if i == 22u32 {return 0u8;} else // unused
|
||||
if i == 23u32 {return 25u8;} else
|
||||
|
||||
if i == 24u32 {return 0u8;} else // unused
|
||||
if i == 25u32 {return 0u8;} else // unused
|
||||
if i == 26u32 {return 0u8;} else // unused
|
||||
if i == 27u32 {return 0u8;} else // unused
|
||||
if i == 28u32 {return 0u8;} else // unused
|
||||
if i == 29u32 {return 21u8;} else
|
||||
if i == 30u32 {return 27u8;} else
|
||||
if i == 31u32 {return 15u8;} else
|
||||
|
||||
if i == 32u32 {return 31u8;} else
|
||||
if i == 33u32 {return 11u8;} else
|
||||
if i == 34u32 {return 5u8;} else
|
||||
if i == 35u32 {return 0u8;} else // unused
|
||||
if i == 36u32 {return 0u8;} else // unused
|
||||
if i == 37u32 {return 0u8;} else // unused
|
||||
if i == 38u32 {return 0u8;} else // unused
|
||||
if i == 39u32 {return 0u8;} else // unused
|
||||
|
||||
if i == 40u32 {return 9u8;} else
|
||||
if i == 41u32 {return 0u8;} else // unused
|
||||
if i == 42u32 {return 0u8;} else // unused
|
||||
if i == 43u32 {return 24u8;} else
|
||||
if i == 44u32 {return 0u8;} else // unused
|
||||
if i == 45u32 {return 0u8;} else // unused
|
||||
if i == 46u32 {return 20u8;} else
|
||||
if i == 47u32 {return 26u8;} else
|
||||
|
||||
if i == 48u32 {return 30u8;} else
|
||||
if i == 49u32 {return 0u8;} else // unused
|
||||
if i == 50u32 {return 0u8;} else // unused
|
||||
if i == 51u32 {return 0u8;} else // unused
|
||||
if i == 52u32 {return 0u8;} else // unused
|
||||
if i == 53u32 {return 23u8;} else
|
||||
if i == 54u32 {return 0u8;} else // unused
|
||||
if i == 55u32 {return 19u8;} else
|
||||
|
||||
if i == 56u32 {return 29u8;} else
|
||||
if i == 57u32 {return 0u8;} else // unused
|
||||
if i == 58u32 {return 22u8;} else
|
||||
if i == 59u32 {return 18u8;} else
|
||||
if i == 60u32 {return 28u8;} else
|
||||
if i == 61u32 {return 17u8;} else
|
||||
if i == 62u32 {return 16u8;} else
|
||||
if i == 63u32 {return 0u8;} else // unused
|
||||
{return 0u8;} // unused
|
||||
}
|
||||
}
|
||||
|
@ -1,74 +1,76 @@
|
||||
// The 'ntzsearchtree' main function.
|
||||
// From Hacker's Delight 2nd ed. figure 5-22,
|
||||
// expanded to a 32-bit version.
|
||||
transition main(public x: u32) -> u8 {
|
||||
if (x & 65535u32 != 0u32) {
|
||||
if (x & 255u32 != 0u32) {
|
||||
if (x & 15u32 != 0u32) {
|
||||
if (x & 3u32 != 0u32) {
|
||||
if (x & 1u32 != 0u32) {return 0u8;}
|
||||
else {return 1u8;} }
|
||||
else {
|
||||
if (x & 4u32 != 0u32) {return 2u8;}
|
||||
else {return 3u8;} } }
|
||||
else { // low 4 bits are 0 but low 8 bits are not zero
|
||||
if (x & 48u32 != 0u32) { // 48 = 0011 0000
|
||||
if (x & 16u32 != 0u32) {return 4u8;}
|
||||
else {return 5u8;} }
|
||||
else {if (x & 64u32 != 0u32) {return 6u8;}
|
||||
else {return 7u8;} } } }
|
||||
else { // low 8 bits are 0 but low 16 bits are not zero
|
||||
// 3840 = 00001111 00000000
|
||||
if (x & 3840u32 != 0u32) {
|
||||
// 768 = 00000011 00000000
|
||||
if (x & 768u32 != 0u32) {
|
||||
if (x & 256u32 != 0u32) {return 8u8;}
|
||||
else {return 9u8;} }
|
||||
else { // 1024 = 00000100 00000000
|
||||
if (x & 1024u32 != 0u32) {return 10u8;}
|
||||
else {return 11u8;} } }
|
||||
else { // low 12 bits are 0 but low 16 bits are not zero
|
||||
// 12288 = 0011 0000 0000 0000
|
||||
if (x & 12288u32 != 0u32) {
|
||||
// 4096 = 0001 0000 0000 0000
|
||||
if (x & 4096u32 != 0u32) {return 12u8;}
|
||||
else {return 13u8;} }
|
||||
else { // low 14 bits are 0 but low 16 bits are not zero
|
||||
// 16384 = 0100 0000 0000 0000
|
||||
if (x & 16384u32 != 0u32) {return 14u8;}
|
||||
else {return 15u8;} } } } }
|
||||
else { // low 16 bits are zero, now look at high 16 bits
|
||||
// Simply by multiplying the previous constants by 65536
|
||||
if (x & (255u32 * 65536u32) != 0u32) {
|
||||
if (x & (15u32 * 65536u32) != 0u32) {
|
||||
if (x & (3u32 * 65536u32) != 0u32) {
|
||||
if (x & (1u32 * 65536u32) != 0u32) {return 16u8;}
|
||||
else {return 17u8;} }
|
||||
else {
|
||||
if (x & (4u32 * 65536u32) != 0u32) {return 18u8;}
|
||||
else {return 19u8;} } }
|
||||
else {
|
||||
if (x & (48u32 * 65536u32) != 0u32) {
|
||||
if (x & (16u32 * 65536u32) != 0u32) {return 20u8;}
|
||||
else {return 21u8;} }
|
||||
else {
|
||||
if (x & (64u32 * 65536u32) != 0u32) {return 22u8;}
|
||||
else {return 23u8;} } } }
|
||||
else {
|
||||
if (x & (3840u32 * 65536u32) != 0u32) {
|
||||
if (x & (768u32 * 65536u32) != 0u32) {
|
||||
if (x & (256u32 * 65536u32) != 0u32) {return 24u8;}
|
||||
else {return 25u8;} }
|
||||
else {
|
||||
if (x & (1024u32 * 65536u32) != 0u32) {return 26u8;}
|
||||
else {return 27u8;} } }
|
||||
else {
|
||||
if (x & (12288u32 * 65536u32) != 0u32) {
|
||||
if (x & (4096u32 * 65536u32) != 0u32) {return 28u8;}
|
||||
else {return 29u8;} }
|
||||
else {
|
||||
if (x & (16384u32 * 65536u32) != 0u32) {return 30u8;}
|
||||
program ntzsearchtree.aleo {
|
||||
// The 'ntzsearchtree' main function.
|
||||
// From Hacker's Delight 2nd ed. figure 5-22,
|
||||
// expanded to a 32-bit version.
|
||||
transition main(public x: u32) -> u8 {
|
||||
if (x & 65535u32 != 0u32) {
|
||||
if (x & 255u32 != 0u32) {
|
||||
if (x & 15u32 != 0u32) {
|
||||
if (x & 3u32 != 0u32) {
|
||||
if (x & 1u32 != 0u32) {return 0u8;}
|
||||
else {return 1u8;} }
|
||||
else {
|
||||
if (x != 0u32) {return 31u8;}
|
||||
else {return 32u8;} } } } } }
|
||||
if (x & 4u32 != 0u32) {return 2u8;}
|
||||
else {return 3u8;} } }
|
||||
else { // low 4 bits are 0 but low 8 bits are not zero
|
||||
if (x & 48u32 != 0u32) { // 48 = 0011 0000
|
||||
if (x & 16u32 != 0u32) {return 4u8;}
|
||||
else {return 5u8;} }
|
||||
else {if (x & 64u32 != 0u32) {return 6u8;}
|
||||
else {return 7u8;} } } }
|
||||
else { // low 8 bits are 0 but low 16 bits are not zero
|
||||
// 3840 = 00001111 00000000
|
||||
if (x & 3840u32 != 0u32) {
|
||||
// 768 = 00000011 00000000
|
||||
if (x & 768u32 != 0u32) {
|
||||
if (x & 256u32 != 0u32) {return 8u8;}
|
||||
else {return 9u8;} }
|
||||
else { // 1024 = 00000100 00000000
|
||||
if (x & 1024u32 != 0u32) {return 10u8;}
|
||||
else {return 11u8;} } }
|
||||
else { // low 12 bits are 0 but low 16 bits are not zero
|
||||
// 12288 = 0011 0000 0000 0000
|
||||
if (x & 12288u32 != 0u32) {
|
||||
// 4096 = 0001 0000 0000 0000
|
||||
if (x & 4096u32 != 0u32) {return 12u8;}
|
||||
else {return 13u8;} }
|
||||
else { // low 14 bits are 0 but low 16 bits are not zero
|
||||
// 16384 = 0100 0000 0000 0000
|
||||
if (x & 16384u32 != 0u32) {return 14u8;}
|
||||
else {return 15u8;} } } } }
|
||||
else { // low 16 bits are zero, now look at high 16 bits
|
||||
// Simply by multiplying the previous constants by 65536
|
||||
if (x & (255u32 * 65536u32) != 0u32) {
|
||||
if (x & (15u32 * 65536u32) != 0u32) {
|
||||
if (x & (3u32 * 65536u32) != 0u32) {
|
||||
if (x & (1u32 * 65536u32) != 0u32) {return 16u8;}
|
||||
else {return 17u8;} }
|
||||
else {
|
||||
if (x & (4u32 * 65536u32) != 0u32) {return 18u8;}
|
||||
else {return 19u8;} } }
|
||||
else {
|
||||
if (x & (48u32 * 65536u32) != 0u32) {
|
||||
if (x & (16u32 * 65536u32) != 0u32) {return 20u8;}
|
||||
else {return 21u8;} }
|
||||
else {
|
||||
if (x & (64u32 * 65536u32) != 0u32) {return 22u8;}
|
||||
else {return 23u8;} } } }
|
||||
else {
|
||||
if (x & (3840u32 * 65536u32) != 0u32) {
|
||||
if (x & (768u32 * 65536u32) != 0u32) {
|
||||
if (x & (256u32 * 65536u32) != 0u32) {return 24u8;}
|
||||
else {return 25u8;} }
|
||||
else {
|
||||
if (x & (1024u32 * 65536u32) != 0u32) {return 26u8;}
|
||||
else {return 27u8;} } }
|
||||
else {
|
||||
if (x & (12288u32 * 65536u32) != 0u32) {
|
||||
if (x & (4096u32 * 65536u32) != 0u32) {return 28u8;}
|
||||
else {return 29u8;} }
|
||||
else {
|
||||
if (x & (16384u32 * 65536u32) != 0u32) {return 30u8;}
|
||||
else {
|
||||
if (x != 0u32) {return 31u8;}
|
||||
else {return 32u8;} } } } } }
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,14 @@
|
||||
// The 'ntzsmallvals' main function.
|
||||
// From Hacker's Delight 2nd ed. figure 5-21
|
||||
transition main(public x: u32) -> u8 {
|
||||
if (x == 0u32) {return 32u8;}
|
||||
let n: u8 = 31u8;
|
||||
let y: u32 = x.shl_wrapped(16u8); if (y != 0u32) {n = n - 16u8; x = y;}
|
||||
y = x.shl_wrapped(8u8); if (y != 0u32) {n = n - 8u8; x = y;}
|
||||
y = x.shl_wrapped(4u8); if (y != 0u32) {n = n - 4u8; x = y;}
|
||||
y = x.shl_wrapped(2u8); if (y != 0u32) {n = n - 2u8; x = y;}
|
||||
y = x.shl_wrapped(1u8); if (y != 0u32) {n = n - 1u8;}
|
||||
return n;
|
||||
program ntzsmallvals.aleo {
|
||||
// The 'ntzsmallvals' main function.
|
||||
// From Hacker's Delight 2nd ed. figure 5-21
|
||||
transition main(public x: u32) -> u8 {
|
||||
if (x == 0u32) {return 32u8;}
|
||||
let n: u8 = 31u8;
|
||||
let y: u32 = x.shl_wrapped(16u8); if (y != 0u32) {n = n - 16u8; x = y;}
|
||||
y = x.shl_wrapped(8u8); if (y != 0u32) {n = n - 8u8; x = y;}
|
||||
y = x.shl_wrapped(4u8); if (y != 0u32) {n = n - 4u8; x = y;}
|
||||
y = x.shl_wrapped(2u8); if (y != 0u32) {n = n - 2u8; x = y;}
|
||||
y = x.shl_wrapped(1u8); if (y != 0u32) {n = n - 1u8;}
|
||||
return n;
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,7 @@
|
||||
// The 'helloworld' main function.
|
||||
transition main(public a: u32, b: u32) -> u32 {
|
||||
return a + b;
|
||||
program helloworld.aleo {
|
||||
// The 'helloworld' main function.
|
||||
transition main(public a: u32, b: u32) -> u32 {
|
||||
return a + b;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,35 +1,37 @@
|
||||
// This function calculates the interest accrued
|
||||
// over ten iterations for some `capital` and `rate`.
|
||||
transition fixed_iteration_interest(capital: u32, public rate: u32) -> u32 {
|
||||
let amount: u32 = capital;
|
||||
program interest.aleo {
|
||||
// This function calculates the interest accrued
|
||||
// over ten iterations for some `capital` and `rate`.
|
||||
transition fixed_iteration_interest(capital: u32, public rate: u32) -> u32 {
|
||||
let amount: u32 = capital;
|
||||
|
||||
// Accrue for exactly 10 iterations.
|
||||
for i:u8 in 0u8..10u8 {
|
||||
// Note that the added amount is rounded down.
|
||||
amount += (amount * rate) / 100u32;
|
||||
}
|
||||
return amount;
|
||||
}
|
||||
|
||||
|
||||
// This function calculates the interest accrued
|
||||
// over a variable number of iterations (max 50) for some `capital` and `rate`.
|
||||
transition bounded_iteration_interest(capital: u32,
|
||||
public rate: u32,
|
||||
iterations: u8) -> u32 {
|
||||
console.assert(iterations <= 50u8);
|
||||
let amount: u32 = capital;
|
||||
|
||||
// Accrue for up to 50 iterations.
|
||||
for i:u8 in 0u8..50u8 {
|
||||
if i < iterations {
|
||||
// Accrue for exactly 10 iterations.
|
||||
for i:u8 in 0u8..10u8 {
|
||||
// Note that the added amount is rounded down.
|
||||
amount += (amount * rate) / 100u32;
|
||||
|
||||
} // Skip the remaining iterations.
|
||||
if i == 40u8 {
|
||||
return amount;
|
||||
}
|
||||
return amount;
|
||||
}
|
||||
|
||||
|
||||
// This function calculates the interest accrued
|
||||
// over a variable number of iterations (max 50) for some `capital` and `rate`.
|
||||
transition bounded_iteration_interest(capital: u32,
|
||||
public rate: u32,
|
||||
iterations: u8) -> u32 {
|
||||
console.assert(iterations <= 50u8);
|
||||
let amount: u32 = capital;
|
||||
|
||||
// Accrue for up to 50 iterations.
|
||||
for i:u8 in 0u8..50u8 {
|
||||
if i < iterations {
|
||||
// Note that the added amount is rounded down.
|
||||
amount += (amount * rate) / 100u32;
|
||||
|
||||
} // Skip the remaining iterations.
|
||||
if i == 40u8 {
|
||||
return amount;
|
||||
}
|
||||
}
|
||||
return amount;
|
||||
}
|
||||
return amount;
|
||||
}
|
||||
|
@ -1,26 +1,27 @@
|
||||
// This example demonstrates the definition and initialization of a "struct" in Leo.
|
||||
program message.aleo {
|
||||
// The "Message" struct.
|
||||
struct Message {
|
||||
// A struct member named "first" with type "field".
|
||||
first: field,
|
||||
// A struct member named "second" with type "field".
|
||||
second: field,
|
||||
}
|
||||
|
||||
// The "Message" struct.
|
||||
struct Message {
|
||||
// A struct member named "first" with type "field".
|
||||
first: field,
|
||||
// A struct member named "second" with type "field".
|
||||
second: field,
|
||||
}
|
||||
|
||||
// The "main" function of this Leo program takes a "Message" struct type as input.
|
||||
// To see how to input variable "m" is passed in open up `inputs/message.in`.
|
||||
transition main(m: Message) -> field {
|
||||
|
||||
// 1. Define the "Message" type.
|
||||
// 2. Use brackets `{ }` to enclose the struct members.
|
||||
// 3. Define each struct member `name : value`.
|
||||
let m1: Message = Message {
|
||||
first: m.first,
|
||||
second: m.second,
|
||||
};
|
||||
|
||||
// Access the members of a struct with dot syntax.
|
||||
// `struct_name.member`
|
||||
return m1.first + m1.second;
|
||||
// The "main" function of this Leo program takes a "Message" struct type as input.
|
||||
// To see how to input variable "m" is passed in open up `inputs/message.in`.
|
||||
transition main(m: Message) -> field {
|
||||
|
||||
// 1. Define the "Message" type.
|
||||
// 2. Use brackets `{ }` to enclose the struct members.
|
||||
// 3. Define each struct member `name : value`.
|
||||
let m1: Message = Message {
|
||||
first: m.first,
|
||||
second: m.second,
|
||||
};
|
||||
|
||||
// Access the members of a struct with dot syntax.
|
||||
// `struct_name.member`
|
||||
return m1.first + m1.second;
|
||||
}
|
||||
}
|
||||
|
@ -1,49 +1,50 @@
|
||||
// This example demonstrates an example of a minting and transferring a token in Leo.
|
||||
program simple_token.aleo {
|
||||
// The `Token` record datatype.
|
||||
record Token {
|
||||
// The token owner.
|
||||
owner: address,
|
||||
// The Aleo balance (in gates).
|
||||
gates: u64,
|
||||
// The token amount.
|
||||
amount: u64,
|
||||
}
|
||||
|
||||
// The `Token` record datatype.
|
||||
record Token {
|
||||
// The token owner.
|
||||
owner: address,
|
||||
// The Aleo balance (in gates).
|
||||
gates: u64,
|
||||
// The token amount.
|
||||
amount: u64,
|
||||
}
|
||||
|
||||
// The `mint` function initializes a new record with the
|
||||
// specified number of tokens assigned to the specified receiver.
|
||||
transition mint(owner: address, amount: u64) -> Token {
|
||||
return Token {
|
||||
owner: owner,
|
||||
gates: 0u64,
|
||||
amount: amount,
|
||||
};
|
||||
}
|
||||
|
||||
// The `transfer` function sends the specified number of tokens
|
||||
// to the receiver from the provided token record.
|
||||
transition transfer(token: Token, to: address, amount: u64) -> (Token, Token) {
|
||||
|
||||
// Checks the given token record has sufficient balance.
|
||||
// This `sub` operation is safe, and the proof will fail
|
||||
// if an overflow occurs.
|
||||
// `difference` holds the change amount to be returned to sender.
|
||||
let difference: u64 = token.amount - amount;
|
||||
|
||||
// Produce a token record with the change amount for the sender.
|
||||
let remaining: Token = Token {
|
||||
owner: token.owner,
|
||||
gates: token.gates,
|
||||
amount: difference,
|
||||
};
|
||||
|
||||
// Produce a token record for the specified receiver.
|
||||
let transferred: Token = Token {
|
||||
owner: to,
|
||||
gates: 0u64,
|
||||
amount: amount,
|
||||
};
|
||||
|
||||
// Output the sender's change record and the receiver's record.
|
||||
return (remaining, transferred);
|
||||
// The `mint` function initializes a new record with the
|
||||
// specified number of tokens assigned to the specified receiver.
|
||||
transition mint(owner: address, amount: u64) -> Token {
|
||||
return Token {
|
||||
owner: owner,
|
||||
gates: 0u64,
|
||||
amount: amount,
|
||||
};
|
||||
}
|
||||
|
||||
// The `transfer` function sends the specified number of tokens
|
||||
// to the receiver from the provided token record.
|
||||
transition transfer(token: Token, to: address, amount: u64) -> (Token, Token) {
|
||||
|
||||
// Checks the given token record has sufficient balance.
|
||||
// This `sub` operation is safe, and the proof will fail
|
||||
// if an overflow occurs.
|
||||
// `difference` holds the change amount to be returned to sender.
|
||||
let difference: u64 = token.amount - amount;
|
||||
|
||||
// Produce a token record with the change amount for the sender.
|
||||
let remaining: Token = Token {
|
||||
owner: token.owner,
|
||||
gates: token.gates,
|
||||
amount: difference,
|
||||
};
|
||||
|
||||
// Produce a token record for the specified receiver.
|
||||
let transferred: Token = Token {
|
||||
owner: to,
|
||||
gates: 0u64,
|
||||
amount: amount,
|
||||
};
|
||||
|
||||
// Output the sender's change record and the receiver's record.
|
||||
return (remaining, transferred);
|
||||
}
|
||||
}
|
||||
|
@ -1,109 +1,111 @@
|
||||
// A row in a tic tac toe board.
|
||||
// - `c1` : The first entry in the row.
|
||||
// - `c2` : The second entry in the row.
|
||||
// - `c3` : The third entry in the row.
|
||||
// A valid entry is either 0, 1, or 2, where 0 is empty, 1 corresponds to player 1, and 2 corresponds to player 2.
|
||||
// Any other values are invalid.
|
||||
struct Row {
|
||||
c1: u8,
|
||||
c2: u8,
|
||||
c3: u8
|
||||
}
|
||||
|
||||
// A tic tac toe board.
|
||||
// - `r1` : The first row in the board.
|
||||
// - `r2` : The second row in the board.
|
||||
// - `r3` : The third row in the board.
|
||||
struct Board {
|
||||
r1: Row,
|
||||
r2: Row,
|
||||
r3: Row,
|
||||
}
|
||||
|
||||
// Returns an empty board.
|
||||
transition new() -> Board {
|
||||
return Board {
|
||||
r1: Row { c1: 0u8, c2: 0u8, c3: 0u8 },
|
||||
r2: Row { c1: 0u8, c2: 0u8, c3: 0u8 },
|
||||
r3: Row { c1: 0u8, c2: 0u8, c3: 0u8 },
|
||||
};
|
||||
}
|
||||
|
||||
// Returns `true` if there exists a row, column, or diagonal with all entries occupied by the same player.
|
||||
// - `b` : A tic tac toe board.
|
||||
// - `p` : A number corresponding to a player.
|
||||
function check_for_win(b: Board, p: u8) -> bool {
|
||||
return
|
||||
(b.r1.c1 == p && b.r1.c2 == p && b.r1.c3 == p) || // row 1
|
||||
(b.r2.c1 == p && b.r2.c2 == p && b.r2.c3 == p) || // row 2
|
||||
(b.r3.c1 == p && b.r3.c3 == p && b.r3.c3 == p) || // row 3
|
||||
(b.r1.c1 == p && b.r2.c1 == p && b.r3.c1 == p) || // column 1
|
||||
(b.r1.c2 == p && b.r2.c3 == p && b.r3.c2 == p) || // column 2
|
||||
(b.r1.c3 == p && b.r2.c3 == p && b.r3.c3 == p) || // column 3
|
||||
(b.r1.c1 == p && b.r2.c2 == p && b.r3.c3 == p) || // diagonal
|
||||
(b.r1.c3 == p && b.r2.c2 == p && b.r3.c1 == p); // other diagonal
|
||||
}
|
||||
|
||||
// Returns an updated tic tac toe board with a move made by a player.
|
||||
// Returns a `u8` corresponding to the player who won the game, or 0 if no one has won yet.
|
||||
// - `player` : A number corresponding to a player.
|
||||
// - `row` : The row of the move.
|
||||
// - `col` : The column of the move.
|
||||
// - `board` : A tic tac toe board.
|
||||
// Assumes that `player` is either 1 or 2.
|
||||
// Assumes that `row` and `col` are valid indices into the board.
|
||||
// If an entry is already occupied, the move is invalid and the board is returned unchanged.
|
||||
transition make_move(player: u8, row: u8, col: u8, board: Board) -> (Board, u8) {
|
||||
// Check that inputs are valid.
|
||||
console.assert(player == 1u8 || player == 2u8);
|
||||
console.assert(1u8 <= row && row <= 3u8);
|
||||
console.assert(1u8 <= col && col <= 3u8);
|
||||
|
||||
// Unpack the entries in the board into variables.
|
||||
let r1c1: u8 = board.r1.c1;
|
||||
let r1c2: u8 = board.r1.c2;
|
||||
let r1c3: u8 = board.r1.c3;
|
||||
let r2c1: u8 = board.r2.c1;
|
||||
let r2c2: u8 = board.r2.c2;
|
||||
let r2c3: u8 = board.r2.c3;
|
||||
let r3c1: u8 = board.r3.c1;
|
||||
let r3c2: u8 = board.r3.c2;
|
||||
let r3c3: u8 = board.r3.c3;
|
||||
|
||||
// Update the appropriate entry with the given move.
|
||||
if row == 1u8 && col == 1u8 && r1c1 == 0u8 {
|
||||
r1c1 = player;
|
||||
} else if row == 1u8 && col == 2u8 && r1c2 == 0u8 {
|
||||
r1c2 = player;
|
||||
} else if row == 1u8 && col == 3u8 && r1c3 == 0u8 {
|
||||
r1c3 = player;
|
||||
} else if row == 2u8 && col == 1u8 && r2c1 == 0u8 {
|
||||
r2c1 = player;
|
||||
} else if row == 2u8 && col == 2u8 && r2c2 == 0u8 {
|
||||
r2c2 = player;
|
||||
} else if row == 2u8 && col == 3u8 && r2c3 == 0u8 {
|
||||
r2c3 = player;
|
||||
} else if row == 3u8 && col == 1u8 && r3c1 == 0u8 {
|
||||
r3c1 = player;
|
||||
} else if row == 3u8 && col == 2u8 && r3c2 == 0u8 {
|
||||
r3c2 = player;
|
||||
} else if row == 3u8 && col == 3u8 && r3c3 == 0u8 {
|
||||
r3c3 = player;
|
||||
program tictactoe.aleo {
|
||||
// A row in a tic tac toe board.
|
||||
// - `c1` : The first entry in the row.
|
||||
// - `c2` : The second entry in the row.
|
||||
// - `c3` : The third entry in the row.
|
||||
// A valid entry is either 0, 1, or 2, where 0 is empty, 1 corresponds to player 1, and 2 corresponds to player 2.
|
||||
// Any other values are invalid.
|
||||
struct Row {
|
||||
c1: u8,
|
||||
c2: u8,
|
||||
c3: u8
|
||||
}
|
||||
|
||||
// Construct the updated game board.
|
||||
let updated: Board = Board {
|
||||
r1: Row { c1: r1c1, c2: r1c2, c3: r1c3 },
|
||||
r2: Row { c1: r2c1, c2: r2c2, c3: r2c3 },
|
||||
r3: Row { c1: r3c1, c2: r2c2, c3: r2c3 },
|
||||
};
|
||||
// A tic tac toe board.
|
||||
// - `r1` : The first row in the board.
|
||||
// - `r2` : The second row in the board.
|
||||
// - `r3` : The third row in the board.
|
||||
struct Board {
|
||||
r1: Row,
|
||||
r2: Row,
|
||||
r3: Row,
|
||||
}
|
||||
|
||||
// Check if the game is over.
|
||||
if check_for_win(updated, 1u8) {
|
||||
return (updated, 1u8);
|
||||
} else if check_for_win(updated, 2u8) {
|
||||
return (updated, 2u8);
|
||||
} else {
|
||||
return (updated, 0u8);
|
||||
// Returns an empty board.
|
||||
transition new() -> Board {
|
||||
return Board {
|
||||
r1: Row { c1: 0u8, c2: 0u8, c3: 0u8 },
|
||||
r2: Row { c1: 0u8, c2: 0u8, c3: 0u8 },
|
||||
r3: Row { c1: 0u8, c2: 0u8, c3: 0u8 },
|
||||
};
|
||||
}
|
||||
|
||||
// Returns `true` if there exists a row, column, or diagonal with all entries occupied by the same player.
|
||||
// - `b` : A tic tac toe board.
|
||||
// - `p` : A number corresponding to a player.
|
||||
function check_for_win(b: Board, p: u8) -> bool {
|
||||
return
|
||||
(b.r1.c1 == p && b.r1.c2 == p && b.r1.c3 == p) || // row 1
|
||||
(b.r2.c1 == p && b.r2.c2 == p && b.r2.c3 == p) || // row 2
|
||||
(b.r3.c1 == p && b.r3.c3 == p && b.r3.c3 == p) || // row 3
|
||||
(b.r1.c1 == p && b.r2.c1 == p && b.r3.c1 == p) || // column 1
|
||||
(b.r1.c2 == p && b.r2.c3 == p && b.r3.c2 == p) || // column 2
|
||||
(b.r1.c3 == p && b.r2.c3 == p && b.r3.c3 == p) || // column 3
|
||||
(b.r1.c1 == p && b.r2.c2 == p && b.r3.c3 == p) || // diagonal
|
||||
(b.r1.c3 == p && b.r2.c2 == p && b.r3.c1 == p); // other diagonal
|
||||
}
|
||||
|
||||
// Returns an updated tic tac toe board with a move made by a player.
|
||||
// Returns a `u8` corresponding to the player who won the game, or 0 if no one has won yet.
|
||||
// - `player` : A number corresponding to a player.
|
||||
// - `row` : The row of the move.
|
||||
// - `col` : The column of the move.
|
||||
// - `board` : A tic tac toe board.
|
||||
// Assumes that `player` is either 1 or 2.
|
||||
// Assumes that `row` and `col` are valid indices into the board.
|
||||
// If an entry is already occupied, the move is invalid and the board is returned unchanged.
|
||||
transition make_move(player: u8, row: u8, col: u8, board: Board) -> (Board, u8) {
|
||||
// Check that inputs are valid.
|
||||
console.assert(player == 1u8 || player == 2u8);
|
||||
console.assert(1u8 <= row && row <= 3u8);
|
||||
console.assert(1u8 <= col && col <= 3u8);
|
||||
|
||||
// Unpack the entries in the board into variables.
|
||||
let r1c1: u8 = board.r1.c1;
|
||||
let r1c2: u8 = board.r1.c2;
|
||||
let r1c3: u8 = board.r1.c3;
|
||||
let r2c1: u8 = board.r2.c1;
|
||||
let r2c2: u8 = board.r2.c2;
|
||||
let r2c3: u8 = board.r2.c3;
|
||||
let r3c1: u8 = board.r3.c1;
|
||||
let r3c2: u8 = board.r3.c2;
|
||||
let r3c3: u8 = board.r3.c3;
|
||||
|
||||
// Update the appropriate entry with the given move.
|
||||
if row == 1u8 && col == 1u8 && r1c1 == 0u8 {
|
||||
r1c1 = player;
|
||||
} else if row == 1u8 && col == 2u8 && r1c2 == 0u8 {
|
||||
r1c2 = player;
|
||||
} else if row == 1u8 && col == 3u8 && r1c3 == 0u8 {
|
||||
r1c3 = player;
|
||||
} else if row == 2u8 && col == 1u8 && r2c1 == 0u8 {
|
||||
r2c1 = player;
|
||||
} else if row == 2u8 && col == 2u8 && r2c2 == 0u8 {
|
||||
r2c2 = player;
|
||||
} else if row == 2u8 && col == 3u8 && r2c3 == 0u8 {
|
||||
r2c3 = player;
|
||||
} else if row == 3u8 && col == 1u8 && r3c1 == 0u8 {
|
||||
r3c1 = player;
|
||||
} else if row == 3u8 && col == 2u8 && r3c2 == 0u8 {
|
||||
r3c2 = player;
|
||||
} else if row == 3u8 && col == 3u8 && r3c3 == 0u8 {
|
||||
r3c3 = player;
|
||||
}
|
||||
|
||||
// Construct the updated game board.
|
||||
let updated: Board = Board {
|
||||
r1: Row { c1: r1c1, c2: r1c2, c3: r1c3 },
|
||||
r2: Row { c1: r2c1, c2: r2c2, c3: r2c3 },
|
||||
r3: Row { c1: r3c1, c2: r2c2, c3: r2c3 },
|
||||
};
|
||||
|
||||
// Check if the game is over.
|
||||
if check_for_win(updated, 1u8) {
|
||||
return (updated, 1u8);
|
||||
} else if check_for_win(updated, 2u8) {
|
||||
return (updated, 2u8);
|
||||
} else {
|
||||
return (updated, 0u8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,26 +1,28 @@
|
||||
// This function calculates the number of powers of two ("twoadicity")
|
||||
// in the prime factorization of the input number `n`.
|
||||
transition main(public n: field) -> u8 {
|
||||
let remaining_n: field = n;
|
||||
let powers_of_two: u8 = 0u8;
|
||||
// Since field ints are 253 bits or fewer, any number in the field
|
||||
// will have at most 252 powers of two in its prime factoring.
|
||||
for i:u8 in 0u8..252u8 {
|
||||
if is_even_and_nonzero(remaining_n) {
|
||||
remaining_n = remaining_n / 2field;
|
||||
powers_of_two = powers_of_two + 1u8;
|
||||
program twoadicity.aleo {
|
||||
// This function calculates the number of powers of two ("twoadicity")
|
||||
// in the prime factorization of the input number `n`.
|
||||
transition main(public n: field) -> u8 {
|
||||
let remaining_n: field = n;
|
||||
let powers_of_two: u8 = 0u8;
|
||||
// Since field ints are 253 bits or fewer, any number in the field
|
||||
// will have at most 252 powers of two in its prime factoring.
|
||||
for i:u8 in 0u8..252u8 {
|
||||
if is_even_and_nonzero(remaining_n) {
|
||||
remaining_n = remaining_n / 2field;
|
||||
powers_of_two = powers_of_two + 1u8;
|
||||
}
|
||||
}
|
||||
return powers_of_two;
|
||||
}
|
||||
return powers_of_two;
|
||||
}
|
||||
|
||||
/* We define the is_even predicate on fields as follows.
|
||||
If n is even and nonzero, clearly n/2 < n.
|
||||
If n is odd, n-p is a field-equivalent negative number that is even, and
|
||||
(n-p)/2 is a field-equivalent negative number closer to 0, greater than n-p.
|
||||
If we add p to both of these negative numbers, we have
|
||||
n/2 = (n-p)/2 + p = (n+p)/2 is greater than n and still less than p.
|
||||
*/
|
||||
function is_even_and_nonzero (n: field) -> bool {
|
||||
return n / 2field < n;
|
||||
/* We define the is_even predicate on fields as follows.
|
||||
If n is even and nonzero, clearly n/2 < n.
|
||||
If n is odd, n-p is a field-equivalent negative number that is even, and
|
||||
(n-p)/2 is a field-equivalent negative number closer to 0, greater than n-p.
|
||||
If we add p to both of these negative numbers, we have
|
||||
n/2 = (n-p)/2 + p = (n+p)/2 is greater than n and still less than p.
|
||||
*/
|
||||
function is_even_and_nonzero (n: field) -> bool {
|
||||
return n / 2field < n;
|
||||
}
|
||||
}
|
||||
|
@ -1,96 +1,97 @@
|
||||
// The 'vote.leo' program.
|
||||
program vote.aleo {
|
||||
// Proposal details
|
||||
struct ProposalInfo {
|
||||
title: field,
|
||||
content: field,
|
||||
proposer: address,
|
||||
}
|
||||
|
||||
// Proposal details
|
||||
struct ProposalInfo {
|
||||
title: field,
|
||||
content: field,
|
||||
proposer: address,
|
||||
}
|
||||
|
||||
// Proposal record records proposal info publicly
|
||||
record Proposal {
|
||||
owner: address,
|
||||
gates: u64,
|
||||
id: field,
|
||||
info: ProposalInfo,
|
||||
}
|
||||
|
||||
// Save proposal info in public storage.
|
||||
mapping proposals: field => ProposalInfo;
|
||||
|
||||
// Privacy tickets to vote
|
||||
record Ticket {
|
||||
owner: address,
|
||||
gates: u64,
|
||||
pid: field,
|
||||
}
|
||||
|
||||
// Count the total tickets issued for each proposal
|
||||
mapping tickets: field => u64;
|
||||
|
||||
mapping agree_votes: field => u64;
|
||||
|
||||
mapping disagree_votes: field => u64;
|
||||
|
||||
// Propose a new proposal to vote on.
|
||||
transition propose(public info: ProposalInfo) -> Proposal {
|
||||
// Authenticate proposer.
|
||||
console.assert_eq(self.caller, info.proposer);
|
||||
|
||||
// Generate a new proposal id.
|
||||
let id: field = BHP256::hash(info.title);
|
||||
|
||||
// Finalize the proposal id.
|
||||
async finalize(id);
|
||||
|
||||
// Return a new record for the proposal.
|
||||
return Proposal {
|
||||
owner: self.caller,
|
||||
gates: 0u64,
|
||||
id,
|
||||
info,
|
||||
};
|
||||
}
|
||||
// Create a new proposal in the "tickets" mapping.
|
||||
finalize propose(public id: field) {
|
||||
increment(tickets, id, 0u64);
|
||||
}
|
||||
|
||||
// Create a new ticket to vote with.
|
||||
transition new_ticket(
|
||||
public pid: field,
|
||||
public voter: address,
|
||||
) -> Ticket {
|
||||
// Finalize the proposal id for the ticket.
|
||||
async finalize(pid);
|
||||
|
||||
return Ticket {
|
||||
owner: voter,
|
||||
gates: 0u64,
|
||||
pid,
|
||||
};
|
||||
}
|
||||
// Create a new ticket on a proposal in the "tickets" mapping.
|
||||
finalize new_ticket(public pid: field) {
|
||||
increment(tickets, pid, 1u64);
|
||||
}
|
||||
|
||||
// Vote privately to agree with a proposal.
|
||||
transition agree(ticket: Ticket) {
|
||||
// Finalize this vote.
|
||||
async finalize(ticket.pid);
|
||||
}
|
||||
finalize agree(public pid: field) {
|
||||
// Publicly increment the number of agree votes.
|
||||
increment(agree_votes, pid, 1u64);
|
||||
}
|
||||
|
||||
// Vote privately to disagree with a proposal.
|
||||
transition disagree(ticket: Ticket) {
|
||||
// Finalize this vote.
|
||||
async finalize(ticket.pid);
|
||||
}
|
||||
finalize disagree(pid: field) {
|
||||
// Publicly increment the number of disagree votes.
|
||||
increment(disagree_votes, pid, 1u64);
|
||||
// Proposal record records proposal info publicly
|
||||
record Proposal {
|
||||
owner: address,
|
||||
gates: u64,
|
||||
id: field,
|
||||
info: ProposalInfo,
|
||||
}
|
||||
|
||||
// Save proposal info in public storage.
|
||||
mapping proposals: field => ProposalInfo;
|
||||
|
||||
// Privacy tickets to vote
|
||||
record Ticket {
|
||||
owner: address,
|
||||
gates: u64,
|
||||
pid: field,
|
||||
}
|
||||
|
||||
// Count the total tickets issued for each proposal
|
||||
mapping tickets: field => u64;
|
||||
|
||||
mapping agree_votes: field => u64;
|
||||
|
||||
mapping disagree_votes: field => u64;
|
||||
|
||||
// Propose a new proposal to vote on.
|
||||
transition propose(public info: ProposalInfo) -> Proposal {
|
||||
// Authenticate proposer.
|
||||
console.assert_eq(self.caller, info.proposer);
|
||||
|
||||
// Generate a new proposal id.
|
||||
let id: field = BHP256::hash(info.title);
|
||||
|
||||
// Finalize the proposal id.
|
||||
async finalize(id);
|
||||
|
||||
// Return a new record for the proposal.
|
||||
return Proposal {
|
||||
owner: self.caller,
|
||||
gates: 0u64,
|
||||
id,
|
||||
info,
|
||||
};
|
||||
}
|
||||
// Create a new proposal in the "tickets" mapping.
|
||||
finalize propose(public id: field) {
|
||||
increment(tickets, id, 0u64);
|
||||
}
|
||||
|
||||
// Create a new ticket to vote with.
|
||||
transition new_ticket(
|
||||
public pid: field,
|
||||
public voter: address,
|
||||
) -> Ticket {
|
||||
// Finalize the proposal id for the ticket.
|
||||
async finalize(pid);
|
||||
|
||||
return Ticket {
|
||||
owner: voter,
|
||||
gates: 0u64,
|
||||
pid,
|
||||
};
|
||||
}
|
||||
// Create a new ticket on a proposal in the "tickets" mapping.
|
||||
finalize new_ticket(public pid: field) {
|
||||
increment(tickets, pid, 1u64);
|
||||
}
|
||||
|
||||
// Vote privately to agree with a proposal.
|
||||
transition agree(ticket: Ticket) {
|
||||
// Finalize this vote.
|
||||
async finalize(ticket.pid);
|
||||
}
|
||||
finalize agree(public pid: field) {
|
||||
// Publicly increment the number of agree votes.
|
||||
increment(agree_votes, pid, 1u64);
|
||||
}
|
||||
|
||||
// Vote privately to disagree with a proposal.
|
||||
transition disagree(ticket: Ticket) {
|
||||
// Finalize this vote.
|
||||
async finalize(ticket.pid);
|
||||
}
|
||||
finalize disagree(pid: field) {
|
||||
// Publicly increment the number of disagree votes.
|
||||
increment(disagree_votes, pid, 1u64);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user