add embed sha256 to stdlib
This commit is contained in:
parent
6e5993bf93
commit
c1f1143681
11 changed files with 168 additions and 6 deletions
|
@ -37,10 +37,10 @@ impl FlatEmbed {
|
|||
#[cfg(feature = "bellman")]
|
||||
FlatEmbed::Sha256Round => Signature::new()
|
||||
.inputs(vec![
|
||||
Type::array(Type::FieldElement, 512),
|
||||
Type::array(Type::FieldElement, 256),
|
||||
Type::array(Type::Boolean, 512),
|
||||
Type::array(Type::Boolean, 256),
|
||||
])
|
||||
.outputs(vec![Type::array(Type::FieldElement, 256)]),
|
||||
.outputs(vec![Type::array(Type::Boolean, 256)]),
|
||||
FlatEmbed::Unpack(bitwidth) => Signature::new()
|
||||
.inputs(vec![Type::FieldElement])
|
||||
.outputs(vec![Type::array(Type::Boolean, *bitwidth)]),
|
||||
|
@ -374,7 +374,7 @@ mod tests {
|
|||
let compiled = sha256_round::<Bn128Field>();
|
||||
|
||||
// function should have 768 inputs
|
||||
assert_eq!(compiled.arguments.len(), 768,);
|
||||
assert_eq!(compiled.arguments.len(), 768);
|
||||
|
||||
// function should return 256 values
|
||||
assert_eq!(
|
||||
|
@ -435,8 +435,9 @@ mod tests {
|
|||
};
|
||||
|
||||
let input = (0..512)
|
||||
.map(|_| Bn128Field::from(0))
|
||||
.chain((0..256).map(|_| Bn128Field::from(1)))
|
||||
.map(|_| 0)
|
||||
.chain((0..256).map(|_| 1))
|
||||
.map(|i| Bn128Field::from(i))
|
||||
.collect();
|
||||
|
||||
let interpreter = Interpreter::default();
|
||||
|
|
|
@ -100,6 +100,14 @@ impl<'ast, T: Field> Inliner<'ast, T> {
|
|||
// inline all calls in the main function, recursively
|
||||
let main = inliner.fold_function_symbol(main);
|
||||
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(feature = "bellman")] {
|
||||
// define a function in the main module for the `sha256` embed
|
||||
let sha256_round = crate::embed::FlatEmbed::Sha256Round;
|
||||
let sha256_round_key = sha256_round.key::<T>();
|
||||
}
|
||||
}
|
||||
|
||||
// define a function in the main module for the `unpack` embed
|
||||
let unpack = crate::embed::FlatEmbed::Unpack(T::get_required_bits());
|
||||
let unpack_key = unpack.key::<T>();
|
||||
|
@ -135,6 +143,8 @@ impl<'ast, T: Field> Inliner<'ast, T> {
|
|||
"main".into(),
|
||||
TypedModule {
|
||||
functions: vec![
|
||||
#[cfg(feature = "bellman")]
|
||||
(sha256_round_key, TypedFunctionSymbol::Flat(sha256_round)),
|
||||
(unpack_key, TypedFunctionSymbol::Flat(unpack)),
|
||||
(u32_from_bits_key, TypedFunctionSymbol::Flat(u32_from_bits)),
|
||||
(u16_from_bits_key, TypedFunctionSymbol::Flat(u16_from_bits)),
|
||||
|
|
13
zokrates_stdlib/stdlib/hashes/sha256/embed/1024bit.zok
Normal file
13
zokrates_stdlib/stdlib/hashes/sha256/embed/1024bit.zok
Normal file
|
@ -0,0 +1,13 @@
|
|||
import "./IVconstants" as IVconstants
|
||||
import "./shaRoundNoBoolCheck" as sha256
|
||||
|
||||
// A function that takes 4 bool[256] arrays as inputs
|
||||
// and applies 2 rounds of sha256 compression.
|
||||
// It returns an array of 256 bool.
|
||||
def main(bool[256] a, bool[256] b, bool[256] c, bool[256] d) -> (bool[256]):
|
||||
|
||||
bool[256] IV = IVconstants()
|
||||
bool[256] digest1 = sha256(a, b, IV)
|
||||
bool[256] digest2 = sha256(c, d, digest1)
|
||||
|
||||
return digest2
|
16
zokrates_stdlib/stdlib/hashes/sha256/embed/1024bitPadded.zok
Normal file
16
zokrates_stdlib/stdlib/hashes/sha256/embed/1024bitPadded.zok
Normal file
|
@ -0,0 +1,16 @@
|
|||
import "./1536bit" as sha256
|
||||
|
||||
// Take two bool[256] arrays as input
|
||||
// and returns their sha256 full round output as an array of 256 bool.
|
||||
def main(bool[256] a, bool[256] b, bool[256] c, bool[256] d) -> (bool[256]):
|
||||
|
||||
// Hash is computed on the full 1024bit block size
|
||||
// padding does not fit in the first two blocks
|
||||
// add dummy block (single "1" followed by "0" + total length)
|
||||
bool[256] dummyblock1 = [true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false]
|
||||
// total length of message is 1024 bits: 0b10000000000
|
||||
bool[256] dummyblock2 = [false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, false, false, false, false, false, false, false, false, false, false]
|
||||
|
||||
bool[256] digest = sha256(a, b, c, d, dummyblock1, dummyblock2)
|
||||
|
||||
return digest
|
14
zokrates_stdlib/stdlib/hashes/sha256/embed/1536bit.zok
Normal file
14
zokrates_stdlib/stdlib/hashes/sha256/embed/1536bit.zok
Normal file
|
@ -0,0 +1,14 @@
|
|||
import "./IVconstants" as IVconstants
|
||||
import "./shaRoundNoBoolCheck" as sha256
|
||||
|
||||
// A function that takes 6 bool[256] arrays as inputs
|
||||
// and applies 3 rounds of sha256 compression.
|
||||
// It returns an array of 256 bool.
|
||||
def main(bool[256] a, bool[256] b, bool[256] c, bool[256] d, bool[256] e, bool[256] f) -> (bool[256]):
|
||||
|
||||
bool[256] IV = IVconstants()
|
||||
bool[256] digest1 = sha256(a, b, IV)
|
||||
bool[256] digest2 = sha256(c, d, digest1)
|
||||
bool[256] digest3 = sha256(e, f, digest2)
|
||||
|
||||
return digest3
|
30
zokrates_stdlib/stdlib/hashes/sha256/embed/256bitPadded.zok
Normal file
30
zokrates_stdlib/stdlib/hashes/sha256/embed/256bitPadded.zok
Normal file
|
@ -0,0 +1,30 @@
|
|||
import "./512bit" as sha256
|
||||
|
||||
// A function that takes 1 bool[256] array as input
|
||||
// and returns the sha256 full round output as an array of 256 bool.
|
||||
def main(bool[256] a) -> (bool[256]):
|
||||
|
||||
// Hash is computed on 256 bits of input
|
||||
// padding fits in the remaining 256 bits of the first block
|
||||
// add dummy block (single "1" followed by "0" + total length)
|
||||
bool[256] dummyblock1 = [ \
|
||||
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
|
||||
0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0]
|
||||
|
||||
bool[256] digest = sha256(a, dummyblock1)
|
||||
|
||||
return digest
|
15
zokrates_stdlib/stdlib/hashes/sha256/embed/512bit.zok
Normal file
15
zokrates_stdlib/stdlib/hashes/sha256/embed/512bit.zok
Normal file
|
@ -0,0 +1,15 @@
|
|||
import "./IVconstants" as IVconstants
|
||||
import "./shaRoundNoBoolCheck" as sha256
|
||||
|
||||
// A function that takes 2 bool[256] arrays as inputs
|
||||
// and returns their sha256 compression function as an array of 256 bool.
|
||||
// In contrast to full_round.zok no padding is being applied
|
||||
def main(bool[256] a, bool[256] b) -> (bool[256]):
|
||||
|
||||
// a and b is NOT checked to be of type bool
|
||||
|
||||
bool[256] IV = IVconstants()
|
||||
bool[256] digest = sha256(a, b, IV)
|
||||
//digest is constraint to be of type bool
|
||||
|
||||
return digest
|
23
zokrates_stdlib/stdlib/hashes/sha256/embed/512bitPacked.zok
Normal file
23
zokrates_stdlib/stdlib/hashes/sha256/embed/512bitPacked.zok
Normal file
|
@ -0,0 +1,23 @@
|
|||
import "../../../utils/pack/bool/pack128" as pack128
|
||||
import "../../../utils/pack/bool/unpack128" as unpack128
|
||||
import "./512bitPadded" as sha256
|
||||
|
||||
// A function that takes an array of 4 field elements as inputs, unpacks each of them to 128
|
||||
// bits (big endian), concatenates them and applies sha256.
|
||||
// It then returns an array of two field elements, each representing 128 bits of the result.
|
||||
def main(field[4] preimage) -> (field[2]):
|
||||
|
||||
bool[128] a = unpack128(preimage[0])
|
||||
bool[128] b = unpack128(preimage[1])
|
||||
bool[128] c = unpack128(preimage[2])
|
||||
bool[128] d = unpack128(preimage[3])
|
||||
|
||||
bool[256] lhs = [...a, ...b]
|
||||
bool[256] rhs = [...c, ...d]
|
||||
|
||||
bool[256] r = sha256(lhs, rhs)
|
||||
|
||||
field res0 = pack128(r[..128])
|
||||
field res1 = pack128(r[128..])
|
||||
|
||||
return [res0, res1]
|
17
zokrates_stdlib/stdlib/hashes/sha256/embed/512bitPadded.zok
Normal file
17
zokrates_stdlib/stdlib/hashes/sha256/embed/512bitPadded.zok
Normal file
|
@ -0,0 +1,17 @@
|
|||
import "./1024bit" as sha256
|
||||
|
||||
// A function that takes 2 bool[256] arrays as inputs
|
||||
// and returns their sha256 full round output as an array of 256 bool.
|
||||
def main(bool[256] a, bool[256] b) -> (bool[256]):
|
||||
|
||||
// Hash is computed on the full 512bit block size
|
||||
// padding does not fit in the primary block
|
||||
// add dummy block (single "1" followed by "0" + total length)
|
||||
bool[256] dummyblock1 = [true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false]
|
||||
|
||||
// total length of message is 512 bits: 0b1000000000
|
||||
bool[256] dummyblock2 = [false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, false, false, false, false, false, false, false, false, false]
|
||||
|
||||
bool[256] digest = sha256(a, b, dummyblock1, dummyblock2)
|
||||
|
||||
return digest
|
15
zokrates_stdlib/stdlib/hashes/sha256/embed/IVconstants.zok
Normal file
15
zokrates_stdlib/stdlib/hashes/sha256/embed/IVconstants.zok
Normal file
|
@ -0,0 +1,15 @@
|
|||
// SHA-256 is specified in FIPS 180-3 and initial values are listed in section 5.3.3
|
||||
// https://csrc.nist.gov/csrc/media/publications/fips/180/3/archive/2008-10-31/documents/fips180-3_final.pdf
|
||||
def main() -> (bool[256]):
|
||||
bool[32] h0 = [false, true, true, false, true, false, true, false, false, false, false, false, true, false, false, true, true, true, true, false, false, true, true, false, false, true, true, false, false, true, true, true]
|
||||
bool[32] h1 = [true, false, true, true, true, false, true, true, false, true, true, false, false, true, true, true, true, false, true, false, true, true, true, false, true, false, false, false, false, true, false, true]
|
||||
bool[32] h2 = [false, false, true, true, true, true, false, false, false, true, true, false, true, true, true, false, true, true, true, true, false, false, true, true, false, true, true, true, false, false, true, false]
|
||||
bool[32] h3 = [true, false, true, false, false, true, false, true, false, true, false, false, true, true, true, true, true, true, true, true, false, true, false, true, false, false, true, true, true, false, true, false]
|
||||
bool[32] h4 = [false, true, false, true, false, false, false, true, false, false, false, false, true, true, true, false, false, true, false, true, false, false, true, false, false, true, true, true, true, true, true, true]
|
||||
bool[32] h5 = [true, false, false, true, true, false, true, true, false, false, false, false, false, true, false, true, false, true, true, false, true, false, false, false, true, false, false, false, true, true, false, false]
|
||||
bool[32] h6 = [false, false, false, true, true, true, true, true, true, false, false, false, false, false, true, true, true, true, false, true, true, false, false, true, true, false, true, false, true, false, true, true]
|
||||
bool[32] h7 = [false, true, false, true, true, false, true, true, true, true, true, false, false, false, false, false, true, true, false, false, true, true, false, true, false, false, false, true, true, false, false, true]
|
||||
|
||||
bool[256] IV = [...h0, ...h1, ...h2, ...h3, ...h4, ...h5, ...h6, ...h7]
|
||||
|
||||
return IV
|
|
@ -0,0 +1,8 @@
|
|||
#pragma curve bn128
|
||||
import "EMBED/sha256round" as sha256round
|
||||
|
||||
// a and b is NOT checked to be 0 or 1
|
||||
// the return value is checked to be 0 or 1
|
||||
// IV vector is checked to be of type bool
|
||||
def main(bool[256] a, bool[256] b, bool[256] IV) -> (bool[256]):
|
||||
return sha256round([...a, ...b], IV)
|
Loading…
Reference in a new issue