1
0
Fork 0
mirror of synced 2025-09-24 04:40:05 +00:00

add embed sha256 to stdlib

This commit is contained in:
dark64 2021-01-12 14:20:57 +01:00
parent 6e5993bf93
commit c1f1143681
11 changed files with 168 additions and 6 deletions

View file

@ -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();

View file

@ -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)),

View 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

View 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

View 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

View 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

View 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

View 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]

View 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

View 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

View file

@ -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)